xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

dri3_request.c (20168B)


      1 /*
      2  * Copyright © 2013 Keith Packard
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that copyright
      7  * notice and this permission notice appear in supporting documentation, and
      8  * that the name of the copyright holders not be used in advertising or
      9  * publicity pertaining to distribution of the software without specific,
     10  * written prior permission.  The copyright holders make no representations
     11  * about the suitability of this software for any purpose.  It is provided "as
     12  * is" without express or implied warranty.
     13  *
     14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     20  * OF THIS SOFTWARE.
     21  */
     22 
     23 #include "dri3_priv.h"
     24 #include <syncsrv.h>
     25 #include <unistd.h>
     26 #include <xace.h>
     27 #include "../Xext/syncsdk.h"
     28 #include <protocol-versions.h>
     29 #include <drm_fourcc.h>
     30 
     31 static Bool
     32 dri3_screen_can_one_point_two(ScreenPtr screen)
     33 {
     34     dri3_screen_priv_ptr dri3 = dri3_screen_priv(screen);
     35 
     36     if (dri3 && dri3->info && dri3->info->version >= 2 &&
     37         dri3->info->pixmap_from_fds && dri3->info->fds_from_pixmap &&
     38         dri3->info->get_formats && dri3->info->get_modifiers &&
     39         dri3->info->get_drawable_modifiers)
     40         return TRUE;
     41 
     42     return FALSE;
     43 }
     44 
     45 static int
     46 proc_dri3_query_version(ClientPtr client)
     47 {
     48     REQUEST(xDRI3QueryVersionReq);
     49     xDRI3QueryVersionReply rep = {
     50         .type = X_Reply,
     51         .sequenceNumber = client->sequence,
     52         .length = 0,
     53         .majorVersion = SERVER_DRI3_MAJOR_VERSION,
     54         .minorVersion = SERVER_DRI3_MINOR_VERSION
     55     };
     56 
     57     REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
     58 
     59     for (int i = 0; i < screenInfo.numScreens; i++) {
     60         if (!dri3_screen_can_one_point_two(screenInfo.screens[i])) {
     61             rep.minorVersion = 0;
     62             break;
     63         }
     64     }
     65 
     66     for (int i = 0; i < screenInfo.numGPUScreens; i++) {
     67         if (!dri3_screen_can_one_point_two(screenInfo.gpuscreens[i])) {
     68             rep.minorVersion = 0;
     69             break;
     70         }
     71     }
     72 
     73     /* From DRI3 proto:
     74      *
     75      * The client sends the highest supported version to the server
     76      * and the server sends the highest version it supports, but no
     77      * higher than the requested version.
     78      */
     79 
     80     if (rep.majorVersion > stuff->majorVersion ||
     81         (rep.majorVersion == stuff->majorVersion &&
     82          rep.minorVersion > stuff->minorVersion)) {
     83         rep.majorVersion = stuff->majorVersion;
     84         rep.minorVersion = stuff->minorVersion;
     85     }
     86 
     87     if (client->swapped) {
     88         swaps(&rep.sequenceNumber);
     89         swapl(&rep.length);
     90         swapl(&rep.majorVersion);
     91         swapl(&rep.minorVersion);
     92     }
     93     WriteToClient(client, sizeof(rep), &rep);
     94     return Success;
     95 }
     96 
     97 int
     98 dri3_send_open_reply(ClientPtr client, int fd)
     99 {
    100     xDRI3OpenReply rep = {
    101         .type = X_Reply,
    102         .nfd = 1,
    103         .sequenceNumber = client->sequence,
    104         .length = 0,
    105     };
    106 
    107     if (client->swapped) {
    108         swaps(&rep.sequenceNumber);
    109         swapl(&rep.length);
    110     }
    111 
    112     if (WriteFdToClient(client, fd, TRUE) < 0) {
    113         close(fd);
    114         return BadAlloc;
    115     }
    116 
    117     WriteToClient(client, sizeof (rep), &rep);
    118 
    119     return Success;
    120 }
    121 
    122 static int
    123 proc_dri3_open(ClientPtr client)
    124 {
    125     REQUEST(xDRI3OpenReq);
    126     RRProviderPtr provider;
    127     DrawablePtr drawable;
    128     ScreenPtr screen;
    129     int fd;
    130     int status;
    131 
    132     REQUEST_SIZE_MATCH(xDRI3OpenReq);
    133 
    134     status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
    135     if (status != Success)
    136         return status;
    137 
    138     if (stuff->provider == None)
    139         provider = NULL;
    140     else if (!RRProviderType) {
    141         return BadMatch;
    142     } else {
    143         VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
    144         if (drawable->pScreen != provider->pScreen)
    145             return BadMatch;
    146     }
    147     screen = drawable->pScreen;
    148 
    149     status = dri3_open(client, screen, provider, &fd);
    150     if (status != Success)
    151         return status;
    152 
    153     if (client->ignoreCount == 0)
    154         return dri3_send_open_reply(client, fd);
    155 
    156     return Success;
    157 }
    158 
    159 static int
    160 proc_dri3_pixmap_from_buffer(ClientPtr client)
    161 {
    162     REQUEST(xDRI3PixmapFromBufferReq);
    163     int fd;
    164     DrawablePtr drawable;
    165     PixmapPtr pixmap;
    166     CARD32 stride, offset;
    167     int rc;
    168 
    169     SetReqFds(client, 1);
    170     REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
    171     LEGAL_NEW_RESOURCE(stuff->pixmap, client);
    172     rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
    173     if (rc != Success) {
    174         client->errorValue = stuff->drawable;
    175         return rc;
    176     }
    177 
    178     if (!stuff->width || !stuff->height) {
    179         client->errorValue = 0;
    180         return BadValue;
    181     }
    182 
    183     if (stuff->width > 32767 || stuff->height > 32767)
    184         return BadAlloc;
    185 
    186     if (stuff->depth != 1) {
    187         DepthPtr depth = drawable->pScreen->allowedDepths;
    188         int i;
    189         for (i = 0; i < drawable->pScreen->numDepths; i++, depth++)
    190             if (depth->depth == stuff->depth)
    191                 break;
    192         if (i == drawable->pScreen->numDepths) {
    193             client->errorValue = stuff->depth;
    194             return BadValue;
    195         }
    196     }
    197 
    198     fd = ReadFdFromClient(client);
    199     if (fd < 0)
    200         return BadValue;
    201 
    202     offset = 0;
    203     stride = stuff->stride;
    204     rc = dri3_pixmap_from_fds(&pixmap,
    205                               drawable->pScreen, 1, &fd,
    206                               stuff->width, stuff->height,
    207                               &stride, &offset,
    208                               stuff->depth, stuff->bpp,
    209                               DRM_FORMAT_MOD_INVALID);
    210     close (fd);
    211     if (rc != Success)
    212         return rc;
    213 
    214     pixmap->drawable.id = stuff->pixmap;
    215 
    216     /* security creation/labeling check */
    217     rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
    218                   pixmap, RT_NONE, NULL, DixCreateAccess);
    219 
    220     if (rc != Success) {
    221         (*drawable->pScreen->DestroyPixmap) (pixmap);
    222         return rc;
    223     }
    224     if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
    225         return BadAlloc;
    226 
    227     return Success;
    228 }
    229 
    230 static int
    231 proc_dri3_buffer_from_pixmap(ClientPtr client)
    232 {
    233     REQUEST(xDRI3BufferFromPixmapReq);
    234     xDRI3BufferFromPixmapReply rep = {
    235         .type = X_Reply,
    236         .nfd = 1,
    237         .sequenceNumber = client->sequence,
    238         .length = 0,
    239     };
    240     int rc;
    241     int fd;
    242     PixmapPtr pixmap;
    243 
    244     REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
    245     rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
    246                                  client, DixWriteAccess);
    247     if (rc != Success) {
    248         client->errorValue = stuff->pixmap;
    249         return rc;
    250     }
    251 
    252     rep.width = pixmap->drawable.width;
    253     rep.height = pixmap->drawable.height;
    254     rep.depth = pixmap->drawable.depth;
    255     rep.bpp = pixmap->drawable.bitsPerPixel;
    256 
    257     fd = dri3_fd_from_pixmap(pixmap, &rep.stride, &rep.size);
    258     if (fd < 0)
    259         return BadPixmap;
    260 
    261     if (client->swapped) {
    262         swaps(&rep.sequenceNumber);
    263         swapl(&rep.length);
    264         swapl(&rep.size);
    265         swaps(&rep.width);
    266         swaps(&rep.height);
    267         swaps(&rep.stride);
    268     }
    269     if (WriteFdToClient(client, fd, TRUE) < 0) {
    270         close(fd);
    271         return BadAlloc;
    272     }
    273 
    274     WriteToClient(client, sizeof(rep), &rep);
    275 
    276     return Success;
    277 }
    278 
    279 static int
    280 proc_dri3_fence_from_fd(ClientPtr client)
    281 {
    282     REQUEST(xDRI3FenceFromFDReq);
    283     DrawablePtr drawable;
    284     int fd;
    285     int status;
    286 
    287     SetReqFds(client, 1);
    288     REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
    289     LEGAL_NEW_RESOURCE(stuff->fence, client);
    290 
    291     status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
    292     if (status != Success)
    293         return status;
    294 
    295     fd = ReadFdFromClient(client);
    296     if (fd < 0)
    297         return BadValue;
    298 
    299     status = SyncCreateFenceFromFD(client, drawable, stuff->fence,
    300                                    fd, stuff->initially_triggered);
    301 
    302     return status;
    303 }
    304 
    305 static int
    306 proc_dri3_fd_from_fence(ClientPtr client)
    307 {
    308     REQUEST(xDRI3FDFromFenceReq);
    309     xDRI3FDFromFenceReply rep = {
    310         .type = X_Reply,
    311         .nfd = 1,
    312         .sequenceNumber = client->sequence,
    313         .length = 0,
    314     };
    315     DrawablePtr drawable;
    316     int fd;
    317     int status;
    318     SyncFence *fence;
    319 
    320     REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
    321 
    322     status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
    323     if (status != Success)
    324         return status;
    325     status = SyncVerifyFence(&fence, stuff->fence, client, DixWriteAccess);
    326     if (status != Success)
    327         return status;
    328 
    329     fd = SyncFDFromFence(client, drawable, fence);
    330     if (fd < 0)
    331         return BadMatch;
    332 
    333     if (client->swapped) {
    334         swaps(&rep.sequenceNumber);
    335         swapl(&rep.length);
    336     }
    337     if (WriteFdToClient(client, fd, FALSE) < 0)
    338         return BadAlloc;
    339 
    340     WriteToClient(client, sizeof(rep), &rep);
    341 
    342     return Success;
    343 }
    344 
    345 static int
    346 proc_dri3_get_supported_modifiers(ClientPtr client)
    347 {
    348     REQUEST(xDRI3GetSupportedModifiersReq);
    349     xDRI3GetSupportedModifiersReply rep = {
    350         .type = X_Reply,
    351         .sequenceNumber = client->sequence,
    352     };
    353     WindowPtr window;
    354     ScreenPtr pScreen;
    355     CARD64 *window_modifiers = NULL;
    356     CARD64 *screen_modifiers = NULL;
    357     CARD32 nwindowmodifiers = 0;
    358     CARD32 nscreenmodifiers = 0;
    359     int status;
    360     int i;
    361 
    362     REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
    363 
    364     status = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
    365     if (status != Success)
    366         return status;
    367     pScreen = window->drawable.pScreen;
    368 
    369     dri3_get_supported_modifiers(pScreen, &window->drawable,
    370 				 stuff->depth, stuff->bpp,
    371                                  &nwindowmodifiers, &window_modifiers,
    372                                  &nscreenmodifiers, &screen_modifiers);
    373 
    374     rep.numWindowModifiers = nwindowmodifiers;
    375     rep.numScreenModifiers = nscreenmodifiers;
    376     rep.length = bytes_to_int32(rep.numWindowModifiers * sizeof(CARD64)) +
    377                  bytes_to_int32(rep.numScreenModifiers * sizeof(CARD64));
    378 
    379     if (client->swapped) {
    380         swaps(&rep.sequenceNumber);
    381         swapl(&rep.length);
    382         swapl(&rep.numWindowModifiers);
    383         swapl(&rep.numScreenModifiers);
    384         for (i = 0; i < nwindowmodifiers; i++)
    385             swapll(&window_modifiers[i]);
    386         for (i = 0; i < nscreenmodifiers; i++)
    387             swapll(&screen_modifiers[i]);
    388     }
    389 
    390     WriteToClient(client, sizeof(rep), &rep);
    391     WriteToClient(client, nwindowmodifiers * sizeof(CARD64), window_modifiers);
    392     WriteToClient(client, nscreenmodifiers * sizeof(CARD64), screen_modifiers);
    393 
    394     free(window_modifiers);
    395     free(screen_modifiers);
    396 
    397     return Success;
    398 }
    399 
    400 static int
    401 proc_dri3_pixmap_from_buffers(ClientPtr client)
    402 {
    403     REQUEST(xDRI3PixmapFromBuffersReq);
    404     int fds[4];
    405     CARD32 strides[4], offsets[4];
    406     ScreenPtr screen;
    407     WindowPtr window;
    408     PixmapPtr pixmap;
    409     int rc;
    410     int i;
    411 
    412     SetReqFds(client, stuff->num_buffers);
    413     REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
    414     LEGAL_NEW_RESOURCE(stuff->pixmap, client);
    415     rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
    416     if (rc != Success) {
    417         client->errorValue = stuff->window;
    418         return rc;
    419     }
    420     screen = window->drawable.pScreen;
    421 
    422     if (!stuff->width || !stuff->height || !stuff->bpp || !stuff->depth) {
    423         client->errorValue = 0;
    424         return BadValue;
    425     }
    426 
    427     if (stuff->width > 32767 || stuff->height > 32767)
    428         return BadAlloc;
    429 
    430     if (stuff->depth != 1) {
    431         DepthPtr depth = screen->allowedDepths;
    432         int j;
    433         for (j = 0; j < screen->numDepths; j++, depth++)
    434             if (depth->depth == stuff->depth)
    435                 break;
    436         if (j == screen->numDepths) {
    437             client->errorValue = stuff->depth;
    438             return BadValue;
    439         }
    440     }
    441 
    442     if (!stuff->num_buffers || stuff->num_buffers > 4) {
    443         client->errorValue = stuff->num_buffers;
    444         return BadValue;
    445     }
    446 
    447     for (i = 0; i < stuff->num_buffers; i++) {
    448         fds[i] = ReadFdFromClient(client);
    449         if (fds[i] < 0) {
    450             while (--i >= 0)
    451                 close(fds[i]);
    452             return BadValue;
    453         }
    454     }
    455 
    456     strides[0] = stuff->stride0;
    457     strides[1] = stuff->stride1;
    458     strides[2] = stuff->stride2;
    459     strides[3] = stuff->stride3;
    460     offsets[0] = stuff->offset0;
    461     offsets[1] = stuff->offset1;
    462     offsets[2] = stuff->offset2;
    463     offsets[3] = stuff->offset3;
    464 
    465     rc = dri3_pixmap_from_fds(&pixmap, screen,
    466                               stuff->num_buffers, fds,
    467                               stuff->width, stuff->height,
    468                               strides, offsets,
    469                               stuff->depth, stuff->bpp,
    470                               stuff->modifier);
    471 
    472     for (i = 0; i < stuff->num_buffers; i++)
    473         close (fds[i]);
    474 
    475     if (rc != Success)
    476         return rc;
    477 
    478     pixmap->drawable.id = stuff->pixmap;
    479 
    480     /* security creation/labeling check */
    481     rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
    482                   pixmap, RT_NONE, NULL, DixCreateAccess);
    483 
    484     if (rc != Success) {
    485         (*screen->DestroyPixmap) (pixmap);
    486         return rc;
    487     }
    488     if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
    489         return BadAlloc;
    490 
    491     return Success;
    492 }
    493 
    494 static int
    495 proc_dri3_buffers_from_pixmap(ClientPtr client)
    496 {
    497     REQUEST(xDRI3BuffersFromPixmapReq);
    498     xDRI3BuffersFromPixmapReply rep = {
    499         .type = X_Reply,
    500         .sequenceNumber = client->sequence,
    501     };
    502     int rc;
    503     int fds[4];
    504     int num_fds;
    505     uint32_t strides[4], offsets[4];
    506     uint64_t modifier;
    507     int i;
    508     PixmapPtr pixmap;
    509 
    510     REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
    511     rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
    512                                  client, DixWriteAccess);
    513     if (rc != Success) {
    514         client->errorValue = stuff->pixmap;
    515         return rc;
    516     }
    517 
    518     num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier);
    519     if (num_fds == 0)
    520         return BadPixmap;
    521 
    522     rep.nfd = num_fds;
    523     rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32));
    524     rep.width = pixmap->drawable.width;
    525     rep.height = pixmap->drawable.height;
    526     rep.depth = pixmap->drawable.depth;
    527     rep.bpp = pixmap->drawable.bitsPerPixel;
    528     rep.modifier = modifier;
    529 
    530     if (client->swapped) {
    531         swaps(&rep.sequenceNumber);
    532         swapl(&rep.length);
    533         swaps(&rep.width);
    534         swaps(&rep.height);
    535         swapll(&rep.modifier);
    536         for (i = 0; i < num_fds; i++) {
    537             swapl(&strides[i]);
    538             swapl(&offsets[i]);
    539         }
    540     }
    541 
    542     for (i = 0; i < num_fds; i++) {
    543         if (WriteFdToClient(client, fds[i], TRUE) < 0) {
    544             while (i--)
    545                 close(fds[i]);
    546             return BadAlloc;
    547         }
    548     }
    549 
    550     WriteToClient(client, sizeof(rep), &rep);
    551     WriteToClient(client, num_fds * sizeof(CARD32), strides);
    552     WriteToClient(client, num_fds * sizeof(CARD32), offsets);
    553 
    554     return Success;
    555 }
    556 
    557 int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
    558     proc_dri3_query_version,            /* 0 */
    559     proc_dri3_open,                     /* 1 */
    560     proc_dri3_pixmap_from_buffer,       /* 2 */
    561     proc_dri3_buffer_from_pixmap,       /* 3 */
    562     proc_dri3_fence_from_fd,            /* 4 */
    563     proc_dri3_fd_from_fence,            /* 5 */
    564     proc_dri3_get_supported_modifiers,  /* 6 */
    565     proc_dri3_pixmap_from_buffers,      /* 7 */
    566     proc_dri3_buffers_from_pixmap,      /* 8 */
    567 };
    568 
    569 int
    570 proc_dri3_dispatch(ClientPtr client)
    571 {
    572     REQUEST(xReq);
    573     if (!client->local)
    574         return BadMatch;
    575     if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data])
    576         return BadRequest;
    577     return (*proc_dri3_vector[stuff->data]) (client);
    578 }
    579 
    580 static int _X_COLD
    581 sproc_dri3_query_version(ClientPtr client)
    582 {
    583     REQUEST(xDRI3QueryVersionReq);
    584     REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
    585 
    586     swaps(&stuff->length);
    587     swapl(&stuff->majorVersion);
    588     swapl(&stuff->minorVersion);
    589     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    590 }
    591 
    592 static int _X_COLD
    593 sproc_dri3_open(ClientPtr client)
    594 {
    595     REQUEST(xDRI3OpenReq);
    596     REQUEST_SIZE_MATCH(xDRI3OpenReq);
    597 
    598     swaps(&stuff->length);
    599     swapl(&stuff->drawable);
    600     swapl(&stuff->provider);
    601     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    602 }
    603 
    604 static int _X_COLD
    605 sproc_dri3_pixmap_from_buffer(ClientPtr client)
    606 {
    607     REQUEST(xDRI3PixmapFromBufferReq);
    608     REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
    609 
    610     swaps(&stuff->length);
    611     swapl(&stuff->pixmap);
    612     swapl(&stuff->drawable);
    613     swapl(&stuff->size);
    614     swaps(&stuff->width);
    615     swaps(&stuff->height);
    616     swaps(&stuff->stride);
    617     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    618 }
    619 
    620 static int _X_COLD
    621 sproc_dri3_buffer_from_pixmap(ClientPtr client)
    622 {
    623     REQUEST(xDRI3BufferFromPixmapReq);
    624     REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
    625 
    626     swaps(&stuff->length);
    627     swapl(&stuff->pixmap);
    628     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    629 }
    630 
    631 static int _X_COLD
    632 sproc_dri3_fence_from_fd(ClientPtr client)
    633 {
    634     REQUEST(xDRI3FenceFromFDReq);
    635     REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
    636 
    637     swaps(&stuff->length);
    638     swapl(&stuff->drawable);
    639     swapl(&stuff->fence);
    640     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    641 }
    642 
    643 static int _X_COLD
    644 sproc_dri3_fd_from_fence(ClientPtr client)
    645 {
    646     REQUEST(xDRI3FDFromFenceReq);
    647     REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
    648 
    649     swaps(&stuff->length);
    650     swapl(&stuff->drawable);
    651     swapl(&stuff->fence);
    652     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    653 }
    654 
    655 static int _X_COLD
    656 sproc_dri3_get_supported_modifiers(ClientPtr client)
    657 {
    658     REQUEST(xDRI3GetSupportedModifiersReq);
    659     REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
    660 
    661     swaps(&stuff->length);
    662     swapl(&stuff->window);
    663     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    664 }
    665 
    666 static int _X_COLD
    667 sproc_dri3_pixmap_from_buffers(ClientPtr client)
    668 {
    669     REQUEST(xDRI3PixmapFromBuffersReq);
    670     REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
    671 
    672     swaps(&stuff->length);
    673     swapl(&stuff->pixmap);
    674     swapl(&stuff->window);
    675     swaps(&stuff->width);
    676     swaps(&stuff->height);
    677     swapl(&stuff->stride0);
    678     swapl(&stuff->offset0);
    679     swapl(&stuff->stride1);
    680     swapl(&stuff->offset1);
    681     swapl(&stuff->stride2);
    682     swapl(&stuff->offset2);
    683     swapl(&stuff->stride3);
    684     swapl(&stuff->offset3);
    685     swapll(&stuff->modifier);
    686     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    687 }
    688 
    689 static int _X_COLD
    690 sproc_dri3_buffers_from_pixmap(ClientPtr client)
    691 {
    692     REQUEST(xDRI3BuffersFromPixmapReq);
    693     REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
    694 
    695     swaps(&stuff->length);
    696     swapl(&stuff->pixmap);
    697     return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
    698 }
    699 
    700 int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
    701     sproc_dri3_query_version,           /* 0 */
    702     sproc_dri3_open,                    /* 1 */
    703     sproc_dri3_pixmap_from_buffer,      /* 2 */
    704     sproc_dri3_buffer_from_pixmap,      /* 3 */
    705     sproc_dri3_fence_from_fd,           /* 4 */
    706     sproc_dri3_fd_from_fence,           /* 5 */
    707     sproc_dri3_get_supported_modifiers, /* 6 */
    708     sproc_dri3_pixmap_from_buffers,     /* 7 */
    709     sproc_dri3_buffers_from_pixmap,     /* 8 */
    710 };
    711 
    712 int _X_COLD
    713 sproc_dri3_dispatch(ClientPtr client)
    714 {
    715     REQUEST(xReq);
    716     if (!client->local)
    717         return BadMatch;
    718     if (stuff->data >= DRI3NumberRequests || !sproc_dri3_vector[stuff->data])
    719         return BadRequest;
    720     return (*sproc_dri3_vector[stuff->data]) (client);
    721 }