xserver

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

xvmc.c (22896B)


      1 
      2 #ifdef HAVE_DIX_CONFIG_H
      3 #include <dix-config.h>
      4 #endif
      5 
      6 #include <string.h>
      7 
      8 #include <X11/X.h>
      9 #include <X11/Xproto.h>
     10 #include "misc.h"
     11 #include "os.h"
     12 #include "dixstruct.h"
     13 #include "resource.h"
     14 #include "scrnintstr.h"
     15 #include "extnsionst.h"
     16 #include "extinit.h"
     17 #include "servermd.h"
     18 #include <X11/Xfuncproto.h>
     19 #include "xvdix.h"
     20 #include <X11/extensions/XvMC.h>
     21 #include <X11/extensions/Xvproto.h>
     22 #include <X11/extensions/XvMCproto.h>
     23 #include "xvmcext.h"
     24 #include "protocol-versions.h"
     25 
     26 #ifdef HAS_XVMCSHM
     27 #include <sys/ipc.h>
     28 #include <sys/types.h>
     29 #include <sys/shm.h>
     30 #endif                          /* HAS_XVMCSHM */
     31 
     32 #define DR_CLIENT_DRIVER_NAME_SIZE 48
     33 #define DR_BUSID_SIZE 48
     34 
     35 static DevPrivateKeyRec XvMCScreenKeyRec;
     36 
     37 #define XvMCScreenKey (&XvMCScreenKeyRec)
     38 static Bool XvMCInUse;
     39 
     40 int XvMCReqCode;
     41 int XvMCEventBase;
     42 
     43 static RESTYPE XvMCRTContext;
     44 static RESTYPE XvMCRTSurface;
     45 static RESTYPE XvMCRTSubpicture;
     46 
     47 int (*XvMCScreenInitProc)(ScreenPtr, int, XvMCAdaptorPtr) = NULL;
     48 
     49 typedef struct {
     50     int num_adaptors;
     51     XvMCAdaptorPtr adaptors;
     52     CloseScreenProcPtr CloseScreen;
     53     char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE];
     54     char busID[DR_BUSID_SIZE];
     55     int major;
     56     int minor;
     57     int patchLevel;
     58 } XvMCScreenRec, *XvMCScreenPtr;
     59 
     60 #define XVMC_GET_PRIVATE(pScreen) \
     61     (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey))
     62 
     63 static int
     64 XvMCDestroyContextRes(void *data, XID id)
     65 {
     66     XvMCContextPtr pContext = (XvMCContextPtr) data;
     67 
     68     pContext->refcnt--;
     69 
     70     if (!pContext->refcnt) {
     71         XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
     72 
     73         (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext) (pContext);
     74         free(pContext);
     75     }
     76 
     77     return Success;
     78 }
     79 
     80 static int
     81 XvMCDestroySurfaceRes(void *data, XID id)
     82 {
     83     XvMCSurfacePtr pSurface = (XvMCSurfacePtr) data;
     84     XvMCContextPtr pContext = pSurface->context;
     85     XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
     86 
     87     (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface) (pSurface);
     88     free(pSurface);
     89 
     90     XvMCDestroyContextRes((void *) pContext, pContext->context_id);
     91 
     92     return Success;
     93 }
     94 
     95 static int
     96 XvMCDestroySubpictureRes(void *data, XID id)
     97 {
     98     XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr) data;
     99     XvMCContextPtr pContext = pSubpict->context;
    100     XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
    101 
    102     (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture) (pSubpict);
    103     free(pSubpict);
    104 
    105     XvMCDestroyContextRes((void *) pContext, pContext->context_id);
    106 
    107     return Success;
    108 }
    109 
    110 static int
    111 ProcXvMCQueryVersion(ClientPtr client)
    112 {
    113     xvmcQueryVersionReply rep = {
    114         .type = X_Reply,
    115         .sequenceNumber = client->sequence,
    116         .length = 0,
    117         .major = SERVER_XVMC_MAJOR_VERSION,
    118         .minor = SERVER_XVMC_MINOR_VERSION
    119     };
    120 
    121     /* REQUEST(xvmcQueryVersionReq); */
    122     REQUEST_SIZE_MATCH(xvmcQueryVersionReq);
    123 
    124     WriteToClient(client, sizeof(xvmcQueryVersionReply), &rep);
    125     return Success;
    126 }
    127 
    128 static int
    129 ProcXvMCListSurfaceTypes(ClientPtr client)
    130 {
    131     XvPortPtr pPort;
    132     int i;
    133     XvMCScreenPtr pScreenPriv;
    134     xvmcListSurfaceTypesReply rep;
    135     xvmcSurfaceInfo info;
    136     XvMCAdaptorPtr adaptor = NULL;
    137     XvMCSurfaceInfoPtr surface;
    138     int num_surfaces;
    139 
    140     REQUEST(xvmcListSurfaceTypesReq);
    141     REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq);
    142 
    143     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    144 
    145     if (XvMCInUse) {            /* any adaptors at all */
    146         ScreenPtr pScreen = pPort->pAdaptor->pScreen;
    147 
    148         if ((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) {        /* any this screen */
    149             for (i = 0; i < pScreenPriv->num_adaptors; i++) {
    150                 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
    151                     adaptor = &(pScreenPriv->adaptors[i]);
    152                     break;
    153                 }
    154             }
    155         }
    156     }
    157 
    158     num_surfaces = (adaptor) ? adaptor->num_surfaces : 0;
    159     rep = (xvmcListSurfaceTypesReply) {
    160         .type = X_Reply,
    161         .sequenceNumber = client->sequence,
    162         .num = num_surfaces,
    163         .length = bytes_to_int32(num_surfaces * sizeof(xvmcSurfaceInfo)),
    164     };
    165 
    166     WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), &rep);
    167 
    168     for (i = 0; i < num_surfaces; i++) {
    169         surface = adaptor->surfaces[i];
    170         info.surface_type_id = surface->surface_type_id;
    171         info.chroma_format = surface->chroma_format;
    172         info.max_width = surface->max_width;
    173         info.max_height = surface->max_height;
    174         info.subpicture_max_width = surface->subpicture_max_width;
    175         info.subpicture_max_height = surface->subpicture_max_height;
    176         info.mc_type = surface->mc_type;
    177         info.flags = surface->flags;
    178         WriteToClient(client, sizeof(xvmcSurfaceInfo), &info);
    179     }
    180 
    181     return Success;
    182 }
    183 
    184 static int
    185 ProcXvMCCreateContext(ClientPtr client)
    186 {
    187     XvPortPtr pPort;
    188     CARD32 *data = NULL;
    189     int dwords = 0;
    190     int i, result, adapt_num = -1;
    191     ScreenPtr pScreen;
    192     XvMCContextPtr pContext;
    193     XvMCScreenPtr pScreenPriv;
    194     XvMCAdaptorPtr adaptor = NULL;
    195     XvMCSurfaceInfoPtr surface = NULL;
    196     xvmcCreateContextReply rep;
    197 
    198     REQUEST(xvmcCreateContextReq);
    199     REQUEST_SIZE_MATCH(xvmcCreateContextReq);
    200 
    201     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    202 
    203     pScreen = pPort->pAdaptor->pScreen;
    204 
    205     if (!XvMCInUse)             /* no XvMC adaptors */
    206         return BadMatch;
    207 
    208     if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))     /* none this screen */
    209         return BadMatch;
    210 
    211     for (i = 0; i < pScreenPriv->num_adaptors; i++) {
    212         if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
    213             adaptor = &(pScreenPriv->adaptors[i]);
    214             adapt_num = i;
    215             break;
    216         }
    217     }
    218 
    219     if (adapt_num < 0)          /* none this port */
    220         return BadMatch;
    221 
    222     for (i = 0; i < adaptor->num_surfaces; i++) {
    223         if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
    224             surface = adaptor->surfaces[i];
    225             break;
    226         }
    227     }
    228 
    229     /* adaptor doesn't support this suface_type_id */
    230     if (!surface)
    231         return BadMatch;
    232 
    233     if ((stuff->width > surface->max_width) ||
    234         (stuff->height > surface->max_height))
    235         return BadValue;
    236 
    237     if (!(pContext = malloc(sizeof(XvMCContextRec)))) {
    238         return BadAlloc;
    239     }
    240 
    241     pContext->pScreen = pScreen;
    242     pContext->adapt_num = adapt_num;
    243     pContext->context_id = stuff->context_id;
    244     pContext->surface_type_id = stuff->surface_type_id;
    245     pContext->width = stuff->width;
    246     pContext->height = stuff->height;
    247     pContext->flags = stuff->flags;
    248     pContext->refcnt = 1;
    249 
    250     result = (*adaptor->CreateContext) (pPort, pContext, &dwords, &data);
    251 
    252     if (result != Success) {
    253         free(pContext);
    254         return result;
    255     }
    256     if (!AddResource(pContext->context_id, XvMCRTContext, pContext)) {
    257         free(data);
    258         return BadAlloc;
    259     }
    260 
    261     rep = (xvmcCreateContextReply) {
    262         .type = X_Reply,
    263         .sequenceNumber = client->sequence,
    264         .length = dwords,
    265         .width_actual = pContext->width,
    266         .height_actual = pContext->height,
    267         .flags_return = pContext->flags
    268     };
    269 
    270     WriteToClient(client, sizeof(xvmcCreateContextReply), &rep);
    271     if (dwords)
    272         WriteToClient(client, dwords << 2, data);
    273 
    274     free(data);
    275 
    276     return Success;
    277 }
    278 
    279 static int
    280 ProcXvMCDestroyContext(ClientPtr client)
    281 {
    282     void *val;
    283     int rc;
    284 
    285     REQUEST(xvmcDestroyContextReq);
    286     REQUEST_SIZE_MATCH(xvmcDestroyContextReq);
    287 
    288     rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext,
    289                                  client, DixDestroyAccess);
    290     if (rc != Success)
    291         return rc;
    292 
    293     FreeResource(stuff->context_id, RT_NONE);
    294 
    295     return Success;
    296 }
    297 
    298 static int
    299 ProcXvMCCreateSurface(ClientPtr client)
    300 {
    301     CARD32 *data = NULL;
    302     int dwords = 0;
    303     int result;
    304     XvMCContextPtr pContext;
    305     XvMCSurfacePtr pSurface;
    306     XvMCScreenPtr pScreenPriv;
    307     xvmcCreateSurfaceReply rep;
    308 
    309     REQUEST(xvmcCreateSurfaceReq);
    310     REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
    311 
    312     result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
    313                                      XvMCRTContext, client, DixUseAccess);
    314     if (result != Success)
    315         return result;
    316 
    317     pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
    318 
    319     if (!(pSurface = malloc(sizeof(XvMCSurfaceRec))))
    320         return BadAlloc;
    321 
    322     pSurface->surface_id = stuff->surface_id;
    323     pSurface->surface_type_id = pContext->surface_type_id;
    324     pSurface->context = pContext;
    325 
    326     result =
    327         (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface) (pSurface,
    328                                                                      &dwords,
    329                                                                      &data);
    330 
    331     if (result != Success) {
    332         free(pSurface);
    333         return result;
    334     }
    335     if (!AddResource(pSurface->surface_id, XvMCRTSurface, pSurface)) {
    336         free(data);
    337         return BadAlloc;
    338     }
    339 
    340     rep = (xvmcCreateSurfaceReply) {
    341         .type = X_Reply,
    342         .sequenceNumber = client->sequence,
    343         .length = dwords
    344     };
    345 
    346     WriteToClient(client, sizeof(xvmcCreateSurfaceReply), &rep);
    347     if (dwords)
    348         WriteToClient(client, dwords << 2, data);
    349 
    350     free(data);
    351 
    352     pContext->refcnt++;
    353 
    354     return Success;
    355 }
    356 
    357 static int
    358 ProcXvMCDestroySurface(ClientPtr client)
    359 {
    360     void *val;
    361     int rc;
    362 
    363     REQUEST(xvmcDestroySurfaceReq);
    364     REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq);
    365 
    366     rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface,
    367                                  client, DixDestroyAccess);
    368     if (rc != Success)
    369         return rc;
    370 
    371     FreeResource(stuff->surface_id, RT_NONE);
    372 
    373     return Success;
    374 }
    375 
    376 static int
    377 ProcXvMCCreateSubpicture(ClientPtr client)
    378 {
    379     Bool image_supported = FALSE;
    380     CARD32 *data = NULL;
    381     int i, result, dwords = 0;
    382     XvMCContextPtr pContext;
    383     XvMCSubpicturePtr pSubpicture;
    384     XvMCScreenPtr pScreenPriv;
    385     xvmcCreateSubpictureReply rep;
    386     XvMCAdaptorPtr adaptor;
    387     XvMCSurfaceInfoPtr surface = NULL;
    388 
    389     REQUEST(xvmcCreateSubpictureReq);
    390     REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
    391 
    392     result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
    393                                      XvMCRTContext, client, DixUseAccess);
    394     if (result != Success)
    395         return result;
    396 
    397     pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
    398 
    399     adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]);
    400 
    401     /* find which surface this context supports */
    402     for (i = 0; i < adaptor->num_surfaces; i++) {
    403         if (adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id) {
    404             surface = adaptor->surfaces[i];
    405             break;
    406         }
    407     }
    408 
    409     if (!surface)
    410         return BadMatch;
    411 
    412     /* make sure this surface supports that xvimage format */
    413     if (!surface->compatible_subpictures)
    414         return BadMatch;
    415 
    416     for (i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
    417         if (surface->compatible_subpictures->xvimage_ids[i] ==
    418             stuff->xvimage_id) {
    419             image_supported = TRUE;
    420             break;
    421         }
    422     }
    423 
    424     if (!image_supported)
    425         return BadMatch;
    426 
    427     /* make sure the size is OK */
    428     if ((stuff->width > surface->subpicture_max_width) ||
    429         (stuff->height > surface->subpicture_max_height))
    430         return BadValue;
    431 
    432     if (!(pSubpicture = malloc(sizeof(XvMCSubpictureRec))))
    433         return BadAlloc;
    434 
    435     pSubpicture->subpicture_id = stuff->subpicture_id;
    436     pSubpicture->xvimage_id = stuff->xvimage_id;
    437     pSubpicture->width = stuff->width;
    438     pSubpicture->height = stuff->height;
    439     pSubpicture->num_palette_entries = 0;       /* overwritten by DDX */
    440     pSubpicture->entry_bytes = 0;       /* overwritten by DDX */
    441     pSubpicture->component_order[0] = 0;        /* overwritten by DDX */
    442     pSubpicture->component_order[1] = 0;
    443     pSubpicture->component_order[2] = 0;
    444     pSubpicture->component_order[3] = 0;
    445     pSubpicture->context = pContext;
    446 
    447     result =
    448         (*pScreenPriv->adaptors[pContext->adapt_num].
    449          CreateSubpicture) (pSubpicture, &dwords, &data);
    450 
    451     if (result != Success) {
    452         free(pSubpicture);
    453         return result;
    454     }
    455     if (!AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture)) {
    456         free(data);
    457         return BadAlloc;
    458     }
    459 
    460     rep = (xvmcCreateSubpictureReply) {
    461         .type = X_Reply,
    462         .sequenceNumber = client->sequence,
    463         .length = dwords,
    464         .width_actual = pSubpicture->width,
    465         .height_actual = pSubpicture->height,
    466         .num_palette_entries = pSubpicture->num_palette_entries,
    467         .entry_bytes = pSubpicture->entry_bytes,
    468         .component_order[0] = pSubpicture->component_order[0],
    469         .component_order[1] = pSubpicture->component_order[1],
    470         .component_order[2] = pSubpicture->component_order[2],
    471         .component_order[3] = pSubpicture->component_order[3]
    472     };
    473 
    474     WriteToClient(client, sizeof(xvmcCreateSubpictureReply), &rep);
    475     if (dwords)
    476         WriteToClient(client, dwords << 2, data);
    477 
    478     free(data);
    479 
    480     pContext->refcnt++;
    481 
    482     return Success;
    483 }
    484 
    485 static int
    486 ProcXvMCDestroySubpicture(ClientPtr client)
    487 {
    488     void *val;
    489     int rc;
    490 
    491     REQUEST(xvmcDestroySubpictureReq);
    492     REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq);
    493 
    494     rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture,
    495                                  client, DixDestroyAccess);
    496     if (rc != Success)
    497         return rc;
    498 
    499     FreeResource(stuff->subpicture_id, RT_NONE);
    500 
    501     return Success;
    502 }
    503 
    504 static int
    505 ProcXvMCListSubpictureTypes(ClientPtr client)
    506 {
    507     XvPortPtr pPort;
    508     xvmcListSubpictureTypesReply rep;
    509     XvMCScreenPtr pScreenPriv;
    510     ScreenPtr pScreen;
    511     XvMCAdaptorPtr adaptor = NULL;
    512     XvMCSurfaceInfoPtr surface = NULL;
    513     xvImageFormatInfo info;
    514     XvImagePtr pImage;
    515     int i, j;
    516 
    517     REQUEST(xvmcListSubpictureTypesReq);
    518     REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq);
    519 
    520     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    521 
    522     pScreen = pPort->pAdaptor->pScreen;
    523 
    524     if (!dixPrivateKeyRegistered(XvMCScreenKey))
    525         return BadMatch;        /* No XvMC adaptors */
    526 
    527     if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
    528         return BadMatch;        /* None this screen */
    529 
    530     for (i = 0; i < pScreenPriv->num_adaptors; i++) {
    531         if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
    532             adaptor = &(pScreenPriv->adaptors[i]);
    533             break;
    534         }
    535     }
    536 
    537     if (!adaptor)
    538         return BadMatch;
    539 
    540     for (i = 0; i < adaptor->num_surfaces; i++) {
    541         if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
    542             surface = adaptor->surfaces[i];
    543             break;
    544         }
    545     }
    546 
    547     if (!surface)
    548         return BadMatch;
    549 
    550     rep = (xvmcListSubpictureTypesReply) {
    551         .type = X_Reply,
    552         .sequenceNumber = client->sequence,
    553         .num = 0
    554     };
    555     if (surface->compatible_subpictures)
    556         rep.num = surface->compatible_subpictures->num_xvimages;
    557 
    558     rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo));
    559 
    560     WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), &rep);
    561 
    562     for (i = 0; i < rep.num; i++) {
    563         pImage = NULL;
    564         for (j = 0; j < adaptor->num_subpictures; j++) {
    565             if (surface->compatible_subpictures->xvimage_ids[i] ==
    566                 adaptor->subpictures[j]->id) {
    567                 pImage = adaptor->subpictures[j];
    568                 break;
    569             }
    570         }
    571         if (!pImage)
    572             return BadImplementation;
    573 
    574         info.id = pImage->id;
    575         info.type = pImage->type;
    576         info.byte_order = pImage->byte_order;
    577         memcpy(&info.guid, pImage->guid, 16);
    578         info.bpp = pImage->bits_per_pixel;
    579         info.num_planes = pImage->num_planes;
    580         info.depth = pImage->depth;
    581         info.red_mask = pImage->red_mask;
    582         info.green_mask = pImage->green_mask;
    583         info.blue_mask = pImage->blue_mask;
    584         info.format = pImage->format;
    585         info.y_sample_bits = pImage->y_sample_bits;
    586         info.u_sample_bits = pImage->u_sample_bits;
    587         info.v_sample_bits = pImage->v_sample_bits;
    588         info.horz_y_period = pImage->horz_y_period;
    589         info.horz_u_period = pImage->horz_u_period;
    590         info.horz_v_period = pImage->horz_v_period;
    591         info.vert_y_period = pImage->vert_y_period;
    592         info.vert_u_period = pImage->vert_u_period;
    593         info.vert_v_period = pImage->vert_v_period;
    594         memcpy(&info.comp_order, pImage->component_order, 32);
    595         info.scanline_order = pImage->scanline_order;
    596         WriteToClient(client, sizeof(xvImageFormatInfo), &info);
    597     }
    598 
    599     return Success;
    600 }
    601 
    602 static int
    603 ProcXvMCGetDRInfo(ClientPtr client)
    604 {
    605     xvmcGetDRInfoReply rep;
    606     XvPortPtr pPort;
    607     ScreenPtr pScreen;
    608     XvMCScreenPtr pScreenPriv;
    609 
    610 #ifdef HAS_XVMCSHM
    611     volatile CARD32 *patternP;
    612 #endif
    613 
    614     REQUEST(xvmcGetDRInfoReq);
    615     REQUEST_SIZE_MATCH(xvmcGetDRInfoReq);
    616 
    617     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    618 
    619     pScreen = pPort->pAdaptor->pScreen;
    620     pScreenPriv = XVMC_GET_PRIVATE(pScreen);
    621 
    622     rep = (xvmcGetDRInfoReply) {
    623         .type = X_Reply,
    624         .sequenceNumber = client->sequence,
    625         .major = pScreenPriv->major,
    626         .minor = pScreenPriv->minor,
    627         .patchLevel = pScreenPriv->patchLevel,
    628         .nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1),
    629         .busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1),
    630         .isLocal = 1
    631     };
    632 
    633     rep.length = rep.nameLen + rep.busIDLen;
    634     rep.nameLen <<= 2;
    635     rep.busIDLen <<= 2;
    636 
    637     /*
    638      * Read back to the client what she has put in the shared memory
    639      * segment she prepared for us.
    640      */
    641 
    642 #ifdef HAS_XVMCSHM
    643     patternP = (CARD32 *) shmat(stuff->shmKey, NULL, SHM_RDONLY);
    644     if (-1 != (long) patternP) {
    645         volatile CARD32 *patternC = patternP;
    646         int i;
    647         CARD32 magic = stuff->magic;
    648 
    649         rep.isLocal = 1;
    650         i = 1024 / sizeof(CARD32);
    651 
    652         while (i--) {
    653             if (*patternC++ != magic) {
    654                 rep.isLocal = 0;
    655                 break;
    656             }
    657             magic = ~magic;
    658         }
    659         shmdt((char *) patternP);
    660     }
    661 #endif                          /* HAS_XVMCSHM */
    662 
    663     WriteToClient(client, sizeof(xvmcGetDRInfoReply), &rep);
    664     if (rep.length) {
    665         WriteToClient(client, rep.nameLen, pScreenPriv->clientDriverName);
    666         WriteToClient(client, rep.busIDLen, pScreenPriv->busID);
    667     }
    668     return Success;
    669 }
    670 
    671 int (*ProcXvMCVector[xvmcNumRequest]) (ClientPtr) = {
    672 ProcXvMCQueryVersion,
    673         ProcXvMCListSurfaceTypes,
    674         ProcXvMCCreateContext,
    675         ProcXvMCDestroyContext,
    676         ProcXvMCCreateSurface,
    677         ProcXvMCDestroySurface,
    678         ProcXvMCCreateSubpicture,
    679         ProcXvMCDestroySubpicture,
    680         ProcXvMCListSubpictureTypes, ProcXvMCGetDRInfo};
    681 
    682 static int
    683 ProcXvMCDispatch(ClientPtr client)
    684 {
    685     REQUEST(xReq);
    686 
    687     if (stuff->data < xvmcNumRequest)
    688         return (*ProcXvMCVector[stuff->data]) (client);
    689     else
    690         return BadRequest;
    691 }
    692 
    693 static int _X_COLD
    694 SProcXvMCDispatch(ClientPtr client)
    695 {
    696     /* We only support local */
    697     return BadImplementation;
    698 }
    699 
    700 void
    701 XvMCExtensionInit(void)
    702 {
    703     ExtensionEntry *extEntry;
    704 
    705     if (!dixPrivateKeyRegistered(XvMCScreenKey))
    706         return;
    707 
    708     if (!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes,
    709                                                 "XvMCRTContext")))
    710         return;
    711 
    712     if (!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes,
    713                                                 "XvMCRTSurface")))
    714         return;
    715 
    716     if (!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes,
    717                                                    "XvMCRTSubpicture")))
    718         return;
    719 
    720     extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors,
    721                             ProcXvMCDispatch, SProcXvMCDispatch,
    722                             NULL, StandardMinorOpcode);
    723 
    724     if (!extEntry)
    725         return;
    726 
    727     XvMCReqCode = extEntry->base;
    728     XvMCEventBase = extEntry->eventBase;
    729     SetResourceTypeErrorValue(XvMCRTContext,
    730                               extEntry->errorBase + XvMCBadContext);
    731     SetResourceTypeErrorValue(XvMCRTSurface,
    732                               extEntry->errorBase + XvMCBadSurface);
    733     SetResourceTypeErrorValue(XvMCRTSubpicture,
    734                               extEntry->errorBase + XvMCBadSubpicture);
    735 }
    736 
    737 static Bool
    738 XvMCCloseScreen(ScreenPtr pScreen)
    739 {
    740     XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
    741 
    742     pScreen->CloseScreen = pScreenPriv->CloseScreen;
    743 
    744     free(pScreenPriv);
    745 
    746     return (*pScreen->CloseScreen) (pScreen);
    747 }
    748 
    749 int
    750 XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt)
    751 {
    752     XvMCScreenPtr pScreenPriv;
    753 
    754     if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0))
    755         return BadAlloc;
    756 
    757     if (!(pScreenPriv = malloc(sizeof(XvMCScreenRec))))
    758         return BadAlloc;
    759 
    760     dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv);
    761 
    762     pScreenPriv->CloseScreen = pScreen->CloseScreen;
    763     pScreen->CloseScreen = XvMCCloseScreen;
    764 
    765     pScreenPriv->num_adaptors = num;
    766     pScreenPriv->adaptors = pAdapt;
    767     pScreenPriv->clientDriverName[0] = 0;
    768     pScreenPriv->busID[0] = 0;
    769     pScreenPriv->major = 0;
    770     pScreenPriv->minor = 0;
    771     pScreenPriv->patchLevel = 0;
    772 
    773     XvMCInUse = TRUE;
    774 
    775     return Success;
    776 }
    777 
    778 XvImagePtr
    779 XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
    780 {
    781     XvImagePtr pImage = NULL;
    782     ScreenPtr pScreen = pPort->pAdaptor->pScreen;
    783     XvMCScreenPtr pScreenPriv;
    784     XvMCAdaptorPtr adaptor = NULL;
    785     int i;
    786 
    787     if (!dixPrivateKeyRegistered(XvMCScreenKey))
    788         return NULL;
    789 
    790     if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
    791         return NULL;
    792 
    793     for (i = 0; i < pScreenPriv->num_adaptors; i++) {
    794         if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
    795             adaptor = &(pScreenPriv->adaptors[i]);
    796             break;
    797         }
    798     }
    799 
    800     if (!adaptor)
    801         return NULL;
    802 
    803     for (i = 0; i < adaptor->num_subpictures; i++) {
    804         if (adaptor->subpictures[i]->id == id) {
    805             pImage = adaptor->subpictures[i];
    806             break;
    807         }
    808     }
    809 
    810     return pImage;
    811 }
    812 
    813 int
    814 xf86XvMCRegisterDRInfo(ScreenPtr pScreen, const char *name,
    815                        const char *busID, int major, int minor, int patchLevel)
    816 {
    817     XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
    818 
    819     strlcpy(pScreenPriv->clientDriverName, name, DR_CLIENT_DRIVER_NAME_SIZE);
    820     strlcpy(pScreenPriv->busID, busID, DR_BUSID_SIZE);
    821     pScreenPriv->major = major;
    822     pScreenPriv->minor = minor;
    823     pScreenPriv->patchLevel = patchLevel;
    824     return Success;
    825 }