/dix/dispatch.c
C | 3954 lines | 3129 code | 518 blank | 307 comment | 679 complexity | a5f6722dc3f3ce4f37c2982ae68d9e31 MD5 | raw file
Possible License(s): MIT
Large files files are truncated, but you can click here to view the full file
- /************************************************************
- 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;
- …
Large files files are truncated, but you can click here to view the full file