xserver

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

xvdisp.c (48196B)


      1 /***********************************************************
      2 Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
      3 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
      4 
      5                         All Rights Reserved
      6 
      7 Permission to use, copy, modify, and distribute this software and its
      8 documentation for any purpose and without fee is hereby granted,
      9 provided that the above copyright notice appear in all copies and that
     10 both that copyright notice and this permission notice appear in
     11 supporting documentation, and that the names of Digital or MIT not be
     12 used in advertising or publicity pertaining to distribution of the
     13 software without specific, written prior permission.
     14 
     15 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     16 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
     17 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     18 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     19 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     20 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     21 SOFTWARE.
     22 ******************************************************************/
     23 
     24 #ifdef HAVE_DIX_CONFIG_H
     25 #include <dix-config.h>
     26 #endif
     27 
     28 #include <string.h>
     29 
     30 #include <X11/X.h>
     31 #include <X11/Xproto.h>
     32 #include "misc.h"
     33 #include "scrnintstr.h"
     34 #include "windowstr.h"
     35 #include "pixmapstr.h"
     36 #include "gcstruct.h"
     37 #include "dixstruct.h"
     38 #include "resource.h"
     39 #include "opaque.h"
     40 
     41 #include <X11/extensions/Xv.h>
     42 #include <X11/extensions/Xvproto.h>
     43 #include "xvdix.h"
     44 #ifdef MITSHM
     45 #include <X11/extensions/shmproto.h>
     46 #include "shmint.h"
     47 #endif
     48 
     49 #include "xvdisp.h"
     50 
     51 #ifdef PANORAMIX
     52 #include "panoramiX.h"
     53 #include "panoramiXsrv.h"
     54 
     55 unsigned long XvXRTPort;
     56 #endif
     57 
     58 static int
     59 SWriteQueryExtensionReply(ClientPtr client, xvQueryExtensionReply * rep)
     60 {
     61     swaps(&rep->sequenceNumber);
     62     swapl(&rep->length);
     63     swaps(&rep->version);
     64     swaps(&rep->revision);
     65 
     66     WriteToClient(client, sz_xvQueryExtensionReply, rep);
     67 
     68     return Success;
     69 }
     70 
     71 static int
     72 SWriteQueryAdaptorsReply(ClientPtr client, xvQueryAdaptorsReply * rep)
     73 {
     74     swaps(&rep->sequenceNumber);
     75     swapl(&rep->length);
     76     swaps(&rep->num_adaptors);
     77 
     78     WriteToClient(client, sz_xvQueryAdaptorsReply, rep);
     79 
     80     return Success;
     81 }
     82 
     83 static int
     84 SWriteQueryEncodingsReply(ClientPtr client, xvQueryEncodingsReply * rep)
     85 {
     86     swaps(&rep->sequenceNumber);
     87     swapl(&rep->length);
     88     swaps(&rep->num_encodings);
     89 
     90     WriteToClient(client, sz_xvQueryEncodingsReply, rep);
     91 
     92     return Success;
     93 }
     94 
     95 static int
     96 SWriteAdaptorInfo(ClientPtr client, xvAdaptorInfo * pAdaptor)
     97 {
     98     swapl(&pAdaptor->base_id);
     99     swaps(&pAdaptor->name_size);
    100     swaps(&pAdaptor->num_ports);
    101     swaps(&pAdaptor->num_formats);
    102 
    103     WriteToClient(client, sz_xvAdaptorInfo, pAdaptor);
    104 
    105     return Success;
    106 }
    107 
    108 static int
    109 SWriteEncodingInfo(ClientPtr client, xvEncodingInfo * pEncoding)
    110 {
    111 
    112     swapl(&pEncoding->encoding);
    113     swaps(&pEncoding->name_size);
    114     swaps(&pEncoding->width);
    115     swaps(&pEncoding->height);
    116     swapl(&pEncoding->rate.numerator);
    117     swapl(&pEncoding->rate.denominator);
    118     WriteToClient(client, sz_xvEncodingInfo, pEncoding);
    119 
    120     return Success;
    121 }
    122 
    123 static int
    124 SWriteFormat(ClientPtr client, xvFormat * pFormat)
    125 {
    126     swapl(&pFormat->visual);
    127     WriteToClient(client, sz_xvFormat, pFormat);
    128 
    129     return Success;
    130 }
    131 
    132 static int
    133 SWriteAttributeInfo(ClientPtr client, xvAttributeInfo * pAtt)
    134 {
    135     swapl(&pAtt->flags);
    136     swapl(&pAtt->size);
    137     swapl(&pAtt->min);
    138     swapl(&pAtt->max);
    139     WriteToClient(client, sz_xvAttributeInfo, pAtt);
    140 
    141     return Success;
    142 }
    143 
    144 static int
    145 SWriteImageFormatInfo(ClientPtr client, xvImageFormatInfo * pImage)
    146 {
    147     swapl(&pImage->id);
    148     swapl(&pImage->red_mask);
    149     swapl(&pImage->green_mask);
    150     swapl(&pImage->blue_mask);
    151     swapl(&pImage->y_sample_bits);
    152     swapl(&pImage->u_sample_bits);
    153     swapl(&pImage->v_sample_bits);
    154     swapl(&pImage->horz_y_period);
    155     swapl(&pImage->horz_u_period);
    156     swapl(&pImage->horz_v_period);
    157     swapl(&pImage->vert_y_period);
    158     swapl(&pImage->vert_u_period);
    159     swapl(&pImage->vert_v_period);
    160 
    161     WriteToClient(client, sz_xvImageFormatInfo, pImage);
    162 
    163     return Success;
    164 }
    165 
    166 static int
    167 SWriteGrabPortReply(ClientPtr client, xvGrabPortReply * rep)
    168 {
    169     swaps(&rep->sequenceNumber);
    170     swapl(&rep->length);
    171 
    172     WriteToClient(client, sz_xvGrabPortReply, rep);
    173 
    174     return Success;
    175 }
    176 
    177 static int
    178 SWriteGetPortAttributeReply(ClientPtr client, xvGetPortAttributeReply * rep)
    179 {
    180     swaps(&rep->sequenceNumber);
    181     swapl(&rep->length);
    182     swapl(&rep->value);
    183 
    184     WriteToClient(client, sz_xvGetPortAttributeReply, rep);
    185 
    186     return Success;
    187 }
    188 
    189 static int
    190 SWriteQueryBestSizeReply(ClientPtr client, xvQueryBestSizeReply * rep)
    191 {
    192     swaps(&rep->sequenceNumber);
    193     swapl(&rep->length);
    194     swaps(&rep->actual_width);
    195     swaps(&rep->actual_height);
    196 
    197     WriteToClient(client, sz_xvQueryBestSizeReply, rep);
    198 
    199     return Success;
    200 }
    201 
    202 static int
    203 SWriteQueryPortAttributesReply(ClientPtr client,
    204                                xvQueryPortAttributesReply * rep)
    205 {
    206     swaps(&rep->sequenceNumber);
    207     swapl(&rep->length);
    208     swapl(&rep->num_attributes);
    209     swapl(&rep->text_size);
    210 
    211     WriteToClient(client, sz_xvQueryPortAttributesReply, rep);
    212 
    213     return Success;
    214 }
    215 
    216 static int
    217 SWriteQueryImageAttributesReply(ClientPtr client,
    218                                 xvQueryImageAttributesReply * rep)
    219 {
    220     swaps(&rep->sequenceNumber);
    221     swapl(&rep->length);
    222     swapl(&rep->num_planes);
    223     swapl(&rep->data_size);
    224     swaps(&rep->width);
    225     swaps(&rep->height);
    226 
    227     WriteToClient(client, sz_xvQueryImageAttributesReply, rep);
    228 
    229     return Success;
    230 }
    231 
    232 static int
    233 SWriteListImageFormatsReply(ClientPtr client, xvListImageFormatsReply * rep)
    234 {
    235     swaps(&rep->sequenceNumber);
    236     swapl(&rep->length);
    237     swapl(&rep->num_formats);
    238 
    239     WriteToClient(client, sz_xvListImageFormatsReply, rep);
    240 
    241     return Success;
    242 }
    243 
    244 #define _WriteQueryAdaptorsReply(_c,_d) \
    245   if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
    246   else WriteToClient(_c, sz_xvQueryAdaptorsReply, _d)
    247 
    248 #define _WriteQueryExtensionReply(_c,_d) \
    249   if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
    250   else WriteToClient(_c, sz_xvQueryExtensionReply, _d)
    251 
    252 #define _WriteQueryEncodingsReply(_c,_d) \
    253   if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
    254   else WriteToClient(_c, sz_xvQueryEncodingsReply, _d)
    255 
    256 #define _WriteAdaptorInfo(_c,_d) \
    257   if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
    258   else WriteToClient(_c, sz_xvAdaptorInfo, _d)
    259 
    260 #define _WriteAttributeInfo(_c,_d) \
    261   if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
    262   else WriteToClient(_c, sz_xvAttributeInfo, _d)
    263 
    264 #define _WriteEncodingInfo(_c,_d) \
    265   if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
    266   else WriteToClient(_c, sz_xvEncodingInfo, _d)
    267 
    268 #define _WriteFormat(_c,_d) \
    269   if ((_c)->swapped) SWriteFormat(_c, _d); \
    270   else WriteToClient(_c, sz_xvFormat, _d)
    271 
    272 #define _WriteGrabPortReply(_c,_d) \
    273   if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
    274   else WriteToClient(_c, sz_xvGrabPortReply, _d)
    275 
    276 #define _WriteGetPortAttributeReply(_c,_d) \
    277   if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
    278   else WriteToClient(_c, sz_xvGetPortAttributeReply, _d)
    279 
    280 #define _WriteQueryBestSizeReply(_c,_d) \
    281   if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
    282   else WriteToClient(_c, sz_xvQueryBestSizeReply, _d)
    283 
    284 #define _WriteQueryPortAttributesReply(_c,_d) \
    285   if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
    286   else WriteToClient(_c, sz_xvQueryPortAttributesReply, _d)
    287 
    288 #define _WriteQueryImageAttributesReply(_c,_d) \
    289   if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
    290   else WriteToClient(_c, sz_xvQueryImageAttributesReply, _d)
    291 
    292 #define _WriteListImageFormatsReply(_c,_d) \
    293   if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
    294   else WriteToClient(_c, sz_xvListImageFormatsReply, _d)
    295 
    296 #define _WriteImageFormatInfo(_c,_d) \
    297   if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
    298   else WriteToClient(_c, sz_xvImageFormatInfo, _d)
    299 
    300 static int
    301 ProcXvQueryExtension(ClientPtr client)
    302 {
    303     xvQueryExtensionReply rep = {
    304         .type = X_Reply,
    305         .sequenceNumber = client->sequence,
    306         .length = 0,
    307         .version = XvVersion,
    308         .revision = XvRevision
    309     };
    310 
    311     /* REQUEST(xvQueryExtensionReq); */
    312     REQUEST_SIZE_MATCH(xvQueryExtensionReq);
    313 
    314     _WriteQueryExtensionReply(client, &rep);
    315 
    316     return Success;
    317 }
    318 
    319 static int
    320 ProcXvQueryAdaptors(ClientPtr client)
    321 {
    322     xvFormat format;
    323     xvAdaptorInfo ainfo;
    324     xvQueryAdaptorsReply rep;
    325     int totalSize, na, nf, rc;
    326     int nameSize;
    327     XvAdaptorPtr pa;
    328     XvFormatPtr pf;
    329     WindowPtr pWin;
    330     ScreenPtr pScreen;
    331     XvScreenPtr pxvs;
    332 
    333     REQUEST(xvQueryAdaptorsReq);
    334     REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
    335 
    336     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    337     if (rc != Success)
    338         return rc;
    339 
    340     pScreen = pWin->drawable.pScreen;
    341     pxvs = (XvScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    342                                           XvGetScreenKey());
    343     if (!pxvs) {
    344         rep = (xvQueryAdaptorsReply) {
    345             .type = X_Reply,
    346             .sequenceNumber = client->sequence,
    347             .length = 0,
    348             .num_adaptors = 0
    349         };
    350 
    351         _WriteQueryAdaptorsReply(client, &rep);
    352 
    353         return Success;
    354     }
    355 
    356     rep = (xvQueryAdaptorsReply) {
    357         .type = X_Reply,
    358         .sequenceNumber = client->sequence,
    359         .num_adaptors = pxvs->nAdaptors
    360     };
    361 
    362     /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
    363 
    364     totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
    365 
    366     /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
    367 
    368     na = pxvs->nAdaptors;
    369     pa = pxvs->pAdaptors;
    370     while (na--) {
    371         totalSize += pad_to_int32(strlen(pa->name));
    372         totalSize += pa->nFormats * sz_xvFormat;
    373         pa++;
    374     }
    375 
    376     rep.length = bytes_to_int32(totalSize);
    377 
    378     _WriteQueryAdaptorsReply(client, &rep);
    379 
    380     na = pxvs->nAdaptors;
    381     pa = pxvs->pAdaptors;
    382     while (na--) {
    383 
    384         ainfo.base_id = pa->base_id;
    385         ainfo.num_ports = pa->nPorts;
    386         ainfo.type = pa->type;
    387         ainfo.name_size = nameSize = strlen(pa->name);
    388         ainfo.num_formats = pa->nFormats;
    389 
    390         _WriteAdaptorInfo(client, &ainfo);
    391 
    392         WriteToClient(client, nameSize, pa->name);
    393 
    394         nf = pa->nFormats;
    395         pf = pa->pFormats;
    396         while (nf--) {
    397             format.depth = pf->depth;
    398             format.visual = pf->visual;
    399             _WriteFormat(client, &format);
    400             pf++;
    401         }
    402 
    403         pa++;
    404 
    405     }
    406 
    407     return Success;
    408 }
    409 
    410 static int
    411 ProcXvQueryEncodings(ClientPtr client)
    412 {
    413     xvEncodingInfo einfo;
    414     xvQueryEncodingsReply rep;
    415     int totalSize;
    416     int nameSize;
    417     XvPortPtr pPort;
    418     int ne;
    419     XvEncodingPtr pe;
    420 
    421     REQUEST(xvQueryEncodingsReq);
    422     REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
    423 
    424     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    425 
    426     rep = (xvQueryEncodingsReply) {
    427         .type = X_Reply,
    428         .sequenceNumber = client->sequence,
    429         .num_encodings = pPort->pAdaptor->nEncodings
    430     };
    431 
    432     /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
    433 
    434     ne = pPort->pAdaptor->nEncodings;
    435     pe = pPort->pAdaptor->pEncodings;
    436     totalSize = ne * sz_xvEncodingInfo;
    437     while (ne--) {
    438         totalSize += pad_to_int32(strlen(pe->name));
    439         pe++;
    440     }
    441 
    442     rep.length = bytes_to_int32(totalSize);
    443 
    444     _WriteQueryEncodingsReply(client, &rep);
    445 
    446     ne = pPort->pAdaptor->nEncodings;
    447     pe = pPort->pAdaptor->pEncodings;
    448     while (ne--) {
    449         einfo.encoding = pe->id;
    450         einfo.name_size = nameSize = strlen(pe->name);
    451         einfo.width = pe->width;
    452         einfo.height = pe->height;
    453         einfo.rate.numerator = pe->rate.numerator;
    454         einfo.rate.denominator = pe->rate.denominator;
    455         _WriteEncodingInfo(client, &einfo);
    456         WriteToClient(client, nameSize, pe->name);
    457         pe++;
    458     }
    459 
    460     return Success;
    461 }
    462 
    463 static int
    464 ProcXvPutVideo(ClientPtr client)
    465 {
    466     DrawablePtr pDraw;
    467     XvPortPtr pPort;
    468     GCPtr pGC;
    469     int status;
    470 
    471     REQUEST(xvPutVideoReq);
    472     REQUEST_SIZE_MATCH(xvPutVideoReq);
    473 
    474     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
    475     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    476 
    477     if (!(pPort->pAdaptor->type & XvInputMask) ||
    478         !(pPort->pAdaptor->type & XvVideoMask)) {
    479         client->errorValue = stuff->port;
    480         return BadMatch;
    481     }
    482 
    483     status = XvdiMatchPort(pPort, pDraw);
    484     if (status != Success) {
    485         return status;
    486     }
    487 
    488     return XvdiPutVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
    489                         stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
    490                         stuff->drw_w, stuff->drw_h);
    491 }
    492 
    493 static int
    494 ProcXvPutStill(ClientPtr client)
    495 {
    496     DrawablePtr pDraw;
    497     XvPortPtr pPort;
    498     GCPtr pGC;
    499     int status;
    500 
    501     REQUEST(xvPutStillReq);
    502     REQUEST_SIZE_MATCH(xvPutStillReq);
    503 
    504     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
    505     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    506 
    507     if (!(pPort->pAdaptor->type & XvInputMask) ||
    508         !(pPort->pAdaptor->type & XvStillMask)) {
    509         client->errorValue = stuff->port;
    510         return BadMatch;
    511     }
    512 
    513     status = XvdiMatchPort(pPort, pDraw);
    514     if (status != Success) {
    515         return status;
    516     }
    517 
    518     return XvdiPutStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
    519                         stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
    520                         stuff->drw_w, stuff->drw_h);
    521 }
    522 
    523 static int
    524 ProcXvGetVideo(ClientPtr client)
    525 {
    526     DrawablePtr pDraw;
    527     XvPortPtr pPort;
    528     GCPtr pGC;
    529     int status;
    530 
    531     REQUEST(xvGetVideoReq);
    532     REQUEST_SIZE_MATCH(xvGetVideoReq);
    533 
    534     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
    535     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    536 
    537     if (!(pPort->pAdaptor->type & XvOutputMask) ||
    538         !(pPort->pAdaptor->type & XvVideoMask)) {
    539         client->errorValue = stuff->port;
    540         return BadMatch;
    541     }
    542 
    543     status = XvdiMatchPort(pPort, pDraw);
    544     if (status != Success) {
    545         return status;
    546     }
    547 
    548     return XvdiGetVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
    549                         stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
    550                         stuff->drw_w, stuff->drw_h);
    551 }
    552 
    553 static int
    554 ProcXvGetStill(ClientPtr client)
    555 {
    556     DrawablePtr pDraw;
    557     XvPortPtr pPort;
    558     GCPtr pGC;
    559     int status;
    560 
    561     REQUEST(xvGetStillReq);
    562     REQUEST_SIZE_MATCH(xvGetStillReq);
    563 
    564     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
    565     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    566 
    567     if (!(pPort->pAdaptor->type & XvOutputMask) ||
    568         !(pPort->pAdaptor->type & XvStillMask)) {
    569         client->errorValue = stuff->port;
    570         return BadMatch;
    571     }
    572 
    573     status = XvdiMatchPort(pPort, pDraw);
    574     if (status != Success) {
    575         return status;
    576     }
    577 
    578     return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
    579                         stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
    580                         stuff->drw_w, stuff->drw_h);
    581 }
    582 
    583 static int
    584 ProcXvSelectVideoNotify(ClientPtr client)
    585 {
    586     DrawablePtr pDraw;
    587     int rc;
    588 
    589     REQUEST(xvSelectVideoNotifyReq);
    590     REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
    591 
    592     rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
    593                            DixReceiveAccess);
    594     if (rc != Success)
    595         return rc;
    596 
    597     return XvdiSelectVideoNotify(client, pDraw, stuff->onoff);
    598 }
    599 
    600 static int
    601 ProcXvSelectPortNotify(ClientPtr client)
    602 {
    603     XvPortPtr pPort;
    604 
    605     REQUEST(xvSelectPortNotifyReq);
    606     REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
    607 
    608     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    609 
    610     return XvdiSelectPortNotify(client, pPort, stuff->onoff);
    611 }
    612 
    613 static int
    614 ProcXvGrabPort(ClientPtr client)
    615 {
    616     int result, status;
    617     XvPortPtr pPort;
    618     xvGrabPortReply rep;
    619 
    620     REQUEST(xvGrabPortReq);
    621     REQUEST_SIZE_MATCH(xvGrabPortReq);
    622 
    623     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    624 
    625     status = XvdiGrabPort(client, pPort, stuff->time, &result);
    626 
    627     if (status != Success) {
    628         return status;
    629     }
    630     rep = (xvGrabPortReply) {
    631         .type = X_Reply,
    632         .sequenceNumber = client->sequence,
    633         .length = 0,
    634         .result = result
    635     };
    636 
    637     _WriteGrabPortReply(client, &rep);
    638 
    639     return Success;
    640 }
    641 
    642 static int
    643 ProcXvUngrabPort(ClientPtr client)
    644 {
    645     XvPortPtr pPort;
    646 
    647     REQUEST(xvGrabPortReq);
    648     REQUEST_SIZE_MATCH(xvGrabPortReq);
    649 
    650     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    651 
    652     return XvdiUngrabPort(client, pPort, stuff->time);
    653 }
    654 
    655 static int
    656 ProcXvStopVideo(ClientPtr client)
    657 {
    658     int ret;
    659     DrawablePtr pDraw;
    660     XvPortPtr pPort;
    661 
    662     REQUEST(xvStopVideoReq);
    663     REQUEST_SIZE_MATCH(xvStopVideoReq);
    664 
    665     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    666 
    667     ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
    668     if (ret != Success)
    669         return ret;
    670 
    671     return XvdiStopVideo(client, pPort, pDraw);
    672 }
    673 
    674 static int
    675 ProcXvSetPortAttribute(ClientPtr client)
    676 {
    677     int status;
    678     XvPortPtr pPort;
    679 
    680     REQUEST(xvSetPortAttributeReq);
    681     REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
    682 
    683     VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess);
    684 
    685     if (!ValidAtom(stuff->attribute)) {
    686         client->errorValue = stuff->attribute;
    687         return BadAtom;
    688     }
    689 
    690     status =
    691         XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value);
    692 
    693     if (status == BadMatch)
    694         client->errorValue = stuff->attribute;
    695     else
    696         client->errorValue = stuff->value;
    697 
    698     return status;
    699 }
    700 
    701 static int
    702 ProcXvGetPortAttribute(ClientPtr client)
    703 {
    704     INT32 value;
    705     int status;
    706     XvPortPtr pPort;
    707     xvGetPortAttributeReply rep;
    708 
    709     REQUEST(xvGetPortAttributeReq);
    710     REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
    711 
    712     VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
    713 
    714     if (!ValidAtom(stuff->attribute)) {
    715         client->errorValue = stuff->attribute;
    716         return BadAtom;
    717     }
    718 
    719     status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value);
    720     if (status != Success) {
    721         client->errorValue = stuff->attribute;
    722         return status;
    723     }
    724 
    725     rep = (xvGetPortAttributeReply) {
    726         .type = X_Reply,
    727         .sequenceNumber = client->sequence,
    728         .length = 0,
    729         .value = value
    730     };
    731 
    732     _WriteGetPortAttributeReply(client, &rep);
    733 
    734     return Success;
    735 }
    736 
    737 static int
    738 ProcXvQueryBestSize(ClientPtr client)
    739 {
    740     unsigned int actual_width, actual_height;
    741     XvPortPtr pPort;
    742     xvQueryBestSizeReply rep;
    743 
    744     REQUEST(xvQueryBestSizeReq);
    745     REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
    746 
    747     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    748 
    749     (*pPort->pAdaptor->ddQueryBestSize) (pPort, stuff->motion,
    750                                          stuff->vid_w, stuff->vid_h,
    751                                          stuff->drw_w, stuff->drw_h,
    752                                          &actual_width, &actual_height);
    753 
    754     rep = (xvQueryBestSizeReply) {
    755         .type = X_Reply,
    756         .sequenceNumber = client->sequence,
    757         .length = 0,
    758         .actual_width = actual_width,
    759         .actual_height = actual_height
    760     };
    761 
    762     _WriteQueryBestSizeReply(client, &rep);
    763 
    764     return Success;
    765 }
    766 
    767 static int
    768 ProcXvQueryPortAttributes(ClientPtr client)
    769 {
    770     int size, i;
    771     XvPortPtr pPort;
    772     XvAttributePtr pAtt;
    773     xvQueryPortAttributesReply rep;
    774     xvAttributeInfo Info;
    775 
    776     REQUEST(xvQueryPortAttributesReq);
    777     REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
    778 
    779     VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
    780 
    781     rep = (xvQueryPortAttributesReply) {
    782         .type = X_Reply,
    783         .sequenceNumber = client->sequence,
    784         .num_attributes = pPort->pAdaptor->nAttributes,
    785         .text_size = 0
    786     };
    787 
    788     for (i = 0, pAtt = pPort->pAdaptor->pAttributes;
    789          i < pPort->pAdaptor->nAttributes; i++, pAtt++) {
    790         rep.text_size += pad_to_int32(strlen(pAtt->name) + 1);
    791     }
    792 
    793     rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo)
    794         + rep.text_size;
    795     rep.length >>= 2;
    796 
    797     _WriteQueryPortAttributesReply(client, &rep);
    798 
    799     for (i = 0, pAtt = pPort->pAdaptor->pAttributes;
    800          i < pPort->pAdaptor->nAttributes; i++, pAtt++) {
    801         size = strlen(pAtt->name) + 1;  /* pass the NULL */
    802         Info.flags = pAtt->flags;
    803         Info.min = pAtt->min_value;
    804         Info.max = pAtt->max_value;
    805         Info.size = pad_to_int32(size);
    806 
    807         _WriteAttributeInfo(client, &Info);
    808 
    809         WriteToClient(client, size, pAtt->name);
    810     }
    811 
    812     return Success;
    813 }
    814 
    815 static int
    816 ProcXvPutImage(ClientPtr client)
    817 {
    818     DrawablePtr pDraw;
    819     XvPortPtr pPort;
    820     XvImagePtr pImage = NULL;
    821     GCPtr pGC;
    822     int status, i, size;
    823     CARD16 width, height;
    824 
    825     REQUEST(xvPutImageReq);
    826     REQUEST_AT_LEAST_SIZE(xvPutImageReq);
    827 
    828     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
    829     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    830 
    831     if (!(pPort->pAdaptor->type & XvImageMask) ||
    832         !(pPort->pAdaptor->type & XvInputMask)) {
    833         client->errorValue = stuff->port;
    834         return BadMatch;
    835     }
    836 
    837     status = XvdiMatchPort(pPort, pDraw);
    838     if (status != Success) {
    839         return status;
    840     }
    841 
    842     for (i = 0; i < pPort->pAdaptor->nImages; i++) {
    843         if (pPort->pAdaptor->pImages[i].id == stuff->id) {
    844             pImage = &(pPort->pAdaptor->pImages[i]);
    845             break;
    846         }
    847     }
    848 
    849     if (!pImage)
    850         return BadMatch;
    851 
    852     width = stuff->width;
    853     height = stuff->height;
    854     size = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage, &width,
    855                                                        &height, NULL, NULL);
    856     size += sizeof(xvPutImageReq);
    857     size = bytes_to_int32(size);
    858 
    859     if ((width < stuff->width) || (height < stuff->height))
    860         return BadValue;
    861 
    862     if (client->req_len < size)
    863         return BadLength;
    864 
    865     return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
    866                         stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
    867                         stuff->drw_w, stuff->drw_h, pImage,
    868                         (unsigned char *) (&stuff[1]), FALSE,
    869                         stuff->width, stuff->height);
    870 }
    871 
    872 #ifdef MITSHM
    873 
    874 static int
    875 ProcXvShmPutImage(ClientPtr client)
    876 {
    877     ShmDescPtr shmdesc;
    878     DrawablePtr pDraw;
    879     XvPortPtr pPort;
    880     XvImagePtr pImage = NULL;
    881     GCPtr pGC;
    882     int status, size_needed, i;
    883     CARD16 width, height;
    884 
    885     REQUEST(xvShmPutImageReq);
    886     REQUEST_SIZE_MATCH(xvShmPutImageReq);
    887 
    888     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
    889     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    890 
    891     if (!(pPort->pAdaptor->type & XvImageMask) ||
    892         !(pPort->pAdaptor->type & XvInputMask)) {
    893         client->errorValue = stuff->port;
    894         return BadMatch;
    895     }
    896 
    897     status = XvdiMatchPort(pPort, pDraw);
    898     if (status != Success) {
    899         return status;
    900     }
    901 
    902     for (i = 0; i < pPort->pAdaptor->nImages; i++) {
    903         if (pPort->pAdaptor->pImages[i].id == stuff->id) {
    904             pImage = &(pPort->pAdaptor->pImages[i]);
    905             break;
    906         }
    907     }
    908 
    909     if (!pImage)
    910         return BadMatch;
    911 
    912     status = dixLookupResourceByType((void **) &shmdesc, stuff->shmseg,
    913                                      ShmSegType, serverClient, DixReadAccess);
    914     if (status != Success)
    915         return status;
    916 
    917     width = stuff->width;
    918     height = stuff->height;
    919     size_needed = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage,
    920                                                               &width, &height,
    921                                                               NULL, NULL);
    922     if ((size_needed + stuff->offset) > shmdesc->size)
    923         return BadAccess;
    924 
    925     if ((width < stuff->width) || (height < stuff->height))
    926         return BadValue;
    927 
    928     status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
    929                           stuff->src_w, stuff->src_h, stuff->drw_x,
    930                           stuff->drw_y, stuff->drw_w, stuff->drw_h, pImage,
    931                           (unsigned char *) shmdesc->addr + stuff->offset,
    932                           stuff->send_event, stuff->width, stuff->height);
    933 
    934     if ((status == Success) && stuff->send_event) {
    935         xShmCompletionEvent ev = {
    936             .type = ShmCompletionCode,
    937             .drawable = stuff->drawable,
    938             .minorEvent = xv_ShmPutImage,
    939             .majorEvent = XvReqCode,
    940             .shmseg = stuff->shmseg,
    941             .offset = stuff->offset
    942         };
    943         WriteEventsToClient(client, 1, (xEvent *) &ev);
    944     }
    945 
    946     return status;
    947 }
    948 #else                           /* !MITSHM */
    949 static int
    950 ProcXvShmPutImage(ClientPtr client)
    951 {
    952     return BadImplementation;
    953 }
    954 #endif
    955 
    956 #ifdef XvMCExtension
    957 #include "xvmcext.h"
    958 #endif
    959 
    960 static int
    961 ProcXvQueryImageAttributes(ClientPtr client)
    962 {
    963     xvQueryImageAttributesReply rep;
    964     int size, num_planes, i;
    965     CARD16 width, height;
    966     XvImagePtr pImage = NULL;
    967     XvPortPtr pPort;
    968     int *offsets;
    969     int *pitches;
    970     int planeLength;
    971 
    972     REQUEST(xvQueryImageAttributesReq);
    973 
    974     REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
    975 
    976     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
    977 
    978     for (i = 0; i < pPort->pAdaptor->nImages; i++) {
    979         if (pPort->pAdaptor->pImages[i].id == stuff->id) {
    980             pImage = &(pPort->pAdaptor->pImages[i]);
    981             break;
    982         }
    983     }
    984 
    985 #ifdef XvMCExtension
    986     if (!pImage)
    987         pImage = XvMCFindXvImage(pPort, stuff->id);
    988 #endif
    989 
    990     if (!pImage)
    991         return BadMatch;
    992 
    993     num_planes = pImage->num_planes;
    994 
    995     if (!(offsets = malloc(num_planes << 3)))
    996         return BadAlloc;
    997     pitches = offsets + num_planes;
    998 
    999     width = stuff->width;
   1000     height = stuff->height;
   1001 
   1002     size = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage,
   1003                                                        &width, &height, offsets,
   1004                                                        pitches);
   1005 
   1006     rep = (xvQueryImageAttributesReply) {
   1007         .type = X_Reply,
   1008         .sequenceNumber = client->sequence,
   1009         .length = planeLength = num_planes << 1,
   1010         .num_planes = num_planes,
   1011         .width = width,
   1012         .height = height,
   1013         .data_size = size
   1014     };
   1015 
   1016     _WriteQueryImageAttributesReply(client, &rep);
   1017     if (client->swapped)
   1018         SwapLongs((CARD32 *) offsets, planeLength);
   1019     WriteToClient(client, planeLength << 2, offsets);
   1020 
   1021     free(offsets);
   1022 
   1023     return Success;
   1024 }
   1025 
   1026 static int
   1027 ProcXvListImageFormats(ClientPtr client)
   1028 {
   1029     XvPortPtr pPort;
   1030     XvImagePtr pImage;
   1031     int i;
   1032     xvListImageFormatsReply rep;
   1033     xvImageFormatInfo info;
   1034 
   1035     REQUEST(xvListImageFormatsReq);
   1036 
   1037     REQUEST_SIZE_MATCH(xvListImageFormatsReq);
   1038 
   1039     VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
   1040 
   1041     rep = (xvListImageFormatsReply) {
   1042         .type = X_Reply,
   1043         .sequenceNumber = client->sequence,
   1044         .num_formats = pPort->pAdaptor->nImages,
   1045         .length =
   1046             bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo)
   1047     };
   1048 
   1049     _WriteListImageFormatsReply(client, &rep);
   1050 
   1051     pImage = pPort->pAdaptor->pImages;
   1052 
   1053     for (i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) {
   1054         info.id = pImage->id;
   1055         info.type = pImage->type;
   1056         info.byte_order = pImage->byte_order;
   1057         memcpy(&info.guid, pImage->guid, 16);
   1058         info.bpp = pImage->bits_per_pixel;
   1059         info.num_planes = pImage->num_planes;
   1060         info.depth = pImage->depth;
   1061         info.red_mask = pImage->red_mask;
   1062         info.green_mask = pImage->green_mask;
   1063         info.blue_mask = pImage->blue_mask;
   1064         info.format = pImage->format;
   1065         info.y_sample_bits = pImage->y_sample_bits;
   1066         info.u_sample_bits = pImage->u_sample_bits;
   1067         info.v_sample_bits = pImage->v_sample_bits;
   1068         info.horz_y_period = pImage->horz_y_period;
   1069         info.horz_u_period = pImage->horz_u_period;
   1070         info.horz_v_period = pImage->horz_v_period;
   1071         info.vert_y_period = pImage->vert_y_period;
   1072         info.vert_u_period = pImage->vert_u_period;
   1073         info.vert_v_period = pImage->vert_v_period;
   1074         memcpy(&info.comp_order, pImage->component_order, 32);
   1075         info.scanline_order = pImage->scanline_order;
   1076         _WriteImageFormatInfo(client, &info);
   1077     }
   1078 
   1079     return Success;
   1080 }
   1081 
   1082 static int (*XvProcVector[xvNumRequests]) (ClientPtr) = {
   1083 ProcXvQueryExtension,
   1084         ProcXvQueryAdaptors,
   1085         ProcXvQueryEncodings,
   1086         ProcXvGrabPort,
   1087         ProcXvUngrabPort,
   1088         ProcXvPutVideo,
   1089         ProcXvPutStill,
   1090         ProcXvGetVideo,
   1091         ProcXvGetStill,
   1092         ProcXvStopVideo,
   1093         ProcXvSelectVideoNotify,
   1094         ProcXvSelectPortNotify,
   1095         ProcXvQueryBestSize,
   1096         ProcXvSetPortAttribute,
   1097         ProcXvGetPortAttribute,
   1098         ProcXvQueryPortAttributes,
   1099         ProcXvListImageFormats,
   1100         ProcXvQueryImageAttributes, ProcXvPutImage, ProcXvShmPutImage,};
   1101 
   1102 int
   1103 ProcXvDispatch(ClientPtr client)
   1104 {
   1105     REQUEST(xReq);
   1106 
   1107     UpdateCurrentTime();
   1108 
   1109     if (stuff->data >= xvNumRequests) {
   1110         return BadRequest;
   1111     }
   1112 
   1113     return XvProcVector[stuff->data] (client);
   1114 }
   1115 
   1116 /* Swapped Procs */
   1117 
   1118 static int _X_COLD
   1119 SProcXvQueryExtension(ClientPtr client)
   1120 {
   1121     REQUEST(xvQueryExtensionReq);
   1122     REQUEST_SIZE_MATCH(xvQueryExtensionReq);
   1123     swaps(&stuff->length);
   1124     return XvProcVector[xv_QueryExtension] (client);
   1125 }
   1126 
   1127 static int _X_COLD
   1128 SProcXvQueryAdaptors(ClientPtr client)
   1129 {
   1130     REQUEST(xvQueryAdaptorsReq);
   1131     REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
   1132     swaps(&stuff->length);
   1133     swapl(&stuff->window);
   1134     return XvProcVector[xv_QueryAdaptors] (client);
   1135 }
   1136 
   1137 static int _X_COLD
   1138 SProcXvQueryEncodings(ClientPtr client)
   1139 {
   1140     REQUEST(xvQueryEncodingsReq);
   1141     REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
   1142     swaps(&stuff->length);
   1143     swapl(&stuff->port);
   1144     return XvProcVector[xv_QueryEncodings] (client);
   1145 }
   1146 
   1147 static int _X_COLD
   1148 SProcXvGrabPort(ClientPtr client)
   1149 {
   1150     REQUEST(xvGrabPortReq);
   1151     REQUEST_SIZE_MATCH(xvGrabPortReq);
   1152     swaps(&stuff->length);
   1153     swapl(&stuff->port);
   1154     swapl(&stuff->time);
   1155     return XvProcVector[xv_GrabPort] (client);
   1156 }
   1157 
   1158 static int _X_COLD
   1159 SProcXvUngrabPort(ClientPtr client)
   1160 {
   1161     REQUEST(xvUngrabPortReq);
   1162     REQUEST_SIZE_MATCH(xvUngrabPortReq);
   1163     swaps(&stuff->length);
   1164     swapl(&stuff->port);
   1165     swapl(&stuff->time);
   1166     return XvProcVector[xv_UngrabPort] (client);
   1167 }
   1168 
   1169 static int _X_COLD
   1170 SProcXvPutVideo(ClientPtr client)
   1171 {
   1172     REQUEST(xvPutVideoReq);
   1173     REQUEST_SIZE_MATCH(xvPutVideoReq);
   1174     swaps(&stuff->length);
   1175     swapl(&stuff->port);
   1176     swapl(&stuff->drawable);
   1177     swapl(&stuff->gc);
   1178     swaps(&stuff->vid_x);
   1179     swaps(&stuff->vid_y);
   1180     swaps(&stuff->vid_w);
   1181     swaps(&stuff->vid_h);
   1182     swaps(&stuff->drw_x);
   1183     swaps(&stuff->drw_y);
   1184     swaps(&stuff->drw_w);
   1185     swaps(&stuff->drw_h);
   1186     return XvProcVector[xv_PutVideo] (client);
   1187 }
   1188 
   1189 static int _X_COLD
   1190 SProcXvPutStill(ClientPtr client)
   1191 {
   1192     REQUEST(xvPutStillReq);
   1193     REQUEST_SIZE_MATCH(xvPutStillReq);
   1194     swaps(&stuff->length);
   1195     swapl(&stuff->port);
   1196     swapl(&stuff->drawable);
   1197     swapl(&stuff->gc);
   1198     swaps(&stuff->vid_x);
   1199     swaps(&stuff->vid_y);
   1200     swaps(&stuff->vid_w);
   1201     swaps(&stuff->vid_h);
   1202     swaps(&stuff->drw_x);
   1203     swaps(&stuff->drw_y);
   1204     swaps(&stuff->drw_w);
   1205     swaps(&stuff->drw_h);
   1206     return XvProcVector[xv_PutStill] (client);
   1207 }
   1208 
   1209 static int _X_COLD
   1210 SProcXvGetVideo(ClientPtr client)
   1211 {
   1212     REQUEST(xvGetVideoReq);
   1213     REQUEST_SIZE_MATCH(xvGetVideoReq);
   1214     swaps(&stuff->length);
   1215     swapl(&stuff->port);
   1216     swapl(&stuff->drawable);
   1217     swapl(&stuff->gc);
   1218     swaps(&stuff->vid_x);
   1219     swaps(&stuff->vid_y);
   1220     swaps(&stuff->vid_w);
   1221     swaps(&stuff->vid_h);
   1222     swaps(&stuff->drw_x);
   1223     swaps(&stuff->drw_y);
   1224     swaps(&stuff->drw_w);
   1225     swaps(&stuff->drw_h);
   1226     return XvProcVector[xv_GetVideo] (client);
   1227 }
   1228 
   1229 static int _X_COLD
   1230 SProcXvGetStill(ClientPtr client)
   1231 {
   1232     REQUEST(xvGetStillReq);
   1233     REQUEST_SIZE_MATCH(xvGetStillReq);
   1234     swaps(&stuff->length);
   1235     swapl(&stuff->port);
   1236     swapl(&stuff->drawable);
   1237     swapl(&stuff->gc);
   1238     swaps(&stuff->vid_x);
   1239     swaps(&stuff->vid_y);
   1240     swaps(&stuff->vid_w);
   1241     swaps(&stuff->vid_h);
   1242     swaps(&stuff->drw_x);
   1243     swaps(&stuff->drw_y);
   1244     swaps(&stuff->drw_w);
   1245     swaps(&stuff->drw_h);
   1246     return XvProcVector[xv_GetStill] (client);
   1247 }
   1248 
   1249 static int _X_COLD
   1250 SProcXvPutImage(ClientPtr client)
   1251 {
   1252     REQUEST(xvPutImageReq);
   1253     REQUEST_AT_LEAST_SIZE(xvPutImageReq);
   1254     swaps(&stuff->length);
   1255     swapl(&stuff->port);
   1256     swapl(&stuff->drawable);
   1257     swapl(&stuff->gc);
   1258     swapl(&stuff->id);
   1259     swaps(&stuff->src_x);
   1260     swaps(&stuff->src_y);
   1261     swaps(&stuff->src_w);
   1262     swaps(&stuff->src_h);
   1263     swaps(&stuff->drw_x);
   1264     swaps(&stuff->drw_y);
   1265     swaps(&stuff->drw_w);
   1266     swaps(&stuff->drw_h);
   1267     swaps(&stuff->width);
   1268     swaps(&stuff->height);
   1269     return XvProcVector[xv_PutImage] (client);
   1270 }
   1271 
   1272 #ifdef MITSHM
   1273 static int _X_COLD
   1274 SProcXvShmPutImage(ClientPtr client)
   1275 {
   1276     REQUEST(xvShmPutImageReq);
   1277     REQUEST_SIZE_MATCH(xvShmPutImageReq);
   1278     swaps(&stuff->length);
   1279     swapl(&stuff->port);
   1280     swapl(&stuff->drawable);
   1281     swapl(&stuff->gc);
   1282     swapl(&stuff->shmseg);
   1283     swapl(&stuff->id);
   1284     swapl(&stuff->offset);
   1285     swaps(&stuff->src_x);
   1286     swaps(&stuff->src_y);
   1287     swaps(&stuff->src_w);
   1288     swaps(&stuff->src_h);
   1289     swaps(&stuff->drw_x);
   1290     swaps(&stuff->drw_y);
   1291     swaps(&stuff->drw_w);
   1292     swaps(&stuff->drw_h);
   1293     swaps(&stuff->width);
   1294     swaps(&stuff->height);
   1295     return XvProcVector[xv_ShmPutImage] (client);
   1296 }
   1297 #else                           /* MITSHM */
   1298 #define SProcXvShmPutImage ProcXvShmPutImage
   1299 #endif
   1300 
   1301 static int _X_COLD
   1302 SProcXvSelectVideoNotify(ClientPtr client)
   1303 {
   1304     REQUEST(xvSelectVideoNotifyReq);
   1305     REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
   1306     swaps(&stuff->length);
   1307     swapl(&stuff->drawable);
   1308     return XvProcVector[xv_SelectVideoNotify] (client);
   1309 }
   1310 
   1311 static int _X_COLD
   1312 SProcXvSelectPortNotify(ClientPtr client)
   1313 {
   1314     REQUEST(xvSelectPortNotifyReq);
   1315     REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
   1316     swaps(&stuff->length);
   1317     swapl(&stuff->port);
   1318     return XvProcVector[xv_SelectPortNotify] (client);
   1319 }
   1320 
   1321 static int _X_COLD
   1322 SProcXvStopVideo(ClientPtr client)
   1323 {
   1324     REQUEST(xvStopVideoReq);
   1325     REQUEST_SIZE_MATCH(xvStopVideoReq);
   1326     swaps(&stuff->length);
   1327     swapl(&stuff->port);
   1328     swapl(&stuff->drawable);
   1329     return XvProcVector[xv_StopVideo] (client);
   1330 }
   1331 
   1332 static int _X_COLD
   1333 SProcXvSetPortAttribute(ClientPtr client)
   1334 {
   1335     REQUEST(xvSetPortAttributeReq);
   1336     REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
   1337     swaps(&stuff->length);
   1338     swapl(&stuff->port);
   1339     swapl(&stuff->attribute);
   1340     swapl(&stuff->value);
   1341     return XvProcVector[xv_SetPortAttribute] (client);
   1342 }
   1343 
   1344 static int _X_COLD
   1345 SProcXvGetPortAttribute(ClientPtr client)
   1346 {
   1347     REQUEST(xvGetPortAttributeReq);
   1348     REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
   1349     swaps(&stuff->length);
   1350     swapl(&stuff->port);
   1351     swapl(&stuff->attribute);
   1352     return XvProcVector[xv_GetPortAttribute] (client);
   1353 }
   1354 
   1355 static int _X_COLD
   1356 SProcXvQueryBestSize(ClientPtr client)
   1357 {
   1358     REQUEST(xvQueryBestSizeReq);
   1359     REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
   1360     swaps(&stuff->length);
   1361     swapl(&stuff->port);
   1362     swaps(&stuff->vid_w);
   1363     swaps(&stuff->vid_h);
   1364     swaps(&stuff->drw_w);
   1365     swaps(&stuff->drw_h);
   1366     return XvProcVector[xv_QueryBestSize] (client);
   1367 }
   1368 
   1369 static int _X_COLD
   1370 SProcXvQueryPortAttributes(ClientPtr client)
   1371 {
   1372     REQUEST(xvQueryPortAttributesReq);
   1373     REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
   1374     swaps(&stuff->length);
   1375     swapl(&stuff->port);
   1376     return XvProcVector[xv_QueryPortAttributes] (client);
   1377 }
   1378 
   1379 static int _X_COLD
   1380 SProcXvQueryImageAttributes(ClientPtr client)
   1381 {
   1382     REQUEST(xvQueryImageAttributesReq);
   1383     REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
   1384     swaps(&stuff->length);
   1385     swapl(&stuff->port);
   1386     swapl(&stuff->id);
   1387     swaps(&stuff->width);
   1388     swaps(&stuff->height);
   1389     return XvProcVector[xv_QueryImageAttributes] (client);
   1390 }
   1391 
   1392 static int _X_COLD
   1393 SProcXvListImageFormats(ClientPtr client)
   1394 {
   1395     REQUEST(xvListImageFormatsReq);
   1396     REQUEST_SIZE_MATCH(xvListImageFormatsReq);
   1397     swaps(&stuff->length);
   1398     swapl(&stuff->port);
   1399     return XvProcVector[xv_ListImageFormats] (client);
   1400 }
   1401 
   1402 static int (*SXvProcVector[xvNumRequests]) (ClientPtr) = {
   1403 SProcXvQueryExtension,
   1404         SProcXvQueryAdaptors,
   1405         SProcXvQueryEncodings,
   1406         SProcXvGrabPort,
   1407         SProcXvUngrabPort,
   1408         SProcXvPutVideo,
   1409         SProcXvPutStill,
   1410         SProcXvGetVideo,
   1411         SProcXvGetStill,
   1412         SProcXvStopVideo,
   1413         SProcXvSelectVideoNotify,
   1414         SProcXvSelectPortNotify,
   1415         SProcXvQueryBestSize,
   1416         SProcXvSetPortAttribute,
   1417         SProcXvGetPortAttribute,
   1418         SProcXvQueryPortAttributes,
   1419         SProcXvListImageFormats,
   1420         SProcXvQueryImageAttributes, SProcXvPutImage, SProcXvShmPutImage,};
   1421 
   1422 int _X_COLD
   1423 SProcXvDispatch(ClientPtr client)
   1424 {
   1425     REQUEST(xReq);
   1426 
   1427     UpdateCurrentTime();
   1428 
   1429     if (stuff->data >= xvNumRequests) {
   1430         return BadRequest;
   1431     }
   1432 
   1433     return SXvProcVector[stuff->data] (client);
   1434 }
   1435 
   1436 #ifdef PANORAMIX
   1437 static int
   1438 XineramaXvStopVideo(ClientPtr client)
   1439 {
   1440     int result, i;
   1441     PanoramiXRes *draw, *port;
   1442 
   1443     REQUEST(xvStopVideoReq);
   1444     REQUEST_SIZE_MATCH(xvStopVideoReq);
   1445 
   1446     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
   1447                                       XRC_DRAWABLE, client, DixWriteAccess);
   1448     if (result != Success)
   1449         return (result == BadValue) ? BadDrawable : result;
   1450 
   1451     result = dixLookupResourceByType((void **) &port, stuff->port,
   1452                                      XvXRTPort, client, DixReadAccess);
   1453     if (result != Success)
   1454         return result;
   1455 
   1456     FOR_NSCREENS_BACKWARD(i) {
   1457         if (port->info[i].id) {
   1458             stuff->drawable = draw->info[i].id;
   1459             stuff->port = port->info[i].id;
   1460             result = ProcXvStopVideo(client);
   1461         }
   1462     }
   1463 
   1464     return result;
   1465 }
   1466 
   1467 static int
   1468 XineramaXvSetPortAttribute(ClientPtr client)
   1469 {
   1470     REQUEST(xvSetPortAttributeReq);
   1471     PanoramiXRes *port;
   1472     int result, i;
   1473 
   1474     REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
   1475 
   1476     result = dixLookupResourceByType((void **) &port, stuff->port,
   1477                                      XvXRTPort, client, DixReadAccess);
   1478     if (result != Success)
   1479         return result;
   1480 
   1481     FOR_NSCREENS_BACKWARD(i) {
   1482         if (port->info[i].id) {
   1483             stuff->port = port->info[i].id;
   1484             result = ProcXvSetPortAttribute(client);
   1485         }
   1486     }
   1487     return result;
   1488 }
   1489 
   1490 #ifdef MITSHM
   1491 static int
   1492 XineramaXvShmPutImage(ClientPtr client)
   1493 {
   1494     REQUEST(xvShmPutImageReq);
   1495     PanoramiXRes *draw, *gc, *port;
   1496     Bool send_event;
   1497     Bool isRoot;
   1498     int result, i, x, y;
   1499 
   1500     REQUEST_SIZE_MATCH(xvShmPutImageReq);
   1501 
   1502     send_event = stuff->send_event;
   1503 
   1504     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
   1505                                       XRC_DRAWABLE, client, DixWriteAccess);
   1506     if (result != Success)
   1507         return (result == BadValue) ? BadDrawable : result;
   1508 
   1509     result = dixLookupResourceByType((void **) &gc, stuff->gc,
   1510                                      XRT_GC, client, DixReadAccess);
   1511     if (result != Success)
   1512         return result;
   1513 
   1514     result = dixLookupResourceByType((void **) &port, stuff->port,
   1515                                      XvXRTPort, client, DixReadAccess);
   1516     if (result != Success)
   1517         return result;
   1518 
   1519     isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
   1520 
   1521     x = stuff->drw_x;
   1522     y = stuff->drw_y;
   1523 
   1524     FOR_NSCREENS_BACKWARD(i) {
   1525         if (port->info[i].id) {
   1526             stuff->drawable = draw->info[i].id;
   1527             stuff->port = port->info[i].id;
   1528             stuff->gc = gc->info[i].id;
   1529             stuff->drw_x = x;
   1530             stuff->drw_y = y;
   1531             if (isRoot) {
   1532                 stuff->drw_x -= screenInfo.screens[i]->x;
   1533                 stuff->drw_y -= screenInfo.screens[i]->y;
   1534             }
   1535             stuff->send_event = (send_event && !i) ? 1 : 0;
   1536 
   1537             result = ProcXvShmPutImage(client);
   1538         }
   1539     }
   1540     return result;
   1541 }
   1542 #else
   1543 #define XineramaXvShmPutImage ProcXvShmPutImage
   1544 #endif
   1545 
   1546 static int
   1547 XineramaXvPutImage(ClientPtr client)
   1548 {
   1549     REQUEST(xvPutImageReq);
   1550     PanoramiXRes *draw, *gc, *port;
   1551     Bool isRoot;
   1552     int result, i, x, y;
   1553 
   1554     REQUEST_AT_LEAST_SIZE(xvPutImageReq);
   1555 
   1556     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
   1557                                       XRC_DRAWABLE, client, DixWriteAccess);
   1558     if (result != Success)
   1559         return (result == BadValue) ? BadDrawable : result;
   1560 
   1561     result = dixLookupResourceByType((void **) &gc, stuff->gc,
   1562                                      XRT_GC, client, DixReadAccess);
   1563     if (result != Success)
   1564         return result;
   1565 
   1566     result = dixLookupResourceByType((void **) &port, stuff->port,
   1567                                      XvXRTPort, client, DixReadAccess);
   1568     if (result != Success)
   1569         return result;
   1570 
   1571     isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
   1572 
   1573     x = stuff->drw_x;
   1574     y = stuff->drw_y;
   1575 
   1576     FOR_NSCREENS_BACKWARD(i) {
   1577         if (port->info[i].id) {
   1578             stuff->drawable = draw->info[i].id;
   1579             stuff->port = port->info[i].id;
   1580             stuff->gc = gc->info[i].id;
   1581             stuff->drw_x = x;
   1582             stuff->drw_y = y;
   1583             if (isRoot) {
   1584                 stuff->drw_x -= screenInfo.screens[i]->x;
   1585                 stuff->drw_y -= screenInfo.screens[i]->y;
   1586             }
   1587 
   1588             result = ProcXvPutImage(client);
   1589         }
   1590     }
   1591     return result;
   1592 }
   1593 
   1594 static int
   1595 XineramaXvPutVideo(ClientPtr client)
   1596 {
   1597     REQUEST(xvPutImageReq);
   1598     PanoramiXRes *draw, *gc, *port;
   1599     Bool isRoot;
   1600     int result, i, x, y;
   1601 
   1602     REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
   1603 
   1604     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
   1605                                       XRC_DRAWABLE, client, DixWriteAccess);
   1606     if (result != Success)
   1607         return (result == BadValue) ? BadDrawable : result;
   1608 
   1609     result = dixLookupResourceByType((void **) &gc, stuff->gc,
   1610                                      XRT_GC, client, DixReadAccess);
   1611     if (result != Success)
   1612         return result;
   1613 
   1614     result = dixLookupResourceByType((void **) &port, stuff->port,
   1615                                      XvXRTPort, client, DixReadAccess);
   1616     if (result != Success)
   1617         return result;
   1618 
   1619     isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
   1620 
   1621     x = stuff->drw_x;
   1622     y = stuff->drw_y;
   1623 
   1624     FOR_NSCREENS_BACKWARD(i) {
   1625         if (port->info[i].id) {
   1626             stuff->drawable = draw->info[i].id;
   1627             stuff->port = port->info[i].id;
   1628             stuff->gc = gc->info[i].id;
   1629             stuff->drw_x = x;
   1630             stuff->drw_y = y;
   1631             if (isRoot) {
   1632                 stuff->drw_x -= screenInfo.screens[i]->x;
   1633                 stuff->drw_y -= screenInfo.screens[i]->y;
   1634             }
   1635 
   1636             result = ProcXvPutVideo(client);
   1637         }
   1638     }
   1639     return result;
   1640 }
   1641 
   1642 static int
   1643 XineramaXvPutStill(ClientPtr client)
   1644 {
   1645     REQUEST(xvPutImageReq);
   1646     PanoramiXRes *draw, *gc, *port;
   1647     Bool isRoot;
   1648     int result, i, x, y;
   1649 
   1650     REQUEST_AT_LEAST_SIZE(xvPutImageReq);
   1651 
   1652     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
   1653                                       XRC_DRAWABLE, client, DixWriteAccess);
   1654     if (result != Success)
   1655         return (result == BadValue) ? BadDrawable : result;
   1656 
   1657     result = dixLookupResourceByType((void **) &gc, stuff->gc,
   1658                                      XRT_GC, client, DixReadAccess);
   1659     if (result != Success)
   1660         return result;
   1661 
   1662     result = dixLookupResourceByType((void **) &port, stuff->port,
   1663                                      XvXRTPort, client, DixReadAccess);
   1664     if (result != Success)
   1665         return result;
   1666 
   1667     isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
   1668 
   1669     x = stuff->drw_x;
   1670     y = stuff->drw_y;
   1671 
   1672     FOR_NSCREENS_BACKWARD(i) {
   1673         if (port->info[i].id) {
   1674             stuff->drawable = draw->info[i].id;
   1675             stuff->port = port->info[i].id;
   1676             stuff->gc = gc->info[i].id;
   1677             stuff->drw_x = x;
   1678             stuff->drw_y = y;
   1679             if (isRoot) {
   1680                 stuff->drw_x -= screenInfo.screens[i]->x;
   1681                 stuff->drw_y -= screenInfo.screens[i]->y;
   1682             }
   1683 
   1684             result = ProcXvPutStill(client);
   1685         }
   1686     }
   1687     return result;
   1688 }
   1689 
   1690 static Bool
   1691 isImageAdaptor(XvAdaptorPtr pAdapt)
   1692 {
   1693     return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0);
   1694 }
   1695 
   1696 static Bool
   1697 hasOverlay(XvAdaptorPtr pAdapt)
   1698 {
   1699     int i;
   1700 
   1701     for (i = 0; i < pAdapt->nAttributes; i++)
   1702         if (!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY"))
   1703             return TRUE;
   1704     return FALSE;
   1705 }
   1706 
   1707 static XvAdaptorPtr
   1708 matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay)
   1709 {
   1710     int i;
   1711     XvScreenPtr xvsp =
   1712         dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey());
   1713     /* Do not try to go on if xv is not supported on this screen */
   1714     if (xvsp == NULL)
   1715         return NULL;
   1716 
   1717     /* if the adaptor has the same name it's a perfect match */
   1718     for (i = 0; i < xvsp->nAdaptors; i++) {
   1719         XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
   1720 
   1721         if (!strcmp(refAdapt->name, pAdapt->name))
   1722             return pAdapt;
   1723     }
   1724 
   1725     /* otherwise we only look for XvImage adaptors */
   1726     if (!isImageAdaptor(refAdapt))
   1727         return NULL;
   1728 
   1729     /* prefer overlay/overlay non-overlay/non-overlay pairing */
   1730     for (i = 0; i < xvsp->nAdaptors; i++) {
   1731         XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
   1732 
   1733         if (isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt))
   1734             return pAdapt;
   1735     }
   1736 
   1737     /* but we'll take any XvImage pairing if we can get it */
   1738     for (i = 0; i < xvsp->nAdaptors; i++) {
   1739         XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
   1740 
   1741         if (isImageAdaptor(pAdapt))
   1742             return pAdapt;
   1743     }
   1744     return NULL;
   1745 }
   1746 
   1747 void
   1748 XineramifyXv(void)
   1749 {
   1750     XvScreenPtr xvsp0 =
   1751         dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey());
   1752     XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
   1753     int i, j, k;
   1754 
   1755     XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
   1756 
   1757     if (!xvsp0 || !XvXRTPort)
   1758         return;
   1759     SetResourceTypeErrorValue(XvXRTPort, _XvBadPort);
   1760 
   1761     for (i = 0; i < xvsp0->nAdaptors; i++) {
   1762         Bool isOverlay;
   1763         XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
   1764 
   1765         if (!(refAdapt->type & XvInputMask))
   1766             continue;
   1767 
   1768         MatchingAdaptors[0] = refAdapt;
   1769         isOverlay = hasOverlay(refAdapt);
   1770         FOR_NSCREENS_FORWARD_SKIP(j)
   1771             MatchingAdaptors[j] =
   1772             matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay);
   1773 
   1774         /* now create a resource for each port */
   1775         for (j = 0; j < refAdapt->nPorts; j++) {
   1776             PanoramiXRes *port = malloc(sizeof(PanoramiXRes));
   1777 
   1778             if (!port)
   1779                 break;
   1780 
   1781             FOR_NSCREENS(k) {
   1782                 if (MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j))
   1783                     port->info[k].id = MatchingAdaptors[k]->base_id + j;
   1784                 else
   1785                     port->info[k].id = 0;
   1786             }
   1787             AddResource(port->info[0].id, XvXRTPort, port);
   1788         }
   1789     }
   1790 
   1791     /* munge the dispatch vector */
   1792     XvProcVector[xv_PutVideo] = XineramaXvPutVideo;
   1793     XvProcVector[xv_PutStill] = XineramaXvPutStill;
   1794     XvProcVector[xv_StopVideo] = XineramaXvStopVideo;
   1795     XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute;
   1796     XvProcVector[xv_PutImage] = XineramaXvPutImage;
   1797     XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage;
   1798 }
   1799 #endif                          /* PANORAMIX */
   1800 
   1801 void
   1802 XvResetProcVector(void)
   1803 {
   1804 #ifdef PANORAMIX
   1805     XvProcVector[xv_PutVideo] = ProcXvPutVideo;
   1806     XvProcVector[xv_PutStill] = ProcXvPutStill;
   1807     XvProcVector[xv_StopVideo] = ProcXvStopVideo;
   1808     XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute;
   1809     XvProcVector[xv_PutImage] = ProcXvPutImage;
   1810     XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage;
   1811 #endif
   1812 }