Commit message: dix: Allow zero-height PutImage requests

The length checking code validates PutImage height and byte width by
making sure that byte-width >= INT32_MAX / height. If height is zero,
this generates a divide by zero exception. Allow zero height requests
explicitly, bypassing the INT32_MAX check.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
CVE: CVE-2015-3418
CWE: CWE-369
Vulnerability description: The ProcPutImage function in dix/dispatch.c in X.Org Server (aka xserver and xorg-server) before 1.16.4 allows attackers to cause a denial of service (divide-by-zero and crash) via a zero-height PutImage request.

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
{
    assert(new->isGPU);
    xorg_list_add(&new->output_head, &pScreen->output_slave_list);
    new->current_master = pScreen;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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--;
    }
}

Project: xserver
File: dispatch.c

CloseDownRetainedResources(void)
{
    int i;
    ClientPtr client;

    for (i = 1; i < currentMaxClients; i++) {
        client = clients[i];
        if (client && (client->closeDownMode == RetainTemporary)
            && (client->clientGone))
            CloseDownClient(client);
    }
}

Project: xserver
File: dispatch.c

DetachOffloadGPU(ScreenPtr slave)
{
    assert(slave->isGPU);
    xorg_list_del(&slave->offload_head);
    slave->current_master = NULL;
}

Project: xserver
File: dispatch.c

DetachOutputGPU(ScreenPtr slave)
{
    assert(slave->isGPU);
    xorg_list_del(&slave->output_head);
    slave->current_master = NULL;
}

Project: xserver
File: dispatch.c

DetachUnboundGPU(ScreenPtr slave)
{
    assert(slave->isGPU);
    xorg_list_del(&slave->unattached_head);
    slave->current_master = NULL;
}

Project: xserver
File: dispatch.c

DisableLimitedSchedulingLatency(void)
{
    --SmartScheduleLatencyLimited;

    /* protect against bugs */
    if (SmartScheduleLatencyLimited < 0)
        SmartScheduleLatencyLimited = 0;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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]);
        }
}

Project: xserver
File: dispatch.c

MarkClientException(ClientPtr client)
{
    client->noClientException = -1;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

ProcBadRequest(ClientPtr client)
{
    return BadRequest;
}

Project: xserver
File: dispatch.c

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]);
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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);
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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);
}

Project: xserver
File: dispatch.c

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) {
        SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
        if (pRgn)
            RegionDestroy(pRgn);
    }

    return Success;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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);
}

Project: xserver
File: dispatch.c

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) {
        SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
        if (pRgn)
            RegionDestroy(pRgn);
    }
    return Success;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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));
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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);
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

ProcListFontsWithInfo(ClientPtr client)
{
    REQUEST(xListFontsWithInfoReq);

    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);

    return StartListFontsWithInfo(client, stuff->nbytes,
                                  (unsigned char *) &stuff[1], stuff->maxNames);
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

ProcNoOperation(ClientPtr client)
{
    REQUEST_AT_LEAST_SIZE(xReq);

    /* noop -- don't do anything */
    return Success;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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);
}

Project: xserver
File: dispatch.c

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);
}

Project: xserver
File: dispatch.c

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]);
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

ProcUngrabServer(ClientPtr client)
{
    REQUEST_SIZE_MATCH(xReq);
    UngrabServer(client);
    return Success;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
    }
}

Project: xserver
File: dispatch.c

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);

}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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);
}

Project: xserver
File: dispatch.c

ServerOrder(void)
{
    int whichbyte = 1;

    if (*((char *) &whichbyte))
        return LSBFirst;
    return MSBFirst;
}

Project: xserver
File: dispatch.c

SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
{
    checkForInput[0] = c0;
    checkForInput[1] = c1;
}

Project: xserver
File: dispatch.c

SetVendorRelease(int release)
{
    VendorRelease = release;
}

Project: xserver
File: dispatch.c

SetVendorString(const char *vendor)
{
    VendorString = vendor;
}

Project: xserver
File: dispatch.c

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);
    }
}

Project: xserver
File: dispatch.c

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;
}

Project: xserver
File: dispatch.c

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;
}