/dix/dispatch.c
C | 3954 lines | 3129 code | 518 blank | 307 comment | 679 complexity | a5f6722dc3f3ce4f37c2982ae68d9e31 MD5 | raw file
Possible License(s): MIT
- /************************************************************
- Copyright 1987, 1989, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall not be
- used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from The Open Group.
- Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
- All Rights Reserved
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of Digital not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- ********************************************************/
- /* The panoramix components contained the following notice */
- /*****************************************************************
- Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
- BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of Digital Equipment Corporation
- shall not be used in advertising or otherwise to promote the sale, use or other
- dealings in this Software without prior written authorization from Digital
- Equipment Corporation.
- ******************************************************************/
- /* XSERVER_DTRACE additions:
- * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #include <version-config.h>
- #endif
- #ifdef PANORAMIX_DEBUG
- #include <stdio.h>
- int ProcInitialConnection();
- #endif
- #include "windowstr.h"
- #include <X11/fonts/fontstruct.h>
- #include "dixfontstr.h"
- #include "gcstruct.h"
- #include "selection.h"
- #include "colormapst.h"
- #include "cursorstr.h"
- #include "scrnintstr.h"
- #include "opaque.h"
- #include "input.h"
- #include "servermd.h"
- #include "extnsionst.h"
- #include "dixfont.h"
- #include "dispatch.h"
- #include "swaprep.h"
- #include "swapreq.h"
- #include "privates.h"
- #include "xace.h"
- #include "inputstr.h"
- #include "xkbsrv.h"
- #include "site.h"
- #include "client.h"
- #ifdef XSERVER_DTRACE
- #include "registry.h"
- #include <sys/types.h>
- typedef const char *string;
- #include "Xserver-dtrace.h"
- #endif
- #define mskcnt ((MAXCLIENTS + 31) / 32)
- #define BITMASK(i) (1U << ((i) & 31))
- #define MASKIDX(i) ((i) >> 5)
- #define MASKWORD(buf, i) buf[MASKIDX(i)]
- #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
- #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
- #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
- xConnSetupPrefix connSetupPrefix;
- PaddingInfo PixmapWidthPaddingInfo[33];
- static ClientPtr grabClient;
- #define GrabNone 0
- #define GrabActive 1
- #define GrabKickout 2
- static int grabState = GrabNone;
- static long grabWaiters[mskcnt];
- CallbackListPtr ServerGrabCallback = NULL;
- HWEventQueuePtr checkForInput[2];
- int connBlockScreenStart;
- static void KillAllClients(void);
- static int nextFreeClientID; /* always MIN free client ID */
- static int nClients; /* number of authorized clients */
- CallbackListPtr ClientStateCallback;
- /* dispatchException & isItTimeToYield must be declared volatile since they
- * are modified by signal handlers - otherwise optimizer may assume it doesn't
- * need to actually check value in memory when used and may miss changes from
- * signal handlers.
- */
- volatile char dispatchException = 0;
- volatile char isItTimeToYield;
- #define SAME_SCREENS(a, b) (\
- (a.pScreen == b.pScreen))
- void
- SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
- {
- checkForInput[0] = c0;
- checkForInput[1] = c1;
- }
- void
- UpdateCurrentTime(void)
- {
- TimeStamp systime;
- /* To avoid time running backwards, we must call GetTimeInMillis before
- * calling ProcessInputEvents.
- */
- systime.months = currentTime.months;
- systime.milliseconds = GetTimeInMillis();
- if (systime.milliseconds < currentTime.milliseconds)
- systime.months++;
- if (*checkForInput[0] != *checkForInput[1])
- ProcessInputEvents();
- if (CompareTimeStamps(systime, currentTime) == LATER)
- currentTime = systime;
- }
- /* Like UpdateCurrentTime, but can't call ProcessInputEvents */
- void
- UpdateCurrentTimeIf(void)
- {
- TimeStamp systime;
- systime.months = currentTime.months;
- systime.milliseconds = GetTimeInMillis();
- if (systime.milliseconds < currentTime.milliseconds)
- systime.months++;
- if (CompareTimeStamps(systime, currentTime) == LATER)
- currentTime = systime;
- }
- #undef SMART_DEBUG
- /* in milliseconds */
- #define SMART_SCHEDULE_DEFAULT_INTERVAL 5
- #define SMART_SCHEDULE_MAX_SLICE 15
- #if defined(WIN32) && !defined(__CYGWIN__)
- Bool SmartScheduleDisable = TRUE;
- #else
- Bool SmartScheduleDisable = FALSE;
- #endif
- long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
- long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
- long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
- long SmartScheduleTime;
- int SmartScheduleLatencyLimited = 0;
- static ClientPtr SmartLastClient;
- static int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1];
- #ifdef SMART_DEBUG
- long SmartLastPrint;
- #endif
- void Dispatch(void);
- static int
- SmartScheduleClient(int *clientReady, int nready)
- {
- ClientPtr pClient;
- int i;
- int client;
- int bestPrio, best = 0;
- int bestRobin, robin;
- long now = SmartScheduleTime;
- long idle;
- bestPrio = -0x7fffffff;
- bestRobin = 0;
- idle = 2 * SmartScheduleSlice;
- for (i = 0; i < nready; i++) {
- client = clientReady[i];
- pClient = clients[client];
- /* Praise clients which haven't run in a while */
- if ((now - pClient->smart_stop_tick) >= idle) {
- if (pClient->smart_priority < 0)
- pClient->smart_priority++;
- }
- /* check priority to select best client */
- robin =
- (pClient->index -
- SmartLastIndex[pClient->smart_priority -
- SMART_MIN_PRIORITY]) & 0xff;
- if (pClient->smart_priority > bestPrio ||
- (pClient->smart_priority == bestPrio && robin > bestRobin)) {
- bestPrio = pClient->smart_priority;
- bestRobin = robin;
- best = client;
- }
- #ifdef SMART_DEBUG
- if ((now - SmartLastPrint) >= 5000)
- fprintf(stderr, " %2d: %3d", client, pClient->smart_priority);
- #endif
- }
- #ifdef SMART_DEBUG
- if ((now - SmartLastPrint) >= 5000) {
- fprintf(stderr, " use %2d\n", best);
- SmartLastPrint = now;
- }
- #endif
- pClient = clients[best];
- SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = pClient->index;
- /*
- * Set current client pointer
- */
- if (SmartLastClient != pClient) {
- pClient->smart_start_tick = now;
- SmartLastClient = pClient;
- }
- /*
- * Adjust slice
- */
- if (nready == 1 && SmartScheduleLatencyLimited == 0) {
- /*
- * If it's been a long time since another client
- * has run, bump the slice up to get maximal
- * performance from a single client
- */
- if ((now - pClient->smart_start_tick) > 1000 &&
- SmartScheduleSlice < SmartScheduleMaxSlice) {
- SmartScheduleSlice += SmartScheduleInterval;
- }
- }
- else {
- SmartScheduleSlice = SmartScheduleInterval;
- }
- return best;
- }
- void
- EnableLimitedSchedulingLatency(void)
- {
- ++SmartScheduleLatencyLimited;
- SmartScheduleSlice = SmartScheduleInterval;
- }
- void
- DisableLimitedSchedulingLatency(void)
- {
- --SmartScheduleLatencyLimited;
- /* protect against bugs */
- if (SmartScheduleLatencyLimited < 0)
- SmartScheduleLatencyLimited = 0;
- }
- void
- Dispatch(void)
- {
- int *clientReady; /* array of request ready clients */
- int result;
- ClientPtr client;
- int nready;
- HWEventQueuePtr *icheck = checkForInput;
- long start_tick;
- nextFreeClientID = 1;
- nClients = 0;
- clientReady = malloc(sizeof(int) * MaxClients);
- if (!clientReady)
- return;
- SmartScheduleSlice = SmartScheduleInterval;
- while (!dispatchException) {
- if (*icheck[0] != *icheck[1]) {
- ProcessInputEvents();
- FlushIfCriticalOutputPending();
- }
- nready = WaitForSomething(clientReady);
- if (nready && !SmartScheduleDisable) {
- clientReady[0] = SmartScheduleClient(clientReady, nready);
- nready = 1;
- }
- /*****************
- * Handle events in round robin fashion, doing input between
- * each round
- *****************/
- while (!dispatchException && (--nready >= 0)) {
- client = clients[clientReady[nready]];
- if (!client) {
- /* KillClient can cause this to happen */
- continue;
- }
- /* GrabServer activation can cause this to be true */
- if (grabState == GrabKickout) {
- grabState = GrabActive;
- break;
- }
- isItTimeToYield = FALSE;
- start_tick = SmartScheduleTime;
- while (!isItTimeToYield) {
- if (*icheck[0] != *icheck[1])
- ProcessInputEvents();
- FlushIfCriticalOutputPending();
- if (!SmartScheduleDisable &&
- (SmartScheduleTime - start_tick) >= SmartScheduleSlice) {
- /* Penalize clients which consume ticks */
- if (client->smart_priority > SMART_MIN_PRIORITY)
- client->smart_priority--;
- break;
- }
- /* now, finally, deal with client requests */
- /* Update currentTime so request time checks, such as for input
- * device grabs, are calculated correctly */
- UpdateCurrentTimeIf();
- result = ReadRequestFromClient(client);
- if (result <= 0) {
- if (result < 0)
- CloseDownClient(client);
- break;
- }
- client->sequence++;
- client->majorOp = ((xReq *) client->requestBuffer)->reqType;
- client->minorOp = 0;
- if (client->majorOp >= EXTENSION_BASE) {
- ExtensionEntry *ext = GetExtensionEntry(client->majorOp);
- if (ext)
- client->minorOp = ext->MinorOpcode(client);
- }
- #ifdef XSERVER_DTRACE
- if (XSERVER_REQUEST_START_ENABLED())
- XSERVER_REQUEST_START(LookupMajorName(client->majorOp),
- client->majorOp,
- ((xReq *) client->requestBuffer)->length,
- client->index,
- client->requestBuffer);
- #endif
- if (result > (maxBigRequestSize << 2))
- result = BadLength;
- else {
- result = XaceHookDispatch(client, client->majorOp);
- if (result == Success)
- result =
- (*client->requestVector[client->majorOp]) (client);
- XaceHookAuditEnd(client, result);
- }
- #ifdef XSERVER_DTRACE
- if (XSERVER_REQUEST_DONE_ENABLED())
- XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
- client->majorOp, client->sequence,
- client->index, result);
- #endif
- if (client->noClientException != Success) {
- CloseDownClient(client);
- break;
- }
- else if (result != Success) {
- SendErrorToClient(client, client->majorOp,
- client->minorOp,
- client->errorValue, result);
- break;
- }
- }
- FlushAllOutput();
- client = clients[clientReady[nready]];
- if (client)
- client->smart_stop_tick = SmartScheduleTime;
- }
- dispatchException &= ~DE_PRIORITYCHANGE;
- }
- #if defined(DDXBEFORERESET)
- ddxBeforeReset();
- #endif
- KillAllClients();
- free(clientReady);
- dispatchException &= ~DE_RESET;
- SmartScheduleLatencyLimited = 0;
- ResetOsBuffers();
- }
- static int VendorRelease = VENDOR_RELEASE;
- static const char *VendorString = VENDOR_NAME;
- void
- SetVendorRelease(int release)
- {
- VendorRelease = release;
- }
- void
- SetVendorString(const char *vendor)
- {
- VendorString = vendor;
- }
- Bool
- CreateConnectionBlock(void)
- {
- xConnSetup setup;
- xWindowRoot root;
- xDepth depth;
- xVisualType visual;
- xPixmapFormat format;
- unsigned long vid;
- int i, j, k, lenofblock, sizesofar = 0;
- char *pBuf;
- memset(&setup, 0, sizeof(xConnSetup));
- /* Leave off the ridBase and ridMask, these must be sent with
- connection */
- setup.release = VendorRelease;
- /*
- * per-server image and bitmap parameters are defined in Xmd.h
- */
- setup.imageByteOrder = screenInfo.imageByteOrder;
- setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
- setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
- setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
- setup.motionBufferSize = NumMotionEvents();
- setup.numRoots = screenInfo.numScreens;
- setup.nbytesVendor = strlen(VendorString);
- setup.numFormats = screenInfo.numPixmapFormats;
- setup.maxRequestSize = MAX_REQUEST_SIZE;
- QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
- lenofblock = sizeof(xConnSetup) +
- pad_to_int32(setup.nbytesVendor) +
- (setup.numFormats * sizeof(xPixmapFormat)) +
- (setup.numRoots * sizeof(xWindowRoot));
- ConnectionInfo = malloc(lenofblock);
- if (!ConnectionInfo)
- return FALSE;
- memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup));
- sizesofar = sizeof(xConnSetup);
- pBuf = ConnectionInfo + sizeof(xConnSetup);
- memmove(pBuf, VendorString, (int) setup.nbytesVendor);
- sizesofar += setup.nbytesVendor;
- pBuf += setup.nbytesVendor;
- i = padding_for_int32(setup.nbytesVendor);
- sizesofar += i;
- while (--i >= 0)
- *pBuf++ = 0;
- memset(&format, 0, sizeof(xPixmapFormat));
- for (i = 0; i < screenInfo.numPixmapFormats; i++) {
- format.depth = screenInfo.formats[i].depth;
- format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
- format.scanLinePad = screenInfo.formats[i].scanlinePad;
- memmove(pBuf, (char *) &format, sizeof(xPixmapFormat));
- pBuf += sizeof(xPixmapFormat);
- sizesofar += sizeof(xPixmapFormat);
- }
- connBlockScreenStart = sizesofar;
- memset(&depth, 0, sizeof(xDepth));
- memset(&visual, 0, sizeof(xVisualType));
- for (i = 0; i < screenInfo.numScreens; i++) {
- ScreenPtr pScreen;
- DepthPtr pDepth;
- VisualPtr pVisual;
- pScreen = screenInfo.screens[i];
- root.windowId = pScreen->root->drawable.id;
- root.defaultColormap = pScreen->defColormap;
- root.whitePixel = pScreen->whitePixel;
- root.blackPixel = pScreen->blackPixel;
- root.currentInputMask = 0; /* filled in when sent */
- root.pixWidth = pScreen->width;
- root.pixHeight = pScreen->height;
- root.mmWidth = pScreen->mmWidth;
- root.mmHeight = pScreen->mmHeight;
- root.minInstalledMaps = pScreen->minInstalledCmaps;
- root.maxInstalledMaps = pScreen->maxInstalledCmaps;
- root.rootVisualID = pScreen->rootVisual;
- root.backingStore = pScreen->backingStoreSupport;
- root.saveUnders = FALSE;
- root.rootDepth = pScreen->rootDepth;
- root.nDepths = pScreen->numDepths;
- memmove(pBuf, (char *) &root, sizeof(xWindowRoot));
- sizesofar += sizeof(xWindowRoot);
- pBuf += sizeof(xWindowRoot);
- pDepth = pScreen->allowedDepths;
- for (j = 0; j < pScreen->numDepths; j++, pDepth++) {
- lenofblock += sizeof(xDepth) +
- (pDepth->numVids * sizeof(xVisualType));
- pBuf = (char *) realloc(ConnectionInfo, lenofblock);
- if (!pBuf) {
- free(ConnectionInfo);
- return FALSE;
- }
- ConnectionInfo = pBuf;
- pBuf += sizesofar;
- depth.depth = pDepth->depth;
- depth.nVisuals = pDepth->numVids;
- memmove(pBuf, (char *) &depth, sizeof(xDepth));
- pBuf += sizeof(xDepth);
- sizesofar += sizeof(xDepth);
- for (k = 0; k < pDepth->numVids; k++) {
- vid = pDepth->vids[k];
- for (pVisual = pScreen->visuals;
- pVisual->vid != vid; pVisual++);
- visual.visualID = vid;
- visual.class = pVisual->class;
- visual.bitsPerRGB = pVisual->bitsPerRGBValue;
- visual.colormapEntries = pVisual->ColormapEntries;
- visual.redMask = pVisual->redMask;
- visual.greenMask = pVisual->greenMask;
- visual.blueMask = pVisual->blueMask;
- memmove(pBuf, (char *) &visual, sizeof(xVisualType));
- pBuf += sizeof(xVisualType);
- sizesofar += sizeof(xVisualType);
- }
- }
- }
- connSetupPrefix.success = xTrue;
- connSetupPrefix.length = lenofblock / 4;
- connSetupPrefix.majorVersion = X_PROTOCOL;
- connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
- return TRUE;
- }
- int
- ProcBadRequest(ClientPtr client)
- {
- return BadRequest;
- }
- int
- ProcCreateWindow(ClientPtr client)
- {
- WindowPtr pParent, pWin;
- REQUEST(xCreateWindowReq);
- int len, rc;
- REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
- LEGAL_NEW_RESOURCE(stuff->wid, client);
- rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
- if (rc != Success)
- return rc;
- len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
- if (!stuff->width || !stuff->height) {
- client->errorValue = 0;
- return BadValue;
- }
- pWin = CreateWindow(stuff->wid, pParent, stuff->x,
- stuff->y, stuff->width, stuff->height,
- stuff->borderWidth, stuff->class,
- stuff->mask, (XID *) &stuff[1],
- (int) stuff->depth, client, stuff->visual, &rc);
- if (pWin) {
- Mask mask = pWin->eventMask;
- pWin->eventMask = 0; /* subterfuge in case AddResource fails */
- if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin))
- return BadAlloc;
- pWin->eventMask = mask;
- }
- return rc;
- }
- int
- ProcChangeWindowAttributes(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xChangeWindowAttributesReq);
- int len, rc;
- Mask access_mode = 0;
- REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
- access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
- access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
- rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
- if (rc != Success)
- return rc;
- len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
- if (len != Ones(stuff->valueMask))
- return BadLength;
- return ChangeWindowAttributes(pWin,
- stuff->valueMask, (XID *) &stuff[1], client);
- }
- int
- ProcGetWindowAttributes(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xResourceReq);
- xGetWindowAttributesReply wa;
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- memset(&wa, 0, sizeof(xGetWindowAttributesReply));
- GetWindowAttributes(pWin, client, &wa);
- WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
- return Success;
- }
- int
- ProcDestroyWindow(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xResourceReq);
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
- if (rc != Success)
- return rc;
- if (pWin->parent) {
- rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
- DixRemoveAccess);
- if (rc != Success)
- return rc;
- FreeResource(stuff->id, RT_NONE);
- }
- return Success;
- }
- int
- ProcDestroySubwindows(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xResourceReq);
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
- if (rc != Success)
- return rc;
- DestroySubwindows(pWin, client);
- return Success;
- }
- int
- ProcChangeSaveSet(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xChangeSaveSetReq);
- int rc;
- REQUEST_SIZE_MATCH(xChangeSaveSetReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
- if (rc != Success)
- return rc;
- if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
- return BadMatch;
- if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
- return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
- client->errorValue = stuff->mode;
- return BadValue;
- }
- int
- ProcReparentWindow(ClientPtr client)
- {
- WindowPtr pWin, pParent;
- REQUEST(xReparentWindowReq);
- int rc;
- REQUEST_SIZE_MATCH(xReparentWindowReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
- if (rc != Success)
- return rc;
- rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
- if (rc != Success)
- return rc;
- if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
- return BadMatch;
- if ((pWin->backgroundState == ParentRelative) &&
- (pParent->drawable.depth != pWin->drawable.depth))
- return BadMatch;
- if ((pWin->drawable.class != InputOnly) &&
- (pParent->drawable.class == InputOnly))
- return BadMatch;
- return ReparentWindow(pWin, pParent,
- (short) stuff->x, (short) stuff->y, client);
- }
- int
- ProcMapWindow(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xResourceReq);
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
- if (rc != Success)
- return rc;
- MapWindow(pWin, client);
- /* update cache to say it is mapped */
- return Success;
- }
- int
- ProcMapSubwindows(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xResourceReq);
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
- if (rc != Success)
- return rc;
- MapSubwindows(pWin, client);
- /* update cache to say it is mapped */
- return Success;
- }
- int
- ProcUnmapWindow(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xResourceReq);
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
- if (rc != Success)
- return rc;
- UnmapWindow(pWin, FALSE);
- /* update cache to say it is mapped */
- return Success;
- }
- int
- ProcUnmapSubwindows(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xResourceReq);
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
- if (rc != Success)
- return rc;
- UnmapSubwindows(pWin);
- return Success;
- }
- int
- ProcConfigureWindow(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xConfigureWindowReq);
- int len, rc;
- REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
- rc = dixLookupWindow(&pWin, stuff->window, client,
- DixManageAccess | DixSetAttrAccess);
- if (rc != Success)
- return rc;
- len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
- if (Ones((Mask) stuff->mask) != len)
- return BadLength;
- return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client);
- }
- int
- ProcCirculateWindow(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xCirculateWindowReq);
- int rc;
- REQUEST_SIZE_MATCH(xCirculateWindowReq);
- if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) {
- client->errorValue = stuff->direction;
- return BadValue;
- }
- rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
- if (rc != Success)
- return rc;
- CirculateWindow(pWin, (int) stuff->direction, client);
- return Success;
- }
- static int
- GetGeometry(ClientPtr client, xGetGeometryReply * rep)
- {
- DrawablePtr pDraw;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- rep->type = X_Reply;
- rep->length = 0;
- rep->sequenceNumber = client->sequence;
- rep->root = pDraw->pScreen->root->drawable.id;
- rep->depth = pDraw->depth;
- rep->width = pDraw->width;
- rep->height = pDraw->height;
- if (WindowDrawable(pDraw->type)) {
- WindowPtr pWin = (WindowPtr) pDraw;
- rep->x = pWin->origin.x - wBorderWidth(pWin);
- rep->y = pWin->origin.y - wBorderWidth(pWin);
- rep->borderWidth = pWin->borderWidth;
- }
- else { /* DRAWABLE_PIXMAP */
- rep->x = rep->y = rep->borderWidth = 0;
- }
- return Success;
- }
- int
- ProcGetGeometry(ClientPtr client)
- {
- xGetGeometryReply rep = { .type = X_Reply };
- int status;
- if ((status = GetGeometry(client, &rep)) != Success)
- return status;
- WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
- return Success;
- }
- int
- ProcQueryTree(ClientPtr client)
- {
- xQueryTreeReply reply;
- int rc, numChildren = 0;
- WindowPtr pChild, pWin, pHead;
- Window *childIDs = (Window *) NULL;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
- if (rc != Success)
- return rc;
- reply = (xQueryTreeReply) {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .root = pWin->drawable.pScreen->root->drawable.id,
- .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None
- };
- pHead = RealChildHead(pWin);
- for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
- numChildren++;
- if (numChildren) {
- int curChild = 0;
- childIDs = malloc(numChildren * sizeof(Window));
- if (!childIDs)
- return BadAlloc;
- for (pChild = pWin->lastChild; pChild != pHead;
- pChild = pChild->prevSib)
- childIDs[curChild++] = pChild->drawable.id;
- }
- reply.nChildren = numChildren;
- reply.length = bytes_to_int32(numChildren * sizeof(Window));
- WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
- if (numChildren) {
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, numChildren * sizeof(Window),
- childIDs);
- free(childIDs);
- }
- return Success;
- }
- int
- ProcInternAtom(ClientPtr client)
- {
- Atom atom;
- char *tchar;
- REQUEST(xInternAtomReq);
- REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
- if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) {
- client->errorValue = stuff->onlyIfExists;
- return BadValue;
- }
- tchar = (char *) &stuff[1];
- atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
- if (atom != BAD_RESOURCE) {
- xInternAtomReply reply = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0,
- .atom = atom
- };
- WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
- return Success;
- }
- else
- return BadAlloc;
- }
- int
- ProcGetAtomName(ClientPtr client)
- {
- const char *str;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- if ((str = NameForAtom(stuff->id))) {
- int len = strlen(str);
- xGetAtomNameReply reply = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = bytes_to_int32(len),
- .nameLength = len
- };
- WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
- WriteToClient(client, len, str);
- return Success;
- }
- else {
- client->errorValue = stuff->id;
- return BadAtom;
- }
- }
- int
- ProcGrabServer(ClientPtr client)
- {
- int rc;
- REQUEST_SIZE_MATCH(xReq);
- if (grabState != GrabNone && client != grabClient) {
- ResetCurrentRequest(client);
- client->sequence--;
- BITSET(grabWaiters, client->index);
- IgnoreClient(client);
- return Success;
- }
- rc = OnlyListenToOneClient(client);
- if (rc != Success)
- return rc;
- grabState = GrabKickout;
- grabClient = client;
- if (ServerGrabCallback) {
- ServerGrabInfoRec grabinfo;
- grabinfo.client = client;
- grabinfo.grabstate = SERVER_GRABBED;
- CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
- }
- return Success;
- }
- static void
- UngrabServer(ClientPtr client)
- {
- int i;
- grabState = GrabNone;
- ListenToAllClients();
- for (i = mskcnt; --i >= 0 && !grabWaiters[i];);
- if (i >= 0) {
- i <<= 5;
- while (!GETBIT(grabWaiters, i))
- i++;
- BITCLEAR(grabWaiters, i);
- AttendClient(clients[i]);
- }
- if (ServerGrabCallback) {
- ServerGrabInfoRec grabinfo;
- grabinfo.client = client;
- grabinfo.grabstate = SERVER_UNGRABBED;
- CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
- }
- }
- int
- ProcUngrabServer(ClientPtr client)
- {
- REQUEST_SIZE_MATCH(xReq);
- UngrabServer(client);
- return Success;
- }
- int
- ProcTranslateCoords(ClientPtr client)
- {
- REQUEST(xTranslateCoordsReq);
- WindowPtr pWin, pDst;
- xTranslateCoordsReply rep;
- int rc;
- REQUEST_SIZE_MATCH(xTranslateCoordsReq);
- rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- rep = (xTranslateCoordsReply) {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0
- };
- if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) {
- rep.sameScreen = xFalse;
- rep.child = None;
- rep.dstX = rep.dstY = 0;
- }
- else {
- INT16 x, y;
- rep.sameScreen = xTrue;
- rep.child = None;
- /* computing absolute coordinates -- adjust to destination later */
- x = pWin->drawable.x + stuff->srcX;
- y = pWin->drawable.y + stuff->srcY;
- pWin = pDst->firstChild;
- while (pWin) {
- BoxRec box;
- if ((pWin->mapped) &&
- (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
- (x < pWin->drawable.x + (int) pWin->drawable.width +
- wBorderWidth(pWin)) &&
- (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
- (y < pWin->drawable.y + (int) pWin->drawable.height +
- wBorderWidth(pWin))
- /* When a window is shaped, a further check
- * is made to see if the point is inside
- * borderSize
- */
- && (!wBoundingShape(pWin) ||
- RegionContainsPoint(&pWin->borderSize, x, y, &box))
- && (!wInputShape(pWin) ||
- RegionContainsPoint(wInputShape(pWin),
- x - pWin->drawable.x,
- y - pWin->drawable.y, &box))
- ) {
- rep.child = pWin->drawable.id;
- pWin = (WindowPtr) NULL;
- }
- else
- pWin = pWin->nextSib;
- }
- /* adjust to destination coordinates */
- rep.dstX = x - pDst->drawable.x;
- rep.dstY = y - pDst->drawable.y;
- }
- WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
- return Success;
- }
- int
- ProcOpenFont(ClientPtr client)
- {
- int err;
- REQUEST(xOpenFontReq);
- REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
- client->errorValue = stuff->fid;
- LEGAL_NEW_RESOURCE(stuff->fid, client);
- err = OpenFont(client, stuff->fid, (Mask) 0,
- stuff->nbytes, (char *) &stuff[1]);
- if (err == Success) {
- return Success;
- }
- else
- return err;
- }
- int
- ProcCloseFont(ClientPtr client)
- {
- FontPtr pFont;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT,
- client, DixDestroyAccess);
- if (rc == Success) {
- FreeResource(stuff->id, RT_NONE);
- return Success;
- }
- else {
- client->errorValue = stuff->id;
- return rc;
- }
- }
- int
- ProcQueryFont(ClientPtr client)
- {
- xQueryFontReply *reply;
- FontPtr pFont;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- {
- xCharInfo *pmax = FONTINKMAX(pFont);
- xCharInfo *pmin = FONTINKMIN(pFont);
- int nprotoxcistructs;
- int rlength;
- nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing &&
- pmax->leftSideBearing == pmin->leftSideBearing &&
- pmax->descent == pmin->descent &&
- pmax->ascent == pmin->ascent &&
- pmax->characterWidth == pmin->characterWidth) ?
- 0 : N2dChars(pFont);
- rlength = sizeof(xQueryFontReply) +
- FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
- nprotoxcistructs * sizeof(xCharInfo);
- reply = calloc(1, rlength);
- if (!reply) {
- return BadAlloc;
- }
- reply->type = X_Reply;
- reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
- reply->sequenceNumber = client->sequence;
- QueryFont(pFont, reply, nprotoxcistructs);
- WriteReplyToClient(client, rlength, reply);
- free(reply);
- return Success;
- }
- }
- int
- ProcQueryTextExtents(ClientPtr client)
- {
- xQueryTextExtentsReply reply;
- FontPtr pFont;
- ExtentInfoRec info;
- unsigned long length;
- int rc;
- REQUEST(xQueryTextExtentsReq);
- REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
- rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
- length = length << 1;
- if (stuff->oddLength) {
- if (length == 0)
- return BadLength;
- length--;
- }
- if (!QueryTextExtents(pFont, length, (unsigned char *) &stuff[1], &info))
- return BadAlloc;
- reply = (xQueryTextExtentsReply) {
- .type = X_Reply,
- .drawDirection = info.drawDirection,
- .sequenceNumber = client->sequence,
- .length = 0,
- .fontAscent = info.fontAscent,
- .fontDescent = info.fontDescent,
- .overallAscent = info.overallAscent,
- .overallDescent = info.overallDescent,
- .overallWidth = info.overallWidth,
- .overallLeft = info.overallLeft,
- .overallRight = info.overallRight
- };
- WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
- return Success;
- }
- int
- ProcListFonts(ClientPtr client)
- {
- REQUEST(xListFontsReq);
- REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
- return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
- stuff->maxNames);
- }
- int
- ProcListFontsWithInfo(ClientPtr client)
- {
- REQUEST(xListFontsWithInfoReq);
- REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
- return StartListFontsWithInfo(client, stuff->nbytes,
- (unsigned char *) &stuff[1], stuff->maxNames);
- }
- /**
- *
- * \param value must conform to DeleteType
- */
- int
- dixDestroyPixmap(void *value, XID pid)
- {
- PixmapPtr pPixmap = (PixmapPtr) value;
- return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
- }
- int
- ProcCreatePixmap(ClientPtr client)
- {
- PixmapPtr pMap;
- DrawablePtr pDraw;
- REQUEST(xCreatePixmapReq);
- DepthPtr pDepth;
- int i, rc;
- REQUEST_SIZE_MATCH(xCreatePixmapReq);
- client->errorValue = stuff->pid;
- LEGAL_NEW_RESOURCE(stuff->pid, client);
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- if (!stuff->width || !stuff->height) {
- client->errorValue = 0;
- return BadValue;
- }
- if (stuff->width > 32767 || stuff->height > 32767) {
- /* It is allowed to try and allocate a pixmap which is larger than
- * 32767 in either dimension. However, all of the framebuffer code
- * is buggy and does not reliably draw to such big pixmaps, basically
- * because the Region data structure operates with signed shorts
- * for the rectangles in it.
- *
- * Furthermore, several places in the X server computes the
- * size in bytes of the pixmap and tries to store it in an
- * integer. This integer can overflow and cause the allocated size
- * to be much smaller.
- *
- * So, such big pixmaps are rejected here with a BadAlloc
- */
- return BadAlloc;
- }
- if (stuff->depth != 1) {
- pDepth = pDraw->pScreen->allowedDepths;
- for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
- if (pDepth->depth == stuff->depth)
- goto CreatePmap;
- client->errorValue = stuff->depth;
- return BadValue;
- }
- CreatePmap:
- pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap)
- (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0);
- if (pMap) {
- pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pMap->drawable.id = stuff->pid;
- /* security creation/labeling check */
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
- pMap, RT_NONE, NULL, DixCreateAccess);
- if (rc != Success) {
- (*pDraw->pScreen->DestroyPixmap) (pMap);
- return rc;
- }
- if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap))
- return Success;
- }
- return BadAlloc;
- }
- int
- ProcFreePixmap(ClientPtr client)
- {
- PixmapPtr pMap;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP,
- client, DixDestroyAccess);
- if (rc == Success) {
- FreeResource(stuff->id, RT_NONE);
- return Success;
- }
- else {
- client->errorValue = stuff->id;
- return rc;
- }
- }
- int
- ProcCreateGC(ClientPtr client)
- {
- int error, rc;
- GC *pGC;
- DrawablePtr pDraw;
- unsigned len;
- REQUEST(xCreateGCReq);
- REQUEST_AT_LEAST_SIZE(xCreateGCReq);
- client->errorValue = stuff->gc;
- LEGAL_NEW_RESOURCE(stuff->gc, client);
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
- if (len != Ones(stuff->mask))
- return BadLength;
- pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
- stuff->gc, client);
- if (error != Success)
- return error;
- if (!AddResource(stuff->gc, RT_GC, (void *) pGC))
- return BadAlloc;
- return Success;
- }
- int
- ProcChangeGC(ClientPtr client)
- {
- GC *pGC;
- int result;
- unsigned len;
- REQUEST(xChangeGCReq);
- REQUEST_AT_LEAST_SIZE(xChangeGCReq);
- result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
- if (result != Success)
- return result;
- len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
- if (len != Ones(stuff->mask))
- return BadLength;
- return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
- }
- int
- ProcCopyGC(ClientPtr client)
- {
- GC *dstGC;
- GC *pGC;
- int result;
- REQUEST(xCopyGCReq);
- REQUEST_SIZE_MATCH(xCopyGCReq);
- result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
- if (result != Success)
- return result;
- result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
- if (result != Success)
- return result;
- if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
- return BadMatch;
- if (stuff->mask & ~GCAllBits) {
- client->errorValue = stuff->mask;
- return BadValue;
- }
- return CopyGC(pGC, dstGC, stuff->mask);
- }
- int
- ProcSetDashes(ClientPtr client)
- {
- GC *pGC;
- int result;
- REQUEST(xSetDashesReq);
- REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
- if (stuff->nDashes == 0) {
- client->errorValue = 0;
- return BadValue;
- }
- result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
- if (result != Success)
- return result;
- /* If there's an error, either there's no sensible errorValue,
- * or there was a dash segment of 0. */
- client->errorValue = 0;
- return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
- (unsigned char *) &stuff[1]);
- }
- int
- ProcSetClipRectangles(ClientPtr client)
- {
- int nr, result;
- GC *pGC;
- REQUEST(xSetClipRectanglesReq);
- REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
- if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
- (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) {
- client->errorValue = stuff->ordering;
- return BadValue;
- }
- result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
- if (result != Success)
- return result;
- nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
- if (nr & 4)
- return BadLength;
- nr >>= 3;
- return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
- nr, (xRectangle *) &stuff[1], (int) stuff->ordering);
- }
- int
- ProcFreeGC(ClientPtr client)
- {
- GC *pGC;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
- if (rc != Success)
- return rc;
- FreeResource(stuff->id, RT_NONE);
- return Success;
- }
- int
- ProcClearToBackground(ClientPtr client)
- {
- REQUEST(xClearAreaReq);
- WindowPtr pWin;
- int rc;
- REQUEST_SIZE_MATCH(xClearAreaReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
- if (rc != Success)
- return rc;
- if (pWin->drawable.class == InputOnly) {
- client->errorValue = stuff->window;
- return BadMatch;
- }
- if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) {
- client->errorValue = stuff->exposures;
- return BadValue;
- }
- (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y,
- stuff->width, stuff->height,
- (Bool) stuff->exposures);
- return Success;
- }
- int
- ProcCopyArea(ClientPtr client)
- {
- DrawablePtr pDst;
- DrawablePtr pSrc;
- GC *pGC;
- REQUEST(xCopyAreaReq);
- RegionPtr pRgn;
- int rc;
- REQUEST_SIZE_MATCH(xCopyAreaReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
- if (stuff->dstDrawable != stuff->srcDrawable) {
- rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
- if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) {
- client->errorValue = stuff->dstDrawable;
- return BadMatch;
- }
- }
- else
- pSrc = pDst;
- pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
- stuff->width, stuff->height,
- stuff->dstX, stuff->dstY);
- if (pGC->graphicsExposures) {
- (*pDst->pScreen->SendGraphicsExpose)
- (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
- if (pRgn)
- RegionDestroy(pRgn);
- }
- return Success;
- }
- int
- ProcCopyPlane(ClientPtr client)
- {
- DrawablePtr psrcDraw, pdstDraw;
- GC *pGC;
- REQUEST(xCopyPlaneReq);
- RegionPtr pRgn;
- int rc;
- REQUEST_SIZE_MATCH(xCopyPlaneReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
- if (stuff->dstDrawable != stuff->srcDrawable) {
- rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
- if (pdstDraw->pScreen != psrcDraw->pScreen) {
- client->errorValue = stuff->dstDrawable;
- return BadMatch;
- }
- }
- else
- psrcDraw = pdstDraw;
- /* Check to see if stuff->bitPlane has exactly ONE good bit set */
- if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
- (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
- client->errorValue = stuff->bitPlane;
- return BadValue;
- }
- pRgn =
- (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX,
- stuff->srcY, stuff->width, stuff->height,
- stuff->dstX, stuff->dstY, stuff->bitPlane);
- if (pGC->graphicsExposures) {
- (*pdstDraw->pScreen->SendGraphicsExpose)
- (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
- if (pRgn)
- RegionDestroy(pRgn);
- }
- return Success;
- }
- int
- ProcPolyPoint(ClientPtr client)
- {
- int npoint;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xPolyPointReq);
- REQUEST_AT_LEAST_SIZE(xPolyPointReq);
- if ((stuff->coordMode != CoordModeOrigin) &&
- (stuff->coordMode != CoordModePrevious)) {
- client->errorValue = stuff->coordMode;
- return BadValue;
- }
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
- if (npoint)
- (*pGC->ops->PolyPoint) (pDraw, pGC, stuff->coordMode, npoint,
- (xPoint *) &stuff[1]);
- return Success;
- }
- int
- ProcPolyLine(ClientPtr client)
- {
- int npoint;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xPolyLineReq);
- REQUEST_AT_LEAST_SIZE(xPolyLineReq);
- if ((stuff->coordMode != CoordModeOrigin) &&
- (stuff->coordMode != CoordModePrevious)) {
- client->errorValue = stuff->coordMode;
- return BadValue;
- }
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
- if (npoint > 1)
- (*pGC->ops->Polylines) (pDraw, pGC, stuff->coordMode, npoint,
- (DDXPointPtr) &stuff[1]);
- return Success;
- }
- int
- ProcPolySegment(ClientPtr client)
- {
- int nsegs;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xPolySegmentReq);
- REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
- if (nsegs & 4)
- return BadLength;
- nsegs >>= 3;
- if (nsegs)
- (*pGC->ops->PolySegment) (pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
- return Success;
- }
- int
- ProcPolyRectangle(ClientPtr client)
- {
- int nrects;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xPolyRectangleReq);
- REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
- if (nrects & 4)
- return BadLength;
- nrects >>= 3;
- if (nrects)
- (*pGC->ops->PolyRectangle) (pDraw, pGC,
- nrects, (xRectangle *) &stuff[1]);
- return Success;
- }
- int
- ProcPolyArc(ClientPtr client)
- {
- int narcs;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xPolyArcReq);
- REQUEST_AT_LEAST_SIZE(xPolyArcReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
- if (narcs % sizeof(xArc))
- return BadLength;
- narcs /= sizeof(xArc);
- if (narcs)
- (*pGC->ops->PolyArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
- return Success;
- }
- int
- ProcFillPoly(ClientPtr client)
- {
- int things;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xFillPolyReq);
- REQUEST_AT_LEAST_SIZE(xFillPolyReq);
- if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
- (stuff->shape != Convex)) {
- client->errorValue = stuff->shape;
- return BadValue;
- }
- if ((stuff->coordMode != CoordModeOrigin) &&
- (stuff->coordMode != CoordModePrevious)) {
- client->errorValue = stuff->coordMode;
- return BadValue;
- }
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
- if (things)
- (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
- stuff->coordMode, things,
- (DDXPointPtr) &stuff[1]);
- return Success;
- }
- int
- ProcPolyFillRectangle(ClientPtr client)
- {
- int things;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xPolyFillRectangleReq);
- REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
- if (things & 4)
- return BadLength;
- things >>= 3;
- if (things)
- (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
- (xRectangle *) &stuff[1]);
- return Success;
- }
- int
- ProcPolyFillArc(ClientPtr client)
- {
- int narcs;
- GC *pGC;
- DrawablePtr pDraw;
- REQUEST(xPolyFillArcReq);
- REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
- if (narcs % sizeof(xArc))
- return BadLength;
- narcs /= sizeof(xArc);
- if (narcs)
- (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
- return Success;
- }
- #ifdef MATCH_CLIENT_ENDIAN
- int
- ServerOrder(void)
- {
- int whichbyte = 1;
- if (*((char *) &whichbyte))
- return LSBFirst;
- return MSBFirst;
- }
- #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
- void
- ReformatImage(char *base, int nbytes, int bpp, int order)
- {
- switch (bpp) {
- case 1: /* yuck */
- if (BITMAP_BIT_ORDER != order)
- BitOrderInvert((unsigned char *) base, nbytes);
- #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
- ReformatImage(base, nbytes, BITMAP_SCANLINE_UNIT, order);
- #endif
- break;
- case 4:
- break; /* yuck */
- case 8:
- break;
- case 16:
- if (IMAGE_BYTE_ORDER != order)
- TwoByteSwap((unsigned char *) base, nbytes);
- break;
- case 32:
- if (IMAGE_BYTE_ORDER != order)
- FourByteSwap((unsigned char *) base, nbytes);
- break;
- }
- }
- #else
- #define ReformatImage(b,n,bpp,o)
- #endif
- /* 64-bit server notes: the protocol restricts padding of images to
- * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
- * to use internally. Removes need for internal alignment checking.
- * All of the PutImage functions could be changed individually, but
- * as currently written, they call other routines which require things
- * to be 64-bit padded on scanlines, so we changed things here.
- * If an image would be padded differently for 64- versus 32-, then
- * copy each scanline to a 64-bit padded scanline.
- * Also, we need to make sure that the image is aligned on a 64-bit
- * boundary, even if the scanlines are padded to our satisfaction.
- */
- int
- ProcPutImage(ClientPtr client)
- {
- GC *pGC;
- DrawablePtr pDraw;
- long length; /* length of scanline server padded */
- long lengthProto; /* length of scanline protocol padded */
- char *tmpImage;
- REQUEST(xPutImageReq);
- REQUEST_AT_LEAST_SIZE(xPutImageReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- if (stuff->format == XYBitmap) {
- if ((stuff->depth != 1) ||
- (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
- return BadMatch;
- length = BitmapBytePad(stuff->width + stuff->leftPad);
- }
- else if (stuff->format == XYPixmap) {
- if ((pDraw->depth != stuff->depth) ||
- (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
- return BadMatch;
- length = BitmapBytePad(stuff->width + stuff->leftPad);
- length *= stuff->depth;
- }
- else if (stuff->format == ZPixmap) {
- if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
- return BadMatch;
- length = PixmapBytePad(stuff->width, stuff->depth);
- }
- else {
- client->errorValue = stuff->format;
- return BadValue;
- }
- tmpImage = (char *) &stuff[1];
- lengthProto = length;
- if ((bytes_to_int32(lengthProto * stuff->height) +
- bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
- return BadLength;
- ReformatImage(tmpImage, lengthProto * stuff->height,
- stuff->format == ZPixmap ? BitsPerPixel(stuff->depth) : 1,
- ClientOrder(client));
- (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
- stuff->width, stuff->height,
- stuff->leftPad, stuff->format, tmpImage);
- return Success;
- }
- static int
- DoGetImage(ClientPtr client, int format, Drawable drawable,
- int x, int y, int width, int height,
- Mask planemask)
- {
- DrawablePtr pDraw, pBoundingDraw;
- int nlines, linesPerBuf, rc;
- int linesDone;
- /* coordinates relative to the bounding drawable */
- int relx, rely;
- long widthBytesLine, length;
- Mask plane = 0;
- char *pBuf;
- xGetImageReply xgi;
- RegionPtr pVisibleRegion = NULL;
- if ((format != XYPixmap) && (format != ZPixmap)) {
- client->errorValue = format;
- return BadValue;
- }
- rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
- if (rc != Success)
- return rc;
- memset(&xgi, 0, sizeof(xGetImageReply));
- relx = x;
- rely = y;
- if (pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr) pDraw;
- /* "If the drawable is a window, the window must be viewable ... or a
- * BadMatch error results" */
- if (!pWin->viewable)
- return BadMatch;
- /* If the drawable is a window, the rectangle must be contained within
- * its bounds (including the border). */
- if (x < -wBorderWidth(pWin) ||
- x + width > wBorderWidth(pWin) + (int) pDraw->width ||
- y < -wBorderWidth(pWin) ||
- y + height > wBorderWidth(pWin) + (int) pDraw->height)
- return BadMatch;
- relx += pDraw->x;
- rely += pDraw->y;
- if (pDraw->pScreen->GetWindowPixmap) {
- PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
- pBoundingDraw = &pPix->drawable;
- #ifdef COMPOSITE
- relx -= pPix->screen_x;
- rely -= pPix->screen_y;
- #endif
- }
- else {
- pBoundingDraw = (DrawablePtr) pDraw->pScreen->root;
- }
- xgi.visual = wVisual(pWin);
- }
- else {
- pBoundingDraw = pDraw;
- xgi.visual = None;
- }
- /* "If the drawable is a pixmap, the given rectangle must be wholly
- * contained within the pixmap, or a BadMatch error results. If the
- * drawable is a window [...] it must be the case that if there were no
- * inferiors or overlapping windows, the specified rectangle of the window
- * would be fully visible on the screen and wholly contained within the
- * outside edges of the window, or a BadMatch error results."
- *
- * We relax the window case slightly to mean that the rectangle must exist
- * within the bounds of the window's backing pixmap. In particular, this
- * means that a GetImage request may succeed or fail with BadMatch depending
- * on whether any of its ancestor windows are redirected. */
- if (relx < 0 || relx + width > (int) pBoundingDraw->width ||
- rely < 0 || rely + height > (int) pBoundingDraw->height)
- return BadMatch;
- xgi.type = X_Reply;
- xgi.sequenceNumber = client->sequence;
- xgi.depth = pDraw->depth;
- if (format == ZPixmap) {
- widthBytesLine = PixmapBytePad(width, pDraw->depth);
- length = widthBytesLine * height;
- }
- else {
- widthBytesLine = BitmapBytePad(width);
- plane = ((Mask) 1) << (pDraw->depth - 1);
- /* only planes asked for */
- length = widthBytesLine * height *
- Ones(planemask & (plane | (plane - 1)));
- }
- xgi.length = length;
- xgi.length = bytes_to_int32(xgi.length);
- if (widthBytesLine == 0 || height == 0)
- linesPerBuf = 0;
- else if (widthBytesLine >= IMAGE_BUFSIZE)
- linesPerBuf = 1;
- else {
- linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
- if (linesPerBuf > height)
- linesPerBuf = height;
- }
- length = linesPerBuf * widthBytesLine;
- if (linesPerBuf < height) {
- /* we have to make sure intermediate buffers don't need padding */
- while ((linesPerBuf > 1) &&
- (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1))) {
- linesPerBuf--;
- length -= widthBytesLine;
- }
- while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1)) {
- linesPerBuf++;
- length += widthBytesLine;
- }
- }
- if (!(pBuf = calloc(1, length)))
- return BadAlloc;
- WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
- if (pDraw->type == DRAWABLE_WINDOW) {
- pVisibleRegion = NotClippedByChildren((WindowPtr) pDraw);
- if (pVisibleRegion) {
- RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
- }
- }
- if (linesPerBuf == 0) {
- /* nothing to do */
- }
- else if (format == ZPixmap) {
- linesDone = 0;
- while (height - linesDone > 0) {
- nlines = min(linesPerBuf, height - linesDone);
- (*pDraw->pScreen->GetImage) (pDraw,
- x,
- y + linesDone,
- width,
- nlines,
- format, planemask, (void *) pBuf);
- if (pVisibleRegion)
- XaceCensorImage(client, pVisibleRegion, widthBytesLine,
- pDraw, x, y + linesDone, width,
- nlines, format, pBuf);
- /* Note that this is NOT a call to WriteSwappedDataToClient,
- as we do NOT byte swap */
- ReformatImage(pBuf, (int) (nlines * widthBytesLine),
- BitsPerPixel(pDraw->depth), ClientOrder(client));
- WriteToClient(client, (int) (nlines * widthBytesLine), pBuf);
- linesDone += nlines;
- }
- }
- else { /* XYPixmap */
- for (; plane; plane >>= 1) {
- if (planemask & plane) {
- linesDone = 0;
- while (height - linesDone > 0) {
- nlines = min(linesPerBuf, height - linesDone);
- (*pDraw->pScreen->GetImage) (pDraw,
- x,
- y + linesDone,
- width,
- nlines,
- format, plane, (void *) pBuf);
- if (pVisibleRegion)
- XaceCensorImage(client, pVisibleRegion,
- widthBytesLine,
- pDraw, x, y + linesDone, width,
- nlines, format, pBuf);
- /* Note: NOT a call to WriteSwappedDataToClient,
- as we do NOT byte swap */
- ReformatImage(pBuf, (int) (nlines * widthBytesLine),
- 1, ClientOrder(client));
- WriteToClient(client, (int)(nlines * widthBytesLine), pBuf);
- linesDone += nlines;
- }
- }
- }
- }
- if (pVisibleRegion)
- RegionDestroy(pVisibleRegion);
- free(pBuf);
- return Success;
- }
- int
- ProcGetImage(ClientPtr client)
- {
- REQUEST(xGetImageReq);
- REQUEST_SIZE_MATCH(xGetImageReq);
- return DoGetImage(client, stuff->format, stuff->drawable,
- stuff->x, stuff->y,
- (int) stuff->width, (int) stuff->height,
- stuff->planeMask);
- }
- int
- ProcPolyText(ClientPtr client)
- {
- int err;
- REQUEST(xPolyTextReq);
- DrawablePtr pDraw;
- GC *pGC;
- REQUEST_AT_LEAST_SIZE(xPolyTextReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- err = PolyText(client,
- pDraw,
- pGC,
- (unsigned char *) &stuff[1],
- ((unsigned char *) stuff) + (client->req_len << 2),
- stuff->x, stuff->y, stuff->reqType, stuff->drawable);
- if (err == Success) {
- return Success;
- }
- else
- return err;
- }
- int
- ProcImageText8(ClientPtr client)
- {
- int err;
- DrawablePtr pDraw;
- GC *pGC;
- REQUEST(xImageTextReq);
- REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- err = ImageText(client,
- pDraw,
- pGC,
- stuff->nChars,
- (unsigned char *) &stuff[1],
- stuff->x, stuff->y, stuff->reqType, stuff->drawable);
- if (err == Success) {
- return Success;
- }
- else
- return err;
- }
- int
- ProcImageText16(ClientPtr client)
- {
- int err;
- DrawablePtr pDraw;
- GC *pGC;
- REQUEST(xImageTextReq);
- REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- err = ImageText(client,
- pDraw,
- pGC,
- stuff->nChars,
- (unsigned char *) &stuff[1],
- stuff->x, stuff->y, stuff->reqType, stuff->drawable);
- if (err == Success) {
- return Success;
- }
- else
- return err;
- }
- int
- ProcCreateColormap(ClientPtr client)
- {
- VisualPtr pVisual;
- ColormapPtr pmap;
- Colormap mid;
- WindowPtr pWin;
- ScreenPtr pScreen;
- REQUEST(xCreateColormapReq);
- int i, result;
- REQUEST_SIZE_MATCH(xCreateColormapReq);
- if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) {
- client->errorValue = stuff->alloc;
- return BadValue;
- }
- mid = stuff->mid;
- LEGAL_NEW_RESOURCE(mid, client);
- result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (result != Success)
- return result;
- pScreen = pWin->drawable.pScreen;
- for (i = 0, pVisual = pScreen->visuals;
- i < pScreen->numVisuals; i++, pVisual++) {
- if (pVisual->vid != stuff->visual)
- continue;
- return CreateColormap(mid, pScreen, pVisual, &pmap,
- (int) stuff->alloc, client->index);
- }
- client->errorValue = stuff->visual;
- return BadMatch;
- }
- int
- ProcFreeColormap(ClientPtr client)
- {
- ColormapPtr pmap;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupResourceByType((void **) &pmap, stuff->id, RT_COLORMAP,
- client, DixDestroyAccess);
- if (rc == Success) {
- /* Freeing a default colormap is a no-op */
- if (!(pmap->flags & IsDefault))
- FreeResource(stuff->id, RT_NONE);
- return Success;
- }
- else {
- client->errorValue = stuff->id;
- return rc;
- }
- }
- int
- ProcCopyColormapAndFree(ClientPtr client)
- {
- Colormap mid;
- ColormapPtr pSrcMap;
- REQUEST(xCopyColormapAndFreeReq);
- int rc;
- REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
- mid = stuff->mid;
- LEGAL_NEW_RESOURCE(mid, client);
- rc = dixLookupResourceByType((void **) &pSrcMap, stuff->srcCmap,
- RT_COLORMAP, client,
- DixReadAccess | DixRemoveAccess);
- if (rc == Success)
- return CopyColormapAndFree(mid, pSrcMap, client->index);
- client->errorValue = stuff->srcCmap;
- return rc;
- }
- int
- ProcInstallColormap(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
- client, DixInstallAccess);
- if (rc != Success)
- goto out;
- rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
- if (rc != Success) {
- if (rc == BadValue)
- rc = BadColor;
- goto out;
- }
- (*(pcmp->pScreen->InstallColormap)) (pcmp);
- return Success;
- out:
- client->errorValue = stuff->id;
- return rc;
- }
- int
- ProcUninstallColormap(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
- client, DixUninstallAccess);
- if (rc != Success)
- goto out;
- rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
- if (rc != Success) {
- if (rc == BadValue)
- rc = BadColor;
- goto out;
- }
- if (pcmp->mid != pcmp->pScreen->defColormap)
- (*(pcmp->pScreen->UninstallColormap)) (pcmp);
- return Success;
- out:
- client->errorValue = stuff->id;
- return rc;
- }
- int
- ProcListInstalledColormaps(ClientPtr client)
- {
- xListInstalledColormapsReply *preply;
- int nummaps, rc;
- WindowPtr pWin;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- preply = malloc(sizeof(xListInstalledColormapsReply) +
- pWin->drawable.pScreen->maxInstalledCmaps *
- sizeof(Colormap));
- if (!preply)
- return BadAlloc;
- preply->type = X_Reply;
- preply->sequenceNumber = client->sequence;
- nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
- (pWin->drawable.pScreen, (Colormap *) &preply[1]);
- preply->nColormaps = nummaps;
- preply->length = nummaps;
- WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply);
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
- free(preply);
- return Success;
- }
- int
- ProcAllocColor(ClientPtr client)
- {
- ColormapPtr pmap;
- int rc;
- REQUEST(xAllocColorReq);
- REQUEST_SIZE_MATCH(xAllocColorReq);
- rc = dixLookupResourceByType((void **) &pmap, stuff->cmap, RT_COLORMAP,
- client, DixAddAccess);
- if (rc == Success) {
- xAllocColorReply acr = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0,
- .red = stuff->red,
- .green = stuff->green,
- .blue = stuff->blue,
- .pixel = 0
- };
- if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
- &acr.pixel, client->index)))
- return rc;
- #ifdef PANORAMIX
- if (noPanoramiXExtension || !pmap->pScreen->myNum)
- #endif
- WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
- return Success;
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcAllocNamedColor(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xAllocNamedColorReq);
- REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixAddAccess);
- if (rc == Success) {
- xAllocNamedColorReply ancr = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0
- };
- if (OsLookupColor
- (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
- &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) {
- ancr.screenRed = ancr.exactRed;
- ancr.screenGreen = ancr.exactGreen;
- ancr.screenBlue = ancr.exactBlue;
- ancr.pixel = 0;
- if ((rc = AllocColor(pcmp,
- &ancr.screenRed, &ancr.screenGreen,
- &ancr.screenBlue, &ancr.pixel, client->index)))
- return rc;
- #ifdef PANORAMIX
- if (noPanoramiXExtension || !pcmp->pScreen->myNum)
- #endif
- WriteReplyToClient(client, sizeof(xAllocNamedColorReply),
- &ancr);
- return Success;
- }
- else
- return BadName;
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcAllocColorCells(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xAllocColorCellsReq);
- REQUEST_SIZE_MATCH(xAllocColorCellsReq);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixAddAccess);
- if (rc == Success) {
- int npixels, nmasks;
- long length;
- Pixel *ppixels, *pmasks;
- npixels = stuff->colors;
- if (!npixels) {
- client->errorValue = npixels;
- return BadValue;
- }
- if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
- client->errorValue = stuff->contiguous;
- return BadValue;
- }
- nmasks = stuff->planes;
- length = ((long) npixels + (long) nmasks) * sizeof(Pixel);
- ppixels = malloc(length);
- if (!ppixels)
- return BadAlloc;
- pmasks = ppixels + npixels;
- if ((rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
- (Bool) stuff->contiguous, ppixels, pmasks))) {
- free(ppixels);
- return rc;
- }
- #ifdef PANORAMIX
- if (noPanoramiXExtension || !pcmp->pScreen->myNum)
- #endif
- {
- xAllocColorCellsReply accr = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = bytes_to_int32(length),
- .nPixels = npixels,
- .nMasks = nmasks
- };
- WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr);
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, length, ppixels);
- }
- free(ppixels);
- return Success;
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcAllocColorPlanes(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xAllocColorPlanesReq);
- REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixAddAccess);
- if (rc == Success) {
- xAllocColorPlanesReply acpr;
- int npixels;
- long length;
- Pixel *ppixels;
- npixels = stuff->colors;
- if (!npixels) {
- client->errorValue = npixels;
- return BadValue;
- }
- if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
- client->errorValue = stuff->contiguous;
- return BadValue;
- }
- acpr = (xAllocColorPlanesReply) {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .nPixels = npixels
- };
- length = (long) npixels *sizeof(Pixel);
- ppixels = malloc(length);
- if (!ppixels)
- return BadAlloc;
- if ((rc = AllocColorPlanes(client->index, pcmp, npixels,
- (int) stuff->red, (int) stuff->green,
- (int) stuff->blue, (Bool) stuff->contiguous,
- ppixels, &acpr.redMask, &acpr.greenMask,
- &acpr.blueMask))) {
- free(ppixels);
- return rc;
- }
- acpr.length = bytes_to_int32(length);
- #ifdef PANORAMIX
- if (noPanoramiXExtension || !pcmp->pScreen->myNum)
- #endif
- {
- WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, length, ppixels);
- }
- free(ppixels);
- return Success;
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcFreeColors(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xFreeColorsReq);
- REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixRemoveAccess);
- if (rc == Success) {
- int count;
- if (pcmp->flags & AllAllocated)
- return BadAccess;
- count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
- return FreeColors(pcmp, client->index, count,
- (Pixel *) &stuff[1], (Pixel) stuff->planeMask);
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcStoreColors(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xStoreColorsReq);
- REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixWriteAccess);
- if (rc == Success) {
- int count;
- count = (client->req_len << 2) - sizeof(xStoreColorsReq);
- if (count % sizeof(xColorItem))
- return BadLength;
- count /= sizeof(xColorItem);
- return StoreColors(pcmp, count, (xColorItem *) &stuff[1], client);
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcStoreNamedColor(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xStoreNamedColorReq);
- REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixWriteAccess);
- if (rc == Success) {
- xColorItem def;
- if (OsLookupColor(pcmp->pScreen->myNum, (char *) &stuff[1],
- stuff->nbytes, &def.red, &def.green, &def.blue)) {
- def.flags = stuff->flags;
- def.pixel = stuff->pixel;
- return StoreColors(pcmp, 1, &def, client);
- }
- return BadName;
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcQueryColors(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xQueryColorsReq);
- REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixReadAccess);
- if (rc == Success) {
- int count;
- xrgb *prgbs;
- xQueryColorsReply qcr;
- count =
- bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
- prgbs = calloc(1, count * sizeof(xrgb));
- if (!prgbs && count)
- return BadAlloc;
- if ((rc =
- QueryColors(pcmp, count, (Pixel *) &stuff[1], prgbs, client))) {
- free(prgbs);
- return rc;
- }
- qcr = (xQueryColorsReply) {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = bytes_to_int32(count * sizeof(xrgb)),
- .nColors = count
- };
- WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
- if (count) {
- client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
- WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
- }
- free(prgbs);
- return Success;
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcLookupColor(ClientPtr client)
- {
- ColormapPtr pcmp;
- int rc;
- REQUEST(xLookupColorReq);
- REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
- rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
- client, DixReadAccess);
- if (rc == Success) {
- CARD16 exactRed, exactGreen, exactBlue;
- if (OsLookupColor
- (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
- &exactRed, &exactGreen, &exactBlue)) {
- xLookupColorReply lcr = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0,
- .exactRed = exactRed,
- .exactGreen = exactGreen,
- .exactBlue = exactBlue,
- .screenRed = exactRed,
- .screenGreen = exactGreen,
- .screenBlue = exactBlue
- };
- (*pcmp->pScreen->ResolveColor) (&lcr.screenRed,
- &lcr.screenGreen,
- &lcr.screenBlue, pcmp->pVisual);
- WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
- return Success;
- }
- return BadName;
- }
- else {
- client->errorValue = stuff->cmap;
- return rc;
- }
- }
- int
- ProcCreateCursor(ClientPtr client)
- {
- CursorPtr pCursor;
- PixmapPtr src;
- PixmapPtr msk;
- unsigned char *srcbits;
- unsigned char *mskbits;
- unsigned short width, height;
- long n;
- CursorMetricRec cm;
- int rc;
- REQUEST(xCreateCursorReq);
- REQUEST_SIZE_MATCH(xCreateCursorReq);
- LEGAL_NEW_RESOURCE(stuff->cid, client);
- rc = dixLookupResourceByType((void **) &src, stuff->source, RT_PIXMAP,
- client, DixReadAccess);
- if (rc != Success) {
- client->errorValue = stuff->source;
- return rc;
- }
- if (src->drawable.depth != 1)
- return (BadMatch);
- /* Find and validate cursor mask pixmap, if one is provided */
- if (stuff->mask != None) {
- rc = dixLookupResourceByType((void **) &msk, stuff->mask, RT_PIXMAP,
- client, DixReadAccess);
- if (rc != Success) {
- client->errorValue = stuff->mask;
- return rc;
- }
- if (src->drawable.width != msk->drawable.width
- || src->drawable.height != msk->drawable.height
- || src->drawable.depth != 1 || msk->drawable.depth != 1)
- return BadMatch;
- }
- else
- msk = NULL;
- width = src->drawable.width;
- height = src->drawable.height;
- if (stuff->x > width || stuff->y > height)
- return BadMatch;
- n = BitmapBytePad(width) * height;
- srcbits = calloc(1, n);
- if (!srcbits)
- return BadAlloc;
- mskbits = malloc(n);
- if (!mskbits) {
- free(srcbits);
- return BadAlloc;
- }
- (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height,
- XYPixmap, 1, (void *) srcbits);
- if (msk == (PixmapPtr) NULL) {
- unsigned char *bits = mskbits;
- while (--n >= 0)
- *bits++ = ~0;
- }
- else {
- /* zeroing the (pad) bits helps some ddx cursor handling */
- memset((char *) mskbits, 0, n);
- (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width,
- height, XYPixmap, 1,
- (void *) mskbits);
- }
- cm.width = width;
- cm.height = height;
- cm.xhot = stuff->x;
- cm.yhot = stuff->y;
- rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
- stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
- stuff->backRed, stuff->backGreen, stuff->backBlue,
- &pCursor, client, stuff->cid);
- if (rc != Success)
- goto bail;
- if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
- rc = BadAlloc;
- goto bail;
- }
- return Success;
- bail:
- free(srcbits);
- free(mskbits);
- return rc;
- }
- int
- ProcCreateGlyphCursor(ClientPtr client)
- {
- CursorPtr pCursor;
- int res;
- REQUEST(xCreateGlyphCursorReq);
- REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
- LEGAL_NEW_RESOURCE(stuff->cid, client);
- res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
- stuff->mask, stuff->maskChar,
- stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
- stuff->backRed, stuff->backGreen, stuff->backBlue,
- &pCursor, client, stuff->cid);
- if (res != Success)
- return res;
- if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
- return Success;
- return BadAlloc;
- }
- int
- ProcFreeCursor(ClientPtr client)
- {
- CursorPtr pCursor;
- int rc;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR,
- client, DixDestroyAccess);
- if (rc == Success) {
- FreeResource(stuff->id, RT_NONE);
- return Success;
- }
- else {
- client->errorValue = stuff->id;
- return rc;
- }
- }
- int
- ProcQueryBestSize(ClientPtr client)
- {
- xQueryBestSizeReply reply;
- DrawablePtr pDraw;
- ScreenPtr pScreen;
- int rc;
- REQUEST(xQueryBestSizeReq);
- REQUEST_SIZE_MATCH(xQueryBestSizeReq);
- if ((stuff->class != CursorShape) &&
- (stuff->class != TileShape) && (stuff->class != StippleShape)) {
- client->errorValue = stuff->class;
- return BadValue;
- }
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
- return BadMatch;
- pScreen = pDraw->pScreen;
- rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- (*pScreen->QueryBestSize) (stuff->class, &stuff->width,
- &stuff->height, pScreen);
- reply = (xQueryBestSizeReply) {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0,
- .width = stuff->width,
- .height = stuff->height
- };
- WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
- return Success;
- }
- int
- ProcSetScreenSaver(ClientPtr client)
- {
- int rc, i, blankingOption, exposureOption;
- REQUEST(xSetScreenSaverReq);
- REQUEST_SIZE_MATCH(xSetScreenSaverReq);
- for (i = 0; i < screenInfo.numScreens; i++) {
- rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
- DixSetAttrAccess);
- if (rc != Success)
- return rc;
- }
- blankingOption = stuff->preferBlank;
- if ((blankingOption != DontPreferBlanking) &&
- (blankingOption != PreferBlanking) &&
- (blankingOption != DefaultBlanking)) {
- client->errorValue = blankingOption;
- return BadValue;
- }
- exposureOption = stuff->allowExpose;
- if ((exposureOption != DontAllowExposures) &&
- (exposureOption != AllowExposures) &&
- (exposureOption != DefaultExposures)) {
- client->errorValue = exposureOption;
- return BadValue;
- }
- if (stuff->timeout < -1) {
- client->errorValue = stuff->timeout;
- return BadValue;
- }
- if (stuff->interval < -1) {
- client->errorValue = stuff->interval;
- return BadValue;
- }
- if (blankingOption == DefaultBlanking)
- ScreenSaverBlanking = defaultScreenSaverBlanking;
- else
- ScreenSaverBlanking = blankingOption;
- if (exposureOption == DefaultExposures)
- ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
- else
- ScreenSaverAllowExposures = exposureOption;
- if (stuff->timeout >= 0)
- ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
- else
- ScreenSaverTime = defaultScreenSaverTime;
- if (stuff->interval >= 0)
- ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
- else
- ScreenSaverInterval = defaultScreenSaverInterval;
- SetScreenSaverTimer();
- return Success;
- }
- int
- ProcGetScreenSaver(ClientPtr client)
- {
- xGetScreenSaverReply rep;
- int rc, i;
- REQUEST_SIZE_MATCH(xReq);
- for (i = 0; i < screenInfo.numScreens; i++) {
- rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- }
- rep = (xGetScreenSaverReply) {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0,
- .timeout = ScreenSaverTime / MILLI_PER_SECOND,
- .interval = ScreenSaverInterval / MILLI_PER_SECOND,
- .preferBlanking = ScreenSaverBlanking,
- .allowExposures = ScreenSaverAllowExposures
- };
- WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
- return Success;
- }
- int
- ProcChangeHosts(ClientPtr client)
- {
- REQUEST(xChangeHostsReq);
- REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
- if (stuff->mode == HostInsert)
- return AddHost(client, (int) stuff->hostFamily,
- stuff->hostLength, (void *) &stuff[1]);
- if (stuff->mode == HostDelete)
- return RemoveHost(client, (int) stuff->hostFamily,
- stuff->hostLength, (void *) &stuff[1]);
- client->errorValue = stuff->mode;
- return BadValue;
- }
- int
- ProcListHosts(ClientPtr client)
- {
- xListHostsReply reply;
- int len, nHosts, result;
- BOOL enabled;
- void *pdata;
- /* REQUEST(xListHostsReq); */
- REQUEST_SIZE_MATCH(xListHostsReq);
- /* untrusted clients can't list hosts */
- result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
- if (result != Success)
- return result;
- result = GetHosts(&pdata, &nHosts, &len, &enabled);
- if (result != Success)
- return result;
- reply = (xListHostsReply) {
- .type = X_Reply,
- .enabled = enabled,
- .sequenceNumber = client->sequence,
- .length = bytes_to_int32(len),
- .nHosts = nHosts
- };
- WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
- if (nHosts) {
- client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
- WriteSwappedDataToClient(client, len, pdata);
- }
- free(pdata);
- return Success;
- }
- int
- ProcChangeAccessControl(ClientPtr client)
- {
- REQUEST(xSetAccessControlReq);
- REQUEST_SIZE_MATCH(xSetAccessControlReq);
- if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) {
- client->errorValue = stuff->mode;
- return BadValue;
- }
- return ChangeAccessControl(client, stuff->mode == EnableAccess);
- }
- /*********************
- * CloseDownRetainedResources
- *
- * Find all clients that are gone and have terminated in RetainTemporary
- * and destroy their resources.
- *********************/
- static void
- CloseDownRetainedResources(void)
- {
- int i;
- ClientPtr client;
- for (i = 1; i < currentMaxClients; i++) {
- client = clients[i];
- if (client && (client->closeDownMode == RetainTemporary)
- && (client->clientGone))
- CloseDownClient(client);
- }
- }
- int
- ProcKillClient(ClientPtr client)
- {
- REQUEST(xResourceReq);
- ClientPtr killclient;
- int rc;
- REQUEST_SIZE_MATCH(xResourceReq);
- if (stuff->id == AllTemporary) {
- CloseDownRetainedResources();
- return Success;
- }
- rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
- if (rc == Success) {
- CloseDownClient(killclient);
- /* if an LBX proxy gets killed, isItTimeToYield will be set */
- if (isItTimeToYield || (client == killclient)) {
- /* force yield and return Success, so that Dispatch()
- * doesn't try to touch client
- */
- isItTimeToYield = TRUE;
- return Success;
- }
- return Success;
- }
- else
- return rc;
- }
- int
- ProcSetFontPath(ClientPtr client)
- {
- unsigned char *ptr;
- unsigned long nbytes, total;
- long nfonts;
- int n;
- REQUEST(xSetFontPathReq);
- REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
- nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
- total = nbytes;
- ptr = (unsigned char *) &stuff[1];
- nfonts = stuff->nFonts;
- while (--nfonts >= 0) {
- if ((total == 0) || (total < (n = (*ptr + 1))))
- return BadLength;
- total -= n;
- ptr += n;
- }
- if (total >= 4)
- return BadLength;
- return SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]);
- }
- int
- ProcGetFontPath(ClientPtr client)
- {
- xGetFontPathReply reply;
- int rc, stringLens, numpaths;
- unsigned char *bufferStart;
- /* REQUEST (xReq); */
- REQUEST_SIZE_MATCH(xReq);
- rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
- if (rc != Success)
- return rc;
- reply = (xGetFontPathReply) {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = bytes_to_int32(stringLens + numpaths),
- .nPaths = numpaths
- };
- WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
- if (stringLens || numpaths)
- WriteToClient(client, stringLens + numpaths, bufferStart);
- return Success;
- }
- int
- ProcChangeCloseDownMode(ClientPtr client)
- {
- int rc;
- REQUEST(xSetCloseDownModeReq);
- REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
- rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
- if (rc != Success)
- return rc;
- if ((stuff->mode == AllTemporary) ||
- (stuff->mode == RetainPermanent) || (stuff->mode == RetainTemporary)) {
- client->closeDownMode = stuff->mode;
- return Success;
- }
- else {
- client->errorValue = stuff->mode;
- return BadValue;
- }
- }
- int
- ProcForceScreenSaver(ClientPtr client)
- {
- int rc;
- REQUEST(xForceScreenSaverReq);
- REQUEST_SIZE_MATCH(xForceScreenSaverReq);
- if ((stuff->mode != ScreenSaverReset) && (stuff->mode != ScreenSaverActive)) {
- client->errorValue = stuff->mode;
- return BadValue;
- }
- rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int) stuff->mode);
- if (rc != Success)
- return rc;
- return Success;
- }
- int
- ProcNoOperation(ClientPtr client)
- {
- REQUEST_AT_LEAST_SIZE(xReq);
- /* noop -- don't do anything */
- return Success;
- }
- /**********************
- * CloseDownClient
- *
- * Client can either mark his resources destroy or retain. If retained and
- * then killed again, the client is really destroyed.
- *********************/
- char dispatchExceptionAtReset = DE_RESET;
- void
- CloseDownClient(ClientPtr client)
- {
- Bool really_close_down = client->clientGone ||
- client->closeDownMode == DestroyAll;
- if (!client->clientGone) {
- /* ungrab server if grabbing client dies */
- if (grabState != GrabNone && grabClient == client) {
- UngrabServer(client);
- }
- BITCLEAR(grabWaiters, client->index);
- DeleteClientFromAnySelections(client);
- ReleaseActiveGrabs(client);
- DeleteClientFontStuff(client);
- if (!really_close_down) {
- /* This frees resources that should never be retained
- * no matter what the close down mode is. Actually we
- * could do this unconditionally, but it's probably
- * better not to traverse all the client's resources
- * twice (once here, once a few lines down in
- * FreeClientResources) in the common case of
- * really_close_down == TRUE.
- */
- FreeClientNeverRetainResources(client);
- client->clientState = ClientStateRetained;
- if (ClientStateCallback) {
- NewClientInfoRec clientinfo;
- clientinfo.client = client;
- clientinfo.prefix = (xConnSetupPrefix *) NULL;
- clientinfo.setup = (xConnSetup *) NULL;
- CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
- }
- }
- client->clientGone = TRUE; /* so events aren't sent to client */
- if (ClientIsAsleep(client))
- ClientSignal(client);
- ProcessWorkQueueZombies();
- CloseDownConnection(client);
- /* If the client made it to the Running stage, nClients has
- * been incremented on its behalf, so we need to decrement it
- * now. If it hasn't gotten to Running, nClients has *not*
- * been incremented, so *don't* decrement it.
- */
- if (client->clientState != ClientStateInitial) {
- --nClients;
- }
- }
- if (really_close_down) {
- if (client->clientState == ClientStateRunning && nClients == 0)
- dispatchException |= dispatchExceptionAtReset;
- client->clientState = ClientStateGone;
- if (ClientStateCallback) {
- NewClientInfoRec clientinfo;
- clientinfo.client = client;
- clientinfo.prefix = (xConnSetupPrefix *) NULL;
- clientinfo.setup = (xConnSetup *) NULL;
- CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
- }
- TouchListenerGone(client->clientAsMask);
- FreeClientResources(client);
- /* Disable client ID tracking. This must be done after
- * ClientStateCallback. */
- ReleaseClientIds(client);
- #ifdef XSERVER_DTRACE
- XSERVER_CLIENT_DISCONNECT(client->index);
- #endif
- if (client->index < nextFreeClientID)
- nextFreeClientID = client->index;
- clients[client->index] = NullClient;
- SmartLastClient = NullClient;
- dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
- while (!clients[currentMaxClients - 1])
- currentMaxClients--;
- }
- }
- static void
- KillAllClients(void)
- {
- int i;
- for (i = 1; i < currentMaxClients; i++)
- if (clients[i]) {
- /* Make sure Retained clients are released. */
- clients[i]->closeDownMode = DestroyAll;
- CloseDownClient(clients[i]);
- }
- }
- void
- InitClient(ClientPtr client, int i, void *ospriv)
- {
- client->index = i;
- client->clientAsMask = ((Mask) i) << CLIENTOFFSET;
- client->closeDownMode = i ? DestroyAll : RetainPermanent;
- client->requestVector = InitialVector;
- client->osPrivate = ospriv;
- QueryMinMaxKeyCodes(&client->minKC, &client->maxKC);
- client->smart_start_tick = SmartScheduleTime;
- client->smart_stop_tick = SmartScheduleTime;
- client->clientIds = NULL;
- }
- /************************
- * int NextAvailableClient(ospriv)
- *
- * OS dependent portion can't assign client id's because of CloseDownModes.
- * Returns NULL if there are no free clients.
- *************************/
- ClientPtr
- NextAvailableClient(void *ospriv)
- {
- int i;
- ClientPtr client;
- xReq data;
- i = nextFreeClientID;
- if (i == MAXCLIENTS)
- return (ClientPtr) NULL;
- clients[i] = client =
- dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT);
- if (!client)
- return (ClientPtr) NULL;
- InitClient(client, i, ospriv);
- if (!InitClientResources(client)) {
- dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
- return (ClientPtr) NULL;
- }
- data.reqType = 1;
- data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
- if (!InsertFakeRequest(client, (char *) &data, sz_xReq)) {
- FreeClientResources(client);
- dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
- return (ClientPtr) NULL;
- }
- if (i == currentMaxClients)
- currentMaxClients++;
- while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
- nextFreeClientID++;
- /* Enable client ID tracking. This must be done before
- * ClientStateCallback. */
- ReserveClientIds(client);
- if (ClientStateCallback) {
- NewClientInfoRec clientinfo;
- clientinfo.client = client;
- clientinfo.prefix = (xConnSetupPrefix *) NULL;
- clientinfo.setup = (xConnSetup *) NULL;
- CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
- }
- return client;
- }
- int
- ProcInitialConnection(ClientPtr client)
- {
- REQUEST(xReq);
- xConnClientPrefix *prefix;
- int whichbyte = 1;
- char order;
- prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq);
- order = prefix->byteOrder;
- if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
- return client->noClientException = -1;
- if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
- (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) {
- client->swapped = TRUE;
- SwapConnClientPrefix(prefix);
- }
- stuff->reqType = 2;
- stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
- bytes_to_int32(prefix->nbytesAuthString);
- if (client->swapped) {
- swaps(&stuff->length);
- }
- if (order == 'r' || order == 'R') {
- client->local = FALSE;
- }
- ResetCurrentRequest(client);
- return Success;
- }
- static int
- SendConnSetup(ClientPtr client, const char *reason)
- {
- xWindowRoot *root;
- int i;
- int numScreens;
- char *lConnectionInfo;
- xConnSetupPrefix *lconnSetupPrefix;
- if (reason) {
- xConnSetupPrefix csp;
- csp.success = xFalse;
- csp.lengthReason = strlen(reason);
- csp.length = bytes_to_int32(csp.lengthReason);
- csp.majorVersion = X_PROTOCOL;
- csp.minorVersion = X_PROTOCOL_REVISION;
- if (client->swapped)
- WriteSConnSetupPrefix(client, &csp);
- else
- WriteToClient(client, sz_xConnSetupPrefix, &csp);
- WriteToClient(client, (int) csp.lengthReason, reason);
- return client->noClientException = -1;
- }
- numScreens = screenInfo.numScreens;
- lConnectionInfo = ConnectionInfo;
- lconnSetupPrefix = &connSetupPrefix;
- /* We're about to start speaking X protocol back to the client by
- * sending the connection setup info. This means the authorization
- * step is complete, and we can count the client as an
- * authorized one.
- */
- nClients++;
- client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
- client->sequence = 0;
- ((xConnSetup *) lConnectionInfo)->ridBase = client->clientAsMask;
- ((xConnSetup *) lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
- #ifdef MATCH_CLIENT_ENDIAN
- ((xConnSetup *) lConnectionInfo)->imageByteOrder = ClientOrder(client);
- ((xConnSetup *) lConnectionInfo)->bitmapBitOrder = ClientOrder(client);
- #endif
- /* fill in the "currentInputMask" */
- root = (xWindowRoot *) (lConnectionInfo + connBlockScreenStart);
- #ifdef PANORAMIX
- if (noPanoramiXExtension)
- numScreens = screenInfo.numScreens;
- else
- numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
- #endif
- for (i = 0; i < numScreens; i++) {
- unsigned int j;
- xDepth *pDepth;
- WindowPtr pRoot = screenInfo.screens[i]->root;
- root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
- pDepth = (xDepth *) (root + 1);
- for (j = 0; j < root->nDepths; j++) {
- pDepth = (xDepth *) (((char *) (pDepth + 1)) +
- pDepth->nVisuals * sizeof(xVisualType));
- }
- root = (xWindowRoot *) pDepth;
- }
- if (client->swapped) {
- WriteSConnSetupPrefix(client, lconnSetupPrefix);
- WriteSConnectionInfo(client,
- (unsigned long) (lconnSetupPrefix->length << 2),
- lConnectionInfo);
- }
- else {
- WriteToClient(client, sizeof(xConnSetupPrefix), lconnSetupPrefix);
- WriteToClient(client, (int) (lconnSetupPrefix->length << 2),
- lConnectionInfo);
- }
- client->clientState = ClientStateRunning;
- if (ClientStateCallback) {
- NewClientInfoRec clientinfo;
- clientinfo.client = client;
- clientinfo.prefix = lconnSetupPrefix;
- clientinfo.setup = (xConnSetup *) lConnectionInfo;
- CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
- }
- return Success;
- }
- int
- ProcEstablishConnection(ClientPtr client)
- {
- const char *reason;
- char *auth_proto, *auth_string;
- xConnClientPrefix *prefix;
- REQUEST(xReq);
- prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
- auth_proto = (char *) prefix + sz_xConnClientPrefix;
- auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
- if ((prefix->majorVersion != X_PROTOCOL) ||
- (prefix->minorVersion != X_PROTOCOL_REVISION))
- reason = "Protocol version mismatch";
- else
- reason = ClientAuthorized(client,
- (unsigned short) prefix->nbytesAuthProto,
- auth_proto,
- (unsigned short) prefix->nbytesAuthString,
- auth_string);
- return (SendConnSetup(client, reason));
- }
- void
- SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
- XID resId, int errorCode)
- {
- xError rep = {
- .type = X_Error,
- .errorCode = errorCode,
- .resourceID = resId,
- .minorCode = minorCode,
- .majorCode = majorCode
- };
- WriteEventsToClient(client, 1, (xEvent *) &rep);
- }
- void
- MarkClientException(ClientPtr client)
- {
- client->noClientException = -1;
- }
- /*
- * This array encodes the answer to the question "what is the log base 2
- * of the number of pixels that fit in a scanline pad unit?"
- * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
- */
- static int answer[6][4] = {
- /* pad pad pad pad */
- /* 8 16 32 64 */
- {3, 4, 5, 6}, /* 1 bit per pixel */
- {1, 2, 3, 4}, /* 4 bits per pixel */
- {0, 1, 2, 3}, /* 8 bits per pixel */
- {~0, 0, 1, 2}, /* 16 bits per pixel */
- {~0, ~0, 0, 1}, /* 24 bits per pixel */
- {~0, ~0, 0, 1} /* 32 bits per pixel */
- };
- /*
- * This array gives the answer to the question "what is the first index for
- * the answer array above given the number of bits per pixel?"
- * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
- */
- static int indexForBitsPerPixel[33] = {
- ~0, 0, ~0, ~0, /* 1 bit per pixel */
- 1, ~0, ~0, ~0, /* 4 bits per pixel */
- 2, ~0, ~0, ~0, /* 8 bits per pixel */
- ~0, ~0, ~0, ~0,
- 3, ~0, ~0, ~0, /* 16 bits per pixel */
- ~0, ~0, ~0, ~0,
- 4, ~0, ~0, ~0, /* 24 bits per pixel */
- ~0, ~0, ~0, ~0,
- 5 /* 32 bits per pixel */
- };
- /*
- * This array gives the bytesperPixel value for cases where the number
- * of bits per pixel is a multiple of 8 but not a power of 2.
- */
- static int answerBytesPerPixel[33] = {
- ~0, 0, ~0, ~0, /* 1 bit per pixel */
- 0, ~0, ~0, ~0, /* 4 bits per pixel */
- 0, ~0, ~0, ~0, /* 8 bits per pixel */
- ~0, ~0, ~0, ~0,
- 0, ~0, ~0, ~0, /* 16 bits per pixel */
- ~0, ~0, ~0, ~0,
- 3, ~0, ~0, ~0, /* 24 bits per pixel */
- ~0, ~0, ~0, ~0,
- 0 /* 32 bits per pixel */
- };
- /*
- * This array gives the answer to the question "what is the second index for
- * the answer array above given the number of bits per scanline pad unit?"
- * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
- */
- static int indexForScanlinePad[65] = {
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
- ~0, ~0, ~0, ~0,
- 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0,
- 3 /* 64 bits per scanline pad unit */
- };
- /*
- grow the array of screenRecs if necessary.
- call the device-supplied initialization procedure
- with its screen number, a pointer to its ScreenRec, argc, and argv.
- return the number of successfully installed screens.
- */
- static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
- {
- int scanlinepad, format, depth, bitsPerPixel, j, k;
- dixInitScreenSpecificPrivates(pScreen);
- if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
- return -1;
- }
- pScreen->myNum = i;
- if (gpu) {
- pScreen->myNum += GPU_SCREEN_OFFSET;
- pScreen->isGPU = TRUE;
- }
- pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */
- pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
- pScreen->CreateScreenResources = 0;
- xorg_list_init(&pScreen->pixmap_dirty_list);
- xorg_list_init(&pScreen->unattached_list);
- xorg_list_init(&pScreen->output_slave_list);
- xorg_list_init(&pScreen->offload_slave_list);
- /*
- * This loop gets run once for every Screen that gets added,
- * but thats ok. If the ddx layer initializes the formats
- * one at a time calling AddScreen() after each, then each
- * iteration will make it a little more accurate. Worst case
- * we do this loop N * numPixmapFormats where N is # of screens.
- * Anyway, this must be called after InitOutput and before the
- * screen init routine is called.
- */
- for (format = 0; format < screenInfo.numPixmapFormats; format++) {
- depth = screenInfo.formats[format].depth;
- bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
- scanlinepad = screenInfo.formats[format].scanlinePad;
- j = indexForBitsPerPixel[bitsPerPixel];
- k = indexForScanlinePad[scanlinepad];
- PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k];
- PixmapWidthPaddingInfo[depth].padRoundUp =
- (scanlinepad / bitsPerPixel) - 1;
- j = indexForBitsPerPixel[8]; /* bits per byte */
- PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k];
- PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel;
- if (answerBytesPerPixel[bitsPerPixel]) {
- PixmapWidthPaddingInfo[depth].notPower2 = 1;
- PixmapWidthPaddingInfo[depth].bytesPerPixel =
- answerBytesPerPixel[bitsPerPixel];
- }
- else {
- PixmapWidthPaddingInfo[depth].notPower2 = 0;
- }
- }
- return 0;
- }
- int
- AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
- int /*argc */ ,
- char ** /*argv */
- ), int argc, char **argv)
- {
- int i;
- ScreenPtr pScreen;
- Bool ret;
- i = screenInfo.numScreens;
- if (i == MAXSCREENS)
- return -1;
- pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
- if (!pScreen)
- return -1;
- ret = init_screen(pScreen, i, FALSE);
- if (ret != 0) {
- free(pScreen);
- return ret;
- }
- /* This is where screen specific stuff gets initialized. Load the
- screen structure, call the hardware, whatever.
- This is also where the default colormap should be allocated and
- also pixel values for blackPixel, whitePixel, and the cursor
- Note that InitScreen is NOT allowed to modify argc, argv, or
- any of the strings pointed to by argv. They may be passed to
- multiple screens.
- */
- screenInfo.screens[i] = pScreen;
- screenInfo.numScreens++;
- if (!(*pfnInit) (pScreen, argc, argv)) {
- dixFreeScreenSpecificPrivates(pScreen);
- dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
- free(pScreen);
- screenInfo.numScreens--;
- return -1;
- }
- update_desktop_dimensions();
- dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR,
- 0);
- return i;
- }
- int
- AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
- int /*argc */ ,
- char ** /*argv */
- ),
- int argc, char **argv)
- {
- int i;
- ScreenPtr pScreen;
- Bool ret;
- i = screenInfo.numGPUScreens;
- if (i == MAXGPUSCREENS)
- return -1;
- pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
- if (!pScreen)
- return -1;
- ret = init_screen(pScreen, i, TRUE);
- if (ret != 0) {
- free(pScreen);
- return ret;
- }
- /* This is where screen specific stuff gets initialized. Load the
- screen structure, call the hardware, whatever.
- This is also where the default colormap should be allocated and
- also pixel values for blackPixel, whitePixel, and the cursor
- Note that InitScreen is NOT allowed to modify argc, argv, or
- any of the strings pointed to by argv. They may be passed to
- multiple screens.
- */
- screenInfo.gpuscreens[i] = pScreen;
- screenInfo.numGPUScreens++;
- if (!(*pfnInit) (pScreen, argc, argv)) {
- dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
- free(pScreen);
- screenInfo.numGPUScreens--;
- return -1;
- }
- update_desktop_dimensions();
- return i;
- }
- void
- RemoveGPUScreen(ScreenPtr pScreen)
- {
- int idx, j;
- if (!pScreen->isGPU)
- return;
- idx = pScreen->myNum - GPU_SCREEN_OFFSET;
- for (j = idx; j < screenInfo.numGPUScreens - 1; j++) {
- screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1];
- screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET;
- }
- screenInfo.numGPUScreens--;
- /* this gets freed later in the resource list, but without
- * the screen existing it causes crashes - so remove it here */
- if (pScreen->defColormap)
- FreeResource(pScreen->defColormap, RT_COLORMAP);
- free(pScreen);
- }
- void
- AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new)
- {
- assert(new->isGPU);
- assert(!new->current_master);
- xorg_list_add(&new->unattached_head, &pScreen->unattached_list);
- new->current_master = pScreen;
- }
- void
- DetachUnboundGPU(ScreenPtr slave)
- {
- assert(slave->isGPU);
- xorg_list_del(&slave->unattached_head);
- slave->current_master = NULL;
- }
- void
- AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
- {
- assert(new->isGPU);
- xorg_list_add(&new->output_head, &pScreen->output_slave_list);
- new->current_master = pScreen;
- }
- void
- DetachOutputGPU(ScreenPtr slave)
- {
- assert(slave->isGPU);
- xorg_list_del(&slave->output_head);
- slave->current_master = NULL;
- }
- void
- AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new)
- {
- assert(new->isGPU);
- xorg_list_add(&new->offload_head, &pScreen->offload_slave_list);
- new->current_master = pScreen;
- }
- void
- DetachOffloadGPU(ScreenPtr slave)
- {
- assert(slave->isGPU);
- xorg_list_del(&slave->offload_head);
- slave->current_master = NULL;
- }