700 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			700 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright © 2013 Keith Packard
 | 
						|
 *
 | 
						|
 * 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, and
 | 
						|
 * that the name of the copyright holders not be used in advertising or
 | 
						|
 * publicity pertaining to distribution of the software without specific,
 | 
						|
 * written prior permission.  The copyright holders make no representations
 | 
						|
 * about the suitability of this software for any purpose.  It is provided "as
 | 
						|
 * is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL THE COPYRIGHT HOLDERS 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.
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef HAVE_XORG_CONFIG_H
 | 
						|
#include <xorg-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include "dri3_priv.h"
 | 
						|
#include <syncsrv.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <xace.h>
 | 
						|
#include "../Xext/syncsdk.h"
 | 
						|
#include <protocol-versions.h>
 | 
						|
#include <drm_fourcc.h>
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_query_version(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3QueryVersionReq);
 | 
						|
    xDRI3QueryVersionReply rep = {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0,
 | 
						|
        .majorVersion = SERVER_DRI3_MAJOR_VERSION,
 | 
						|
        .minorVersion = SERVER_DRI3_MINOR_VERSION
 | 
						|
    };
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
 | 
						|
    /* From DRI3 proto:
 | 
						|
     *
 | 
						|
     * The client sends the highest supported version to the server
 | 
						|
     * and the server sends the highest version it supports, but no
 | 
						|
     * higher than the requested version.
 | 
						|
     */
 | 
						|
 | 
						|
    if (rep.majorVersion > stuff->majorVersion ||
 | 
						|
        rep.minorVersion > stuff->minorVersion) {
 | 
						|
        rep.majorVersion = stuff->majorVersion;
 | 
						|
        rep.minorVersion = stuff->minorVersion;
 | 
						|
    }
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
        swaps(&rep.sequenceNumber);
 | 
						|
        swapl(&rep.length);
 | 
						|
        swapl(&rep.majorVersion);
 | 
						|
        swapl(&rep.minorVersion);
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof(rep), &rep);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
dri3_send_open_reply(ClientPtr client, int fd)
 | 
						|
{
 | 
						|
    xDRI3OpenReply rep = {
 | 
						|
        .type = X_Reply,
 | 
						|
        .nfd = 1,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0,
 | 
						|
    };
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
        swaps(&rep.sequenceNumber);
 | 
						|
        swapl(&rep.length);
 | 
						|
    }
 | 
						|
 | 
						|
    if (WriteFdToClient(client, fd, TRUE) < 0) {
 | 
						|
        close(fd);
 | 
						|
        return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof (rep), &rep);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_open(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3OpenReq);
 | 
						|
    RRProviderPtr provider;
 | 
						|
    DrawablePtr drawable;
 | 
						|
    ScreenPtr screen;
 | 
						|
    int fd;
 | 
						|
    int status;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3OpenReq);
 | 
						|
 | 
						|
    status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixReadAccess);
 | 
						|
    if (status != Success)
 | 
						|
        return status;
 | 
						|
 | 
						|
    if (stuff->provider == None)
 | 
						|
        provider = NULL;
 | 
						|
    else if (!RRProviderType) {
 | 
						|
        return BadMatch;
 | 
						|
    } else {
 | 
						|
        VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
 | 
						|
        if (drawable->pScreen != provider->pScreen)
 | 
						|
            return BadMatch;
 | 
						|
    }
 | 
						|
    screen = drawable->pScreen;
 | 
						|
 | 
						|
    status = dri3_open(client, screen, provider, &fd);
 | 
						|
    if (status != Success)
 | 
						|
        return status;
 | 
						|
 | 
						|
    if (client->ignoreCount == 0)
 | 
						|
        return dri3_send_open_reply(client, fd);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_pixmap_from_buffer(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3PixmapFromBufferReq);
 | 
						|
    int fd;
 | 
						|
    DrawablePtr drawable;
 | 
						|
    PixmapPtr pixmap;
 | 
						|
    CARD32 stride, offset;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    SetReqFds(client, 1);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->pixmap, client);
 | 
						|
    rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
 | 
						|
    if (rc != Success) {
 | 
						|
        client->errorValue = stuff->drawable;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!stuff->width || !stuff->height) {
 | 
						|
        client->errorValue = 0;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (stuff->width > 32767 || stuff->height > 32767)
 | 
						|
        return BadAlloc;
 | 
						|
 | 
						|
    if (stuff->depth != 1) {
 | 
						|
        DepthPtr depth = drawable->pScreen->allowedDepths;
 | 
						|
        int i;
 | 
						|
        for (i = 0; i < drawable->pScreen->numDepths; i++, depth++)
 | 
						|
            if (depth->depth == stuff->depth)
 | 
						|
                break;
 | 
						|
        if (i == drawable->pScreen->numDepths) {
 | 
						|
            client->errorValue = stuff->depth;
 | 
						|
            return BadValue;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    fd = ReadFdFromClient(client);
 | 
						|
    if (fd < 0)
 | 
						|
        return BadValue;
 | 
						|
 | 
						|
    offset = 0;
 | 
						|
    stride = stuff->stride;
 | 
						|
    rc = dri3_pixmap_from_fds(&pixmap,
 | 
						|
                              drawable->pScreen, 1, &fd,
 | 
						|
                              stuff->width, stuff->height,
 | 
						|
                              &stride, &offset,
 | 
						|
                              stuff->depth, stuff->bpp,
 | 
						|
                              DRM_FORMAT_MOD_INVALID);
 | 
						|
    close (fd);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    pixmap->drawable.id = stuff->pixmap;
 | 
						|
 | 
						|
    /* security creation/labeling check */
 | 
						|
    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
 | 
						|
                  pixmap, RT_NONE, NULL, DixCreateAccess);
 | 
						|
 | 
						|
    if (rc != Success) {
 | 
						|
        (*drawable->pScreen->DestroyPixmap) (pixmap);
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
    if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
 | 
						|
        return BadAlloc;
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_buffer_from_pixmap(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3BufferFromPixmapReq);
 | 
						|
    xDRI3BufferFromPixmapReply rep = {
 | 
						|
        .type = X_Reply,
 | 
						|
        .nfd = 1,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0,
 | 
						|
    };
 | 
						|
    int rc;
 | 
						|
    int num_fds;
 | 
						|
    int fds[4];
 | 
						|
    uint32_t strides[4], offsets[4];
 | 
						|
    uint64_t modifier;
 | 
						|
    PixmapPtr pixmap;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
 | 
						|
                                 client, DixWriteAccess);
 | 
						|
    if (rc != Success) {
 | 
						|
        client->errorValue = stuff->pixmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.width = pixmap->drawable.width;
 | 
						|
    rep.height = pixmap->drawable.height;
 | 
						|
    rep.depth = pixmap->drawable.depth;
 | 
						|
    rep.bpp = pixmap->drawable.bitsPerPixel;
 | 
						|
 | 
						|
    num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier);
 | 
						|
    if (num_fds != 1)
 | 
						|
        return BadPixmap;
 | 
						|
 | 
						|
    rep.stride = (CARD16) strides[0];
 | 
						|
    rep.size = rep.stride * rep.height;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
        swaps(&rep.sequenceNumber);
 | 
						|
        swapl(&rep.length);
 | 
						|
        swapl(&rep.size);
 | 
						|
        swaps(&rep.width);
 | 
						|
        swaps(&rep.height);
 | 
						|
        swaps(&rep.stride);
 | 
						|
    }
 | 
						|
    if (WriteFdToClient(client, fds[0], TRUE) < 0) {
 | 
						|
        close(fds[0]);
 | 
						|
        return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(rep), &rep);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_fence_from_fd(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3FenceFromFDReq);
 | 
						|
    DrawablePtr drawable;
 | 
						|
    int fd;
 | 
						|
    int status;
 | 
						|
 | 
						|
    SetReqFds(client, 1);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->fence, client);
 | 
						|
 | 
						|
    status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
 | 
						|
    if (status != Success)
 | 
						|
        return status;
 | 
						|
 | 
						|
    fd = ReadFdFromClient(client);
 | 
						|
    if (fd < 0)
 | 
						|
        return BadValue;
 | 
						|
 | 
						|
    status = SyncCreateFenceFromFD(client, drawable, stuff->fence,
 | 
						|
                                   fd, stuff->initially_triggered);
 | 
						|
 | 
						|
    return status;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_fd_from_fence(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3FDFromFenceReq);
 | 
						|
    xDRI3FDFromFenceReply rep = {
 | 
						|
        .type = X_Reply,
 | 
						|
        .nfd = 1,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0,
 | 
						|
    };
 | 
						|
    DrawablePtr drawable;
 | 
						|
    int fd;
 | 
						|
    int status;
 | 
						|
    SyncFence *fence;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
 | 
						|
 | 
						|
    status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
 | 
						|
    if (status != Success)
 | 
						|
        return status;
 | 
						|
    status = SyncVerifyFence(&fence, stuff->fence, client, DixWriteAccess);
 | 
						|
    if (status != Success)
 | 
						|
        return status;
 | 
						|
 | 
						|
    fd = SyncFDFromFence(client, drawable, fence);
 | 
						|
    if (fd < 0)
 | 
						|
        return BadMatch;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
        swaps(&rep.sequenceNumber);
 | 
						|
        swapl(&rep.length);
 | 
						|
    }
 | 
						|
    if (WriteFdToClient(client, fd, FALSE) < 0)
 | 
						|
        return BadAlloc;
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(rep), &rep);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_get_supported_modifiers(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3GetSupportedModifiersReq);
 | 
						|
    xDRI3GetSupportedModifiersReply rep = {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
    };
 | 
						|
    WindowPtr window;
 | 
						|
    ScreenPtr pScreen;
 | 
						|
    CARD64 *window_modifiers = NULL;
 | 
						|
    CARD64 *screen_modifiers = NULL;
 | 
						|
    CARD32 nwindowmodifiers = 0;
 | 
						|
    CARD32 nscreenmodifiers = 0;
 | 
						|
    int status;
 | 
						|
    int i;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
 | 
						|
 | 
						|
    status = dixLookupWindow(&window, stuff->window, client, DixReadAccess);
 | 
						|
    if (status != Success)
 | 
						|
        return status;
 | 
						|
    pScreen = window->drawable.pScreen;
 | 
						|
 | 
						|
    dri3_get_supported_modifiers(pScreen, &window->drawable,
 | 
						|
				 stuff->depth, stuff->bpp,
 | 
						|
                                 &nwindowmodifiers, &window_modifiers,
 | 
						|
                                 &nscreenmodifiers, &screen_modifiers);
 | 
						|
 | 
						|
    rep.numWindowModifiers = nwindowmodifiers;
 | 
						|
    rep.numScreenModifiers = nscreenmodifiers;
 | 
						|
    rep.length = bytes_to_int32(rep.numWindowModifiers * sizeof(CARD64)) +
 | 
						|
                 bytes_to_int32(rep.numScreenModifiers * sizeof(CARD64));
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
        swaps(&rep.sequenceNumber);
 | 
						|
        swapl(&rep.length);
 | 
						|
        swapl(&rep.numWindowModifiers);
 | 
						|
        swapl(&rep.numScreenModifiers);
 | 
						|
        for (i = 0; i < nwindowmodifiers; i++)
 | 
						|
            swapll(&window_modifiers[i]);
 | 
						|
        for (i = 0; i < nscreenmodifiers; i++)
 | 
						|
            swapll(&screen_modifiers[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(rep), &rep);
 | 
						|
    WriteToClient(client, nwindowmodifiers * sizeof(CARD64), window_modifiers);
 | 
						|
    WriteToClient(client, nscreenmodifiers * sizeof(CARD64), screen_modifiers);
 | 
						|
 | 
						|
    free(window_modifiers);
 | 
						|
    free(screen_modifiers);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_pixmap_from_buffers(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3PixmapFromBuffersReq);
 | 
						|
    int fds[4];
 | 
						|
    CARD32 strides[4], offsets[4];
 | 
						|
    ScreenPtr screen;
 | 
						|
    WindowPtr window;
 | 
						|
    PixmapPtr pixmap;
 | 
						|
    int rc;
 | 
						|
    int i;
 | 
						|
 | 
						|
    SetReqFds(client, stuff->num_buffers);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->pixmap, client);
 | 
						|
    rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success) {
 | 
						|
        client->errorValue = stuff->window;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
    screen = window->drawable.pScreen;
 | 
						|
 | 
						|
    if (!stuff->width || !stuff->height || !stuff->bpp || !stuff->depth) {
 | 
						|
        client->errorValue = 0;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (stuff->width > 32767 || stuff->height > 32767)
 | 
						|
        return BadAlloc;
 | 
						|
 | 
						|
    if (stuff->depth != 1) {
 | 
						|
        DepthPtr depth = screen->allowedDepths;
 | 
						|
        int j;
 | 
						|
        for (j = 0; j < screen->numDepths; j++, depth++)
 | 
						|
            if (depth->depth == stuff->depth)
 | 
						|
                break;
 | 
						|
        if (j == screen->numDepths) {
 | 
						|
            client->errorValue = stuff->depth;
 | 
						|
            return BadValue;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!stuff->num_buffers || stuff->num_buffers > 4) {
 | 
						|
        client->errorValue = stuff->num_buffers;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 0; i < stuff->num_buffers; i++) {
 | 
						|
        fds[i] = ReadFdFromClient(client);
 | 
						|
        if (fds[i] < 0) {
 | 
						|
            while (--i >= 0)
 | 
						|
                close(fds[i]);
 | 
						|
            return BadValue;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    strides[0] = stuff->stride0;
 | 
						|
    strides[1] = stuff->stride1;
 | 
						|
    strides[2] = stuff->stride2;
 | 
						|
    strides[3] = stuff->stride3;
 | 
						|
    offsets[0] = stuff->offset0;
 | 
						|
    offsets[1] = stuff->offset1;
 | 
						|
    offsets[2] = stuff->offset2;
 | 
						|
    offsets[3] = stuff->offset3;
 | 
						|
 | 
						|
    rc = dri3_pixmap_from_fds(&pixmap, screen,
 | 
						|
                              stuff->num_buffers, fds,
 | 
						|
                              stuff->width, stuff->height,
 | 
						|
                              strides, offsets,
 | 
						|
                              stuff->depth, stuff->bpp,
 | 
						|
                              stuff->modifier);
 | 
						|
 | 
						|
    for (i = 0; i < stuff->num_buffers; i++)
 | 
						|
        close (fds[i]);
 | 
						|
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    pixmap->drawable.id = stuff->pixmap;
 | 
						|
 | 
						|
    /* security creation/labeling check */
 | 
						|
    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
 | 
						|
                  pixmap, RT_NONE, NULL, DixCreateAccess);
 | 
						|
 | 
						|
    if (rc != Success) {
 | 
						|
        (*screen->DestroyPixmap) (pixmap);
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
    if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
 | 
						|
        return BadAlloc;
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proc_dri3_buffers_from_pixmap(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3BuffersFromPixmapReq);
 | 
						|
    xDRI3BuffersFromPixmapReply rep = {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
    };
 | 
						|
    int rc;
 | 
						|
    int fds[4];
 | 
						|
    int num_fds;
 | 
						|
    uint32_t strides[4], offsets[4];
 | 
						|
    uint64_t modifier;
 | 
						|
    int i;
 | 
						|
    PixmapPtr pixmap;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
 | 
						|
                                 client, DixWriteAccess);
 | 
						|
    if (rc != Success) {
 | 
						|
        client->errorValue = stuff->pixmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
 | 
						|
    num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier);
 | 
						|
    if (num_fds == 0)
 | 
						|
        return BadPixmap;
 | 
						|
 | 
						|
    rep.nfd = num_fds;
 | 
						|
    rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32));
 | 
						|
    rep.width = pixmap->drawable.width;
 | 
						|
    rep.height = pixmap->drawable.height;
 | 
						|
    rep.modifier = modifier;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
        swaps(&rep.sequenceNumber);
 | 
						|
        swapl(&rep.length);
 | 
						|
        swaps(&rep.width);
 | 
						|
        swaps(&rep.height);
 | 
						|
        swapll(&rep.modifier);
 | 
						|
        for (i = 0; i < num_fds; i++) {
 | 
						|
            swapl(&strides[i]);
 | 
						|
            swapl(&offsets[i]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 0; i < num_fds; i++) {
 | 
						|
        if (WriteFdToClient(client, fds[i], TRUE) < 0) {
 | 
						|
            while (i--)
 | 
						|
                close(fds[i]);
 | 
						|
            return BadAlloc;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(rep), &rep);
 | 
						|
    WriteToClient(client, num_fds * sizeof(CARD32), strides);
 | 
						|
    WriteToClient(client, num_fds * sizeof(CARD32), offsets);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
 | 
						|
    proc_dri3_query_version,            /* 0 */
 | 
						|
    proc_dri3_open,                     /* 1 */
 | 
						|
    proc_dri3_pixmap_from_buffer,       /* 2 */
 | 
						|
    proc_dri3_buffer_from_pixmap,       /* 3 */
 | 
						|
    proc_dri3_fence_from_fd,            /* 4 */
 | 
						|
    proc_dri3_fd_from_fence,            /* 5 */
 | 
						|
    proc_dri3_get_supported_modifiers,  /* 6 */
 | 
						|
    proc_dri3_pixmap_from_buffers,      /* 7 */
 | 
						|
    proc_dri3_buffers_from_pixmap,      /* 8 */
 | 
						|
};
 | 
						|
 | 
						|
int
 | 
						|
proc_dri3_dispatch(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
    if (!client->local)
 | 
						|
        return BadMatch;
 | 
						|
    if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data])
 | 
						|
        return BadRequest;
 | 
						|
    return (*proc_dri3_vector[stuff->data]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_query_version(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3QueryVersionReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->majorVersion);
 | 
						|
    swapl(&stuff->minorVersion);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_open(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3OpenReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3OpenReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->drawable);
 | 
						|
    swapl(&stuff->provider);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_pixmap_from_buffer(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3PixmapFromBufferReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->pixmap);
 | 
						|
    swapl(&stuff->drawable);
 | 
						|
    swapl(&stuff->size);
 | 
						|
    swaps(&stuff->width);
 | 
						|
    swaps(&stuff->height);
 | 
						|
    swaps(&stuff->stride);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_buffer_from_pixmap(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3BufferFromPixmapReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->pixmap);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_fence_from_fd(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3FenceFromFDReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->drawable);
 | 
						|
    swapl(&stuff->fence);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_fd_from_fence(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3FDFromFenceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->drawable);
 | 
						|
    swapl(&stuff->fence);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_get_supported_modifiers(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3GetSupportedModifiersReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->window);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_pixmap_from_buffers(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3PixmapFromBuffersReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->pixmap);
 | 
						|
    swapl(&stuff->window);
 | 
						|
    swaps(&stuff->width);
 | 
						|
    swaps(&stuff->height);
 | 
						|
    swapl(&stuff->stride0);
 | 
						|
    swapl(&stuff->offset0);
 | 
						|
    swapl(&stuff->stride1);
 | 
						|
    swapl(&stuff->offset1);
 | 
						|
    swapl(&stuff->stride2);
 | 
						|
    swapl(&stuff->offset2);
 | 
						|
    swapl(&stuff->stride3);
 | 
						|
    swapl(&stuff->offset3);
 | 
						|
    swapll(&stuff->modifier);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
static int _X_COLD
 | 
						|
sproc_dri3_buffers_from_pixmap(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xDRI3BuffersFromPixmapReq);
 | 
						|
    REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
 | 
						|
 | 
						|
    swaps(&stuff->length);
 | 
						|
    swapl(&stuff->pixmap);
 | 
						|
    return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
 | 
						|
}
 | 
						|
 | 
						|
int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
 | 
						|
    sproc_dri3_query_version,           /* 0 */
 | 
						|
    sproc_dri3_open,                    /* 1 */
 | 
						|
    sproc_dri3_pixmap_from_buffer,      /* 2 */
 | 
						|
    sproc_dri3_buffer_from_pixmap,      /* 3 */
 | 
						|
    sproc_dri3_fence_from_fd,           /* 4 */
 | 
						|
    sproc_dri3_fd_from_fence,           /* 5 */
 | 
						|
    sproc_dri3_get_supported_modifiers, /* 6 */
 | 
						|
    sproc_dri3_pixmap_from_buffers,     /* 7 */
 | 
						|
    sproc_dri3_buffers_from_pixmap,     /* 8 */
 | 
						|
};
 | 
						|
 | 
						|
int _X_COLD
 | 
						|
sproc_dri3_dispatch(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
    if (!client->local)
 | 
						|
        return BadMatch;
 | 
						|
    if (stuff->data >= DRI3NumberRequests || !sproc_dri3_vector[stuff->data])
 | 
						|
        return BadRequest;
 | 
						|
    return (*sproc_dri3_vector[stuff->data]) (client);
 | 
						|
}
 |