Home | History | Annotate | Download | only in Xv
      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 /* $XFree86: xc/lib/Xv/Xv.c,v 1.15 2001/05/11 08:23:22 alanh Exp $ */
     25 /*
     26 ** File:
     27 **
     28 **   Xv.c --- Xv library extension module.
     29 **
     30 ** Author:
     31 **
     32 **   David Carver (Digital Workstation Engineering/Project Athena)
     33 **
     34 ** Revisions:
     35 **
     36 **   26.06.91 Carver
     37 **     - changed XvFreeAdaptors to XvFreeAdaptorInfo
     38 **     - changed XvFreeEncodings to XvFreeEncodingInfo
     39 **
     40 **   11.06.91 Carver
     41 **     - changed SetPortControl to SetPortAttribute
     42 **     - changed GetPortControl to GetPortAttribute
     43 **     - changed QueryBestSize
     44 **
     45 **   15.05.91 Carver
     46 **     - version 2.0 upgrade
     47 **
     48 **   240.01.91 Carver
     49 **     - version 1.4 upgrade
     50 **
     51 */
     52 
     53 #include <stdio.h>
     54 #include "Xvlibint.h"
     55 #include "../extensions/Xext.h"
     56 #include <X11/extensions/XShm.h>
     57 #include "../extensions/extutil.h"
     58 
     59 static XExtensionInfo _xv_info_data;
     60 static XExtensionInfo *xv_info = &_xv_info_data;
     61 static char *xv_extension_name = XvName;
     62 
     63 #define XvCheckExtension(dpy, i, val) \
     64   XextCheckExtension(dpy, i, xv_extension_name, val)
     65 
     66 static char *xv_error_string();
     67 static int xv_close_display();
     68 static Bool xv_wire_to_event();
     69 
     70 static XExtensionHooks xv_extension_hooks = {
     71     NULL,                               /* create_gc */
     72     NULL,                               /* copy_gc */
     73     NULL,                               /* flush_gc */
     74     NULL,                               /* free_gc */
     75     NULL,                               /* create_font */
     76     NULL,                               /* free_font */
     77     xv_close_display,                   /* close_display */
     78     xv_wire_to_event,                   /* wire_to_event */
     79     NULL,                               /* event_to_wire */
     80     NULL,                               /* error */
     81     xv_error_string                     /* error_string */
     82 };
     83 
     84 
     85 static char *xv_error_list[] =
     86 {
     87    "BadPort",	    /* XvBadPort     */
     88    "BadEncoding",   /* XvBadEncoding */
     89    "BadControl"     /* XvBadControl  */
     90 };
     91 
     92 static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
     93 
     94 
     95 static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
     96                                    xv_extension_name,
     97                                    &xv_extension_hooks,
     98 				   XvNumEvents, NULL)
     99 
    100 
    101 static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
    102                                    XvNumErrors, xv_error_list)
    103 
    104 
    105 int
    106 SDL_NAME(XvQueryExtension)(
    107      Display *dpy,
    108      unsigned int *p_version,
    109      unsigned int *p_revision,
    110      unsigned int *p_requestBase,
    111      unsigned int *p_eventBase,
    112      unsigned int *p_errorBase
    113 ){
    114   XExtDisplayInfo *info = xv_find_display(dpy);
    115   xvQueryExtensionReq *req;
    116   xvQueryExtensionReply rep;
    117 
    118   XvCheckExtension(dpy, info, XvBadExtension);
    119 
    120   LockDisplay(dpy);
    121 
    122   XvGetReq(QueryExtension, req);
    123 
    124   if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    125      UnlockDisplay(dpy);
    126      SyncHandle();
    127      return XvBadExtension;
    128   }
    129 
    130   *p_version = rep.version;
    131   *p_revision = rep.revision;
    132   *p_requestBase = info->codes->major_opcode;
    133   *p_eventBase = info->codes->first_event;
    134   *p_errorBase = info->codes->first_error;
    135 
    136   UnlockDisplay(dpy);
    137   SyncHandle();
    138 
    139   return Success;
    140 }
    141 
    142 int
    143 SDL_NAME(XvQueryAdaptors)(
    144      Display *dpy,
    145      Window window,
    146      unsigned int *p_nAdaptors,
    147      SDL_NAME(XvAdaptorInfo) **p_pAdaptors
    148 ){
    149   XExtDisplayInfo *info = xv_find_display(dpy);
    150   xvQueryAdaptorsReq *req;
    151   xvQueryAdaptorsReply rep;
    152   int size,ii,jj;
    153   char *name;
    154   SDL_NAME(XvAdaptorInfo) *pas, *pa;
    155   SDL_NAME(XvFormat) *pfs, *pf;
    156   char *buffer;
    157   union
    158     {
    159       char *buffer;
    160       char *string;
    161       xvAdaptorInfo *pa;
    162       xvFormat *pf;
    163     } u;
    164 
    165   XvCheckExtension(dpy, info, XvBadExtension);
    166 
    167   LockDisplay(dpy);
    168 
    169   XvGetReq(QueryAdaptors, req);
    170   req->window = window;
    171 
    172   /* READ THE REPLY */
    173 
    174   if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
    175       UnlockDisplay(dpy);
    176       SyncHandle();
    177       return(XvBadReply);
    178   }
    179 
    180   size = rep.length << 2;
    181   if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
    182       UnlockDisplay(dpy);
    183       SyncHandle();
    184       return(XvBadAlloc);
    185   }
    186   _XRead (dpy, buffer, size);
    187 
    188   u.buffer = buffer;
    189 
    190   /* GET INPUT ADAPTORS */
    191 
    192   if (rep.num_adaptors == 0) {
    193       pas = NULL;
    194   } else {
    195       size = rep.num_adaptors*sizeof(SDL_NAME(XvAdaptorInfo));
    196       if ((pas=(SDL_NAME(XvAdaptorInfo) *)Xmalloc(size))==NULL) {
    197           Xfree(buffer);
    198           UnlockDisplay(dpy);
    199           SyncHandle();
    200           return(XvBadAlloc);
    201       }
    202   }
    203 
    204   /* INIT ADAPTOR FIELDS */
    205 
    206   pa = pas;
    207   for (ii=0; ii<rep.num_adaptors; ii++) {
    208       pa->num_adaptors = 0;
    209       pa->name = (char *)NULL;
    210       pa->formats = (SDL_NAME(XvFormat) *)NULL;
    211       pa++;
    212   }
    213 
    214   pa = pas;
    215   for (ii=0; ii<rep.num_adaptors; ii++) {
    216       pa->type = u.pa->type;
    217       pa->base_id = u.pa->base_id;
    218       pa->num_ports = u.pa->num_ports;
    219       pa->num_formats = u.pa->num_formats;
    220       pa->num_adaptors = rep.num_adaptors - ii;
    221 
    222       /* GET ADAPTOR NAME */
    223 
    224       size = u.pa->name_size;
    225       u.buffer += (sz_xvAdaptorInfo + 3) & ~3;
    226 
    227       if ( (name = (char *)Xmalloc(size+1)) == NULL)
    228 	{
    229 	  SDL_NAME(XvFreeAdaptorInfo)(pas);
    230 	  Xfree(buffer);
    231           UnlockDisplay(dpy);
    232           SyncHandle();
    233 	  return(XvBadAlloc);
    234 	}
    235       SDL_strlcpy(name, u.string, size);
    236       pa->name = name;
    237 
    238       u.buffer += (size + 3) & ~3;
    239 
    240       /* GET FORMATS */
    241 
    242       size = pa->num_formats*sizeof(SDL_NAME(XvFormat));
    243       if ((pfs=(SDL_NAME(XvFormat) *)Xmalloc(size))==NULL) {
    244 	  SDL_NAME(XvFreeAdaptorInfo)(pas);
    245 	  Xfree(buffer);
    246           UnlockDisplay(dpy);
    247           SyncHandle();
    248 	  return(XvBadAlloc);
    249       }
    250 
    251       pf = pfs;
    252       for (jj=0; jj<pa->num_formats; jj++) {
    253 	  pf->depth = u.pf->depth;
    254 	  pf->visual_id = u.pf->visual;
    255 	  pf++;
    256 
    257 	  u.buffer += (sz_xvFormat + 3) & ~3;
    258       }
    259 
    260       pa->formats = pfs;
    261 
    262       pa++;
    263 
    264   }
    265 
    266   *p_nAdaptors = rep.num_adaptors;
    267   *p_pAdaptors = pas;
    268 
    269   Xfree(buffer);
    270   UnlockDisplay(dpy);
    271   SyncHandle();
    272 
    273   return (Success);
    274 }
    275 
    276 
    277 void
    278 SDL_NAME(XvFreeAdaptorInfo)(SDL_NAME(XvAdaptorInfo) *pAdaptors)
    279 {
    280 
    281   SDL_NAME(XvAdaptorInfo) *pa;
    282   int ii;
    283 
    284   if (!pAdaptors) return;
    285 
    286   pa = pAdaptors;
    287 
    288   for (ii=0; ii<pAdaptors->num_adaptors; ii++, pa++)
    289     {
    290       if (pa->name)
    291 	{
    292 	  Xfree(pa->name);
    293 	}
    294       if (pa->formats)
    295 	{
    296 	  Xfree(pa->formats);
    297 	}
    298     }
    299 
    300   Xfree(pAdaptors);
    301 }
    302 
    303 int
    304 SDL_NAME(XvQueryEncodings)(
    305      Display *dpy,
    306      XvPortID port,
    307      unsigned int *p_nEncodings,
    308      SDL_NAME(XvEncodingInfo) **p_pEncodings
    309 ){
    310   XExtDisplayInfo *info = xv_find_display(dpy);
    311   xvQueryEncodingsReq *req;
    312   xvQueryEncodingsReply rep;
    313   int size, jj;
    314   char *name;
    315   SDL_NAME(XvEncodingInfo) *pes, *pe;
    316   char *buffer;
    317   union
    318     {
    319       char *buffer;
    320       char *string;
    321       xvEncodingInfo *pe;
    322     } u;
    323 
    324   XvCheckExtension(dpy, info, XvBadExtension);
    325 
    326   LockDisplay(dpy);
    327 
    328   XvGetReq(QueryEncodings, req);
    329   req->port = port;
    330 
    331   /* READ THE REPLY */
    332 
    333   if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
    334       UnlockDisplay(dpy);
    335       SyncHandle();
    336       return(XvBadReply);
    337   }
    338 
    339   size = rep.length << 2;
    340   if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
    341       UnlockDisplay(dpy);
    342       SyncHandle();
    343       return(XvBadAlloc);
    344   }
    345   _XRead (dpy, buffer, size);
    346 
    347   u.buffer = buffer;
    348 
    349   /* GET ENCODINGS */
    350 
    351   size = rep.num_encodings*sizeof(SDL_NAME(XvEncodingInfo));
    352   if ( (pes = (SDL_NAME(XvEncodingInfo) *)Xmalloc(size)) == NULL) {
    353       Xfree(buffer);
    354       UnlockDisplay(dpy);
    355       SyncHandle();
    356       return(XvBadAlloc);
    357   }
    358 
    359   /* INITIALIZE THE ENCODING POINTER */
    360 
    361   pe = pes;
    362   for (jj=0; jj<rep.num_encodings; jj++) {
    363       pe->name = (char *)NULL;
    364       pe->num_encodings = 0;
    365       pe++;
    366   }
    367 
    368   pe = pes;
    369   for (jj=0; jj<rep.num_encodings; jj++) {
    370       pe->encoding_id = u.pe->encoding;
    371       pe->width = u.pe->width;
    372       pe->height = u.pe->height;
    373       pe->rate.numerator = u.pe->rate.numerator;
    374       pe->rate.denominator = u.pe->rate.denominator;
    375       pe->num_encodings = rep.num_encodings - jj;
    376 
    377       size = u.pe->name_size;
    378       u.buffer += (sz_xvEncodingInfo + 3) & ~3;
    379 
    380       if ( (name = (char *)Xmalloc(size+1)) == NULL) {
    381 	  Xfree(buffer);
    382           UnlockDisplay(dpy);
    383           SyncHandle();
    384 	  return(XvBadAlloc);
    385       }
    386       SDL_strlcpy(name, u.string, size);
    387       pe->name = name;
    388       pe++;
    389 
    390       u.buffer += (size + 3) & ~3;
    391   }
    392 
    393   *p_nEncodings = rep.num_encodings;
    394   *p_pEncodings = pes;
    395 
    396   Xfree(buffer);
    397   UnlockDisplay(dpy);
    398   SyncHandle();
    399 
    400   return (Success);
    401 }
    402 
    403 void
    404 SDL_NAME(XvFreeEncodingInfo)(SDL_NAME(XvEncodingInfo) *pEncodings)
    405 {
    406 
    407   SDL_NAME(XvEncodingInfo) *pe;
    408   int ii;
    409 
    410   if (!pEncodings) return;
    411 
    412   pe = pEncodings;
    413 
    414   for (ii=0; ii<pEncodings->num_encodings; ii++, pe++) {
    415       if (pe->name) Xfree(pe->name);
    416   }
    417 
    418   Xfree(pEncodings);
    419 }
    420 
    421 int
    422 SDL_NAME(XvPutVideo)(
    423      Display *dpy,
    424      XvPortID port,
    425      Drawable d,
    426      GC gc,
    427      int vx, int vy,
    428      unsigned int vw, unsigned int vh,
    429      int dx, int dy,
    430      unsigned int dw, unsigned int dh
    431 ){
    432   XExtDisplayInfo *info = xv_find_display(dpy);
    433   xvPutVideoReq *req;
    434 
    435   XvCheckExtension(dpy, info, XvBadExtension);
    436 
    437   LockDisplay(dpy);
    438 
    439   FlushGC(dpy, gc);
    440 
    441   XvGetReq(PutVideo, req);
    442 
    443   req->port = port;
    444   req->drawable = d;
    445   req->gc = gc->gid;
    446   req->vid_x = vx;
    447   req->vid_y = vy;
    448   req->vid_w = vw;
    449   req->vid_h = vh;
    450   req->drw_x = dx;
    451   req->drw_y = dy;
    452   req->drw_w = dw;
    453   req->drw_h = dh;
    454 
    455   UnlockDisplay(dpy);
    456   SyncHandle();
    457 
    458   return Success;
    459 }
    460 
    461 int
    462 SDL_NAME(XvPutStill)(
    463      Display *dpy,
    464      XvPortID port,
    465      Drawable d,
    466      GC gc,
    467      int vx, int vy,
    468      unsigned int vw, unsigned int vh,
    469      int dx, int dy,
    470      unsigned int dw, unsigned int dh
    471 ){
    472   XExtDisplayInfo *info = xv_find_display(dpy);
    473   xvPutStillReq *req;
    474 
    475   XvCheckExtension(dpy, info, XvBadExtension);
    476 
    477   LockDisplay(dpy);
    478 
    479   FlushGC(dpy, gc);
    480 
    481   XvGetReq(PutStill, req);
    482   req->port = port;
    483   req->drawable = d;
    484   req->gc = gc->gid;
    485   req->vid_x = vx;
    486   req->vid_y = vy;
    487   req->vid_w = vw;
    488   req->vid_h = vh;
    489   req->drw_x = dx;
    490   req->drw_y = dy;
    491   req->drw_w = dw;
    492   req->drw_h = dh;
    493 
    494   UnlockDisplay(dpy);
    495   SyncHandle();
    496 
    497   return Success;
    498 }
    499 
    500 int
    501 SDL_NAME(XvGetVideo)(
    502      Display *dpy,
    503      XvPortID port,
    504      Drawable d,
    505      GC gc,
    506      int vx, int vy,
    507      unsigned int vw, unsigned int vh,
    508      int dx, int dy,
    509      unsigned int dw, unsigned int dh
    510 ){
    511   XExtDisplayInfo *info = xv_find_display(dpy);
    512   xvGetVideoReq *req;
    513 
    514   XvCheckExtension(dpy, info, XvBadExtension);
    515 
    516   LockDisplay(dpy);
    517 
    518   FlushGC(dpy, gc);
    519 
    520   XvGetReq(GetVideo, req);
    521   req->port = port;
    522   req->drawable = d;
    523   req->gc = gc->gid;
    524   req->vid_x = vx;
    525   req->vid_y = vy;
    526   req->vid_w = vw;
    527   req->vid_h = vh;
    528   req->drw_x = dx;
    529   req->drw_y = dy;
    530   req->drw_w = dw;
    531   req->drw_h = dh;
    532 
    533   UnlockDisplay(dpy);
    534   SyncHandle();
    535 
    536   return Success;
    537 }
    538 
    539 int
    540 SDL_NAME(XvGetStill)(
    541      Display *dpy,
    542      XvPortID port,
    543      Drawable d,
    544      GC gc,
    545      int vx, int vy,
    546      unsigned int vw, unsigned int vh,
    547      int dx, int dy,
    548      unsigned int dw, unsigned int dh
    549 ){
    550   XExtDisplayInfo *info = xv_find_display(dpy);
    551   xvGetStillReq *req;
    552 
    553   XvCheckExtension(dpy, info, XvBadExtension);
    554 
    555   LockDisplay(dpy);
    556 
    557   FlushGC(dpy, gc);
    558 
    559   XvGetReq(GetStill, req);
    560   req->port = port;
    561   req->drawable = d;
    562   req->gc = gc->gid;
    563   req->vid_x = vx;
    564   req->vid_y = vy;
    565   req->vid_w = vw;
    566   req->vid_h = vh;
    567   req->drw_x = dx;
    568   req->drw_y = dy;
    569   req->drw_w = dw;
    570   req->drw_h = dh;
    571 
    572   UnlockDisplay(dpy);
    573   SyncHandle();
    574 
    575   return Success;
    576 }
    577 
    578 int
    579 SDL_NAME(XvStopVideo)(
    580      Display *dpy,
    581      XvPortID port,
    582      Drawable draw
    583 ){
    584   XExtDisplayInfo *info = xv_find_display(dpy);
    585   xvStopVideoReq *req;
    586 
    587   XvCheckExtension(dpy, info, XvBadExtension);
    588 
    589   LockDisplay(dpy);
    590 
    591   XvGetReq(StopVideo, req);
    592   req->port = port;
    593   req->drawable = draw;
    594 
    595   UnlockDisplay(dpy);
    596   SyncHandle();
    597 
    598   return Success;
    599 }
    600 
    601 int
    602 SDL_NAME(XvGrabPort)(
    603      Display *dpy,
    604      XvPortID port,
    605      Time time
    606 ){
    607   XExtDisplayInfo *info = xv_find_display(dpy);
    608   int result;
    609   xvGrabPortReply rep;
    610   xvGrabPortReq *req;
    611 
    612   XvCheckExtension(dpy, info, XvBadExtension);
    613 
    614   LockDisplay(dpy);
    615 
    616   XvGetReq(GrabPort, req);
    617   req->port = port;
    618   req->time = time;
    619 
    620   if (_XReply (dpy, (xReply *) &rep, 0, xTrue) == 0)
    621     rep.result = GrabSuccess;
    622 
    623   result = rep.result;
    624 
    625   UnlockDisplay(dpy);
    626   SyncHandle();
    627 
    628   return result;
    629 }
    630 
    631 int
    632 SDL_NAME(XvUngrabPort)(
    633      Display *dpy,
    634      XvPortID port,
    635      Time time
    636 ){
    637   XExtDisplayInfo *info = xv_find_display(dpy);
    638   xvUngrabPortReq *req;
    639 
    640   XvCheckExtension(dpy, info, XvBadExtension);
    641 
    642   LockDisplay(dpy);
    643 
    644   XvGetReq(UngrabPort, req);
    645   req->port = port;
    646   req->time = time;
    647 
    648   UnlockDisplay(dpy);
    649   SyncHandle();
    650 
    651   return Success;
    652 }
    653 
    654 int
    655 SDL_NAME(XvSelectVideoNotify)(
    656      Display *dpy,
    657      Drawable drawable,
    658      Bool onoff
    659 ){
    660   XExtDisplayInfo *info = xv_find_display(dpy);
    661   xvSelectVideoNotifyReq *req;
    662 
    663   XvCheckExtension(dpy, info, XvBadExtension);
    664 
    665   LockDisplay(dpy);
    666 
    667   XvGetReq(SelectVideoNotify, req);
    668   req->drawable = drawable;
    669   req->onoff = onoff;
    670 
    671   UnlockDisplay(dpy);
    672   SyncHandle();
    673 
    674   return Success;
    675 }
    676 
    677 int
    678 SDL_NAME(XvSelectPortNotify)(
    679      Display *dpy,
    680      XvPortID port,
    681      Bool onoff
    682 ){
    683   XExtDisplayInfo *info = xv_find_display(dpy);
    684   xvSelectPortNotifyReq *req;
    685 
    686   XvCheckExtension(dpy, info, XvBadExtension);
    687 
    688   LockDisplay(dpy);
    689 
    690   XvGetReq(SelectPortNotify, req);
    691   req->port = port;
    692   req->onoff = onoff;
    693 
    694   UnlockDisplay(dpy);
    695   SyncHandle();
    696 
    697   return Success;
    698 }
    699 
    700 int
    701 SDL_NAME(XvSetPortAttribute) (
    702      Display *dpy,
    703      XvPortID port,
    704      Atom attribute,
    705      int value
    706 )
    707 {
    708   XExtDisplayInfo *info = xv_find_display(dpy);
    709   xvSetPortAttributeReq *req;
    710 
    711   XvCheckExtension(dpy, info, XvBadExtension);
    712 
    713   LockDisplay(dpy);
    714 
    715   XvGetReq(SetPortAttribute, req);
    716   req->port = port;
    717   req->attribute = attribute;
    718   req->value = value;
    719 
    720   UnlockDisplay(dpy);
    721   SyncHandle();
    722 
    723   return (Success);
    724 }
    725 
    726 int
    727 SDL_NAME(XvGetPortAttribute) (
    728      Display *dpy,
    729      XvPortID port,
    730      Atom attribute,
    731      int *p_value
    732 )
    733 {
    734   XExtDisplayInfo *info = xv_find_display(dpy);
    735   xvGetPortAttributeReq *req;
    736   xvGetPortAttributeReply rep;
    737 
    738   XvCheckExtension(dpy, info, XvBadExtension);
    739 
    740   LockDisplay(dpy);
    741 
    742   XvGetReq(GetPortAttribute, req);
    743   req->port = port;
    744   req->attribute = attribute;
    745 
    746   /* READ THE REPLY */
    747 
    748   if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
    749       UnlockDisplay(dpy);
    750       SyncHandle();
    751       return(XvBadReply);
    752   }
    753 
    754   *p_value = rep.value;
    755 
    756   UnlockDisplay(dpy);
    757   SyncHandle();
    758 
    759   return (Success);
    760 }
    761 
    762 int
    763 SDL_NAME(XvQueryBestSize)(
    764      Display *dpy,
    765      XvPortID port,
    766      Bool motion,
    767      unsigned int vid_w,
    768      unsigned int vid_h,
    769      unsigned int drw_w,
    770      unsigned int drw_h,
    771      unsigned int *p_actual_width,
    772      unsigned int *p_actual_height
    773 )
    774 {
    775   XExtDisplayInfo *info = xv_find_display(dpy);
    776   xvQueryBestSizeReq *req;
    777   xvQueryBestSizeReply rep;
    778 
    779   XvCheckExtension(dpy, info, XvBadExtension);
    780 
    781   LockDisplay(dpy);
    782 
    783   XvGetReq(QueryBestSize, req);
    784   req->port = port;
    785   req->motion = motion;
    786   req->vid_w = vid_w;
    787   req->vid_h = vid_h;
    788   req->drw_w = drw_w;
    789   req->drw_h = drw_h;
    790 
    791   /* READ THE REPLY */
    792 
    793   if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
    794       UnlockDisplay(dpy);
    795       SyncHandle();
    796       return(XvBadReply);
    797   }
    798 
    799   *p_actual_width = rep.actual_width;
    800   *p_actual_height = rep.actual_height;
    801 
    802   UnlockDisplay(dpy);
    803   SyncHandle();
    804 
    805   return (Success);
    806 }
    807 
    808 
    809 SDL_NAME(XvAttribute)*
    810 SDL_NAME(XvQueryPortAttributes)(Display *dpy, XvPortID port, int *num)
    811 {
    812   XExtDisplayInfo *info = xv_find_display(dpy);
    813   xvQueryPortAttributesReq *req;
    814   xvQueryPortAttributesReply rep;
    815   SDL_NAME(XvAttribute) *ret = NULL;
    816 
    817   *num = 0;
    818 
    819   XvCheckExtension(dpy, info, NULL);
    820 
    821   LockDisplay(dpy);
    822 
    823   XvGetReq(QueryPortAttributes, req);
    824   req->port = port;
    825 
    826   /* READ THE REPLY */
    827 
    828   if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
    829       UnlockDisplay(dpy);
    830       SyncHandle();
    831       return ret;
    832   }
    833 
    834   if(rep.num_attributes) {
    835       int size = (rep.num_attributes * sizeof(SDL_NAME(XvAttribute))) + rep.text_size;
    836 
    837       if((ret = Xmalloc(size))) {
    838 	  char* marker = (char*)(&ret[rep.num_attributes]);
    839 	  xvAttributeInfo Info;
    840 	  int i;
    841 
    842 	  for(i = 0; i < rep.num_attributes; i++) {
    843              _XRead(dpy, (char*)(&Info), sz_xvAttributeInfo);
    844 	      ret[i].flags = (int)Info.flags;
    845 	      ret[i].min_value = Info.min;
    846 	      ret[i].max_value = Info.max;
    847 	      ret[i].name = marker;
    848 	      _XRead(dpy, marker, Info.size);
    849 	      marker += Info.size;
    850 	      (*num)++;
    851 	  }
    852       } else
    853 	_XEatData(dpy, rep.length << 2);
    854   }
    855 
    856   UnlockDisplay(dpy);
    857   SyncHandle();
    858 
    859   return ret;
    860 }
    861 
    862 SDL_NAME(XvImageFormatValues) * SDL_NAME(XvListImageFormats) (
    863    Display 	*dpy,
    864    XvPortID 	port,
    865    int 		*num
    866 ){
    867   XExtDisplayInfo *info = xv_find_display(dpy);
    868   xvListImageFormatsReq *req;
    869   xvListImageFormatsReply rep;
    870   SDL_NAME(XvImageFormatValues) *ret = NULL;
    871 
    872   *num = 0;
    873 
    874   XvCheckExtension(dpy, info, NULL);
    875 
    876   LockDisplay(dpy);
    877 
    878   XvGetReq(ListImageFormats, req);
    879   req->port = port;
    880 
    881   /* READ THE REPLY */
    882 
    883   if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
    884       UnlockDisplay(dpy);
    885       SyncHandle();
    886       return NULL;
    887   }
    888 
    889   if(rep.num_formats) {
    890       int size = (rep.num_formats * sizeof(SDL_NAME(XvImageFormatValues)));
    891 
    892       if((ret = Xmalloc(size))) {
    893 	  xvImageFormatInfo Info;
    894 	  int i;
    895 
    896 	  for(i = 0; i < rep.num_formats; i++) {
    897               _XRead(dpy, (char*)(&Info), sz_xvImageFormatInfo);
    898 	      ret[i].id = Info.id;
    899 	      ret[i].type = Info.type;
    900 	      ret[i].byte_order = Info.byte_order;
    901 	      memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16);
    902 	      ret[i].bits_per_pixel = Info.bpp;
    903   	      ret[i].format = Info.format;
    904    	      ret[i].num_planes = Info.num_planes;
    905     	      ret[i].depth = Info.depth;
    906     	      ret[i].red_mask = Info.red_mask;
    907     	      ret[i].green_mask = Info.green_mask;
    908     	      ret[i].blue_mask = Info.blue_mask;
    909     	      ret[i].y_sample_bits = Info.y_sample_bits;
    910     	      ret[i].u_sample_bits = Info.u_sample_bits;
    911     	      ret[i].v_sample_bits = Info.v_sample_bits;
    912     	      ret[i].horz_y_period = Info.horz_y_period;
    913     	      ret[i].horz_u_period = Info.horz_u_period;
    914     	      ret[i].horz_v_period = Info.horz_v_period;
    915     	      ret[i].vert_y_period = Info.vert_y_period;
    916     	      ret[i].vert_u_period = Info.vert_u_period;
    917     	      ret[i].vert_v_period = Info.vert_v_period;
    918 	      memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32);
    919     	      ret[i].scanline_order = Info.scanline_order;
    920 	      (*num)++;
    921 	  }
    922       } else
    923 	_XEatData(dpy, rep.length << 2);
    924   }
    925 
    926   UnlockDisplay(dpy);
    927   SyncHandle();
    928 
    929   return ret;
    930 }
    931 
    932 SDL_NAME(XvImage) * SDL_NAME(XvCreateImage) (
    933    Display *dpy,
    934    XvPortID port,
    935    int id,
    936    char *data,
    937    int width,
    938    int height
    939 ) {
    940    XExtDisplayInfo *info = xv_find_display(dpy);
    941    xvQueryImageAttributesReq *req;
    942    xvQueryImageAttributesReply rep;
    943    SDL_NAME(XvImage) *ret = NULL;
    944 
    945    XvCheckExtension(dpy, info, NULL);
    946 
    947    LockDisplay(dpy);
    948 
    949    XvGetReq(QueryImageAttributes, req);
    950    req->id = id;
    951    req->port = port;
    952    req->width = width;
    953    req->height = height;
    954 
    955    /* READ THE REPLY */
    956 
    957    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    958        UnlockDisplay(dpy);
    959        SyncHandle();
    960       return NULL;
    961    }
    962 
    963    if((ret = (SDL_NAME(XvImage)*)Xmalloc(sizeof(SDL_NAME(XvImage)) + (rep.num_planes << 3)))) {
    964 	ret->id = id;
    965 	ret->width = rep.width;
    966 	ret->height = rep.height;
    967 	ret->data_size = rep.data_size;
    968 	ret->num_planes = rep.num_planes;
    969 	ret->pitches = (int*)(&ret[1]);
    970 	ret->offsets = ret->pitches + rep.num_planes;
    971 	ret->data = data;
    972 	ret->obdata = NULL;
    973   	_XRead(dpy, (char*)(ret->pitches), rep.num_planes << 2);
    974 	_XRead(dpy, (char*)(ret->offsets), rep.num_planes << 2);
    975    } else
    976 	_XEatData(dpy, rep.length << 2);
    977 
    978    UnlockDisplay(dpy);
    979    SyncHandle();
    980    return ret;
    981 }
    982 
    983 SDL_NAME(XvImage) * SDL_NAME(XvShmCreateImage) (
    984    Display *dpy,
    985    XvPortID port,
    986    int id,
    987    char *data,
    988    int width,
    989    int height,
    990    XShmSegmentInfo *shminfo
    991 ){
    992    SDL_NAME(XvImage) *ret;
    993 
    994    ret = SDL_NAME(XvCreateImage)(dpy, port, id, data, width, height);
    995 
    996    if(ret) ret->obdata = (XPointer)shminfo;
    997 
    998    return ret;
    999 }
   1000 
   1001 int SDL_NAME(XvPutImage) (
   1002    Display *dpy,
   1003    XvPortID port,
   1004    Drawable d,
   1005    GC gc,
   1006    SDL_NAME(XvImage) *image,
   1007    int src_x,
   1008    int src_y,
   1009    unsigned int src_w,
   1010    unsigned int src_h,
   1011    int dest_x,
   1012    int dest_y,
   1013    unsigned int dest_w,
   1014    unsigned int dest_h
   1015 ){
   1016   XExtDisplayInfo *info = xv_find_display(dpy);
   1017   xvPutImageReq *req;
   1018   int len;
   1019 
   1020   XvCheckExtension(dpy, info, XvBadExtension);
   1021 
   1022   LockDisplay(dpy);
   1023 
   1024   FlushGC(dpy, gc);
   1025 
   1026   XvGetReq(PutImage, req);
   1027 
   1028   req->port = port;
   1029   req->drawable = d;
   1030   req->gc = gc->gid;
   1031   req->id = image->id;
   1032   req->src_x = src_x;
   1033   req->src_y = src_y;
   1034   req->src_w = src_w;
   1035   req->src_h = src_h;
   1036   req->drw_x = dest_x;
   1037   req->drw_y = dest_y;
   1038   req->drw_w = dest_w;
   1039   req->drw_h = dest_h;
   1040   req->width = image->width;
   1041   req->height = image->height;
   1042 
   1043   len = (image->data_size + 3) >> 2;
   1044   SetReqLen(req, len, len);
   1045 
   1046   /* Yes it's kindof lame that we are sending the whole thing,
   1047      but for video all of it may be needed even if displaying
   1048      only a subsection, and I don't want to go through the
   1049      trouble of creating subregions to send */
   1050   Data(dpy, (char *)image->data, image->data_size);
   1051 
   1052   UnlockDisplay(dpy);
   1053   SyncHandle();
   1054 
   1055   return Success;
   1056 }
   1057 
   1058 int SDL_NAME(XvShmPutImage) (
   1059    Display *dpy,
   1060    XvPortID port,
   1061    Drawable d,
   1062    GC gc,
   1063    SDL_NAME(XvImage) *image,
   1064    int src_x,
   1065    int src_y,
   1066    unsigned int src_w,
   1067    unsigned int src_h,
   1068    int dest_x,
   1069    int dest_y,
   1070    unsigned int dest_w,
   1071    unsigned int dest_h,
   1072    Bool send_event
   1073 ){
   1074   XExtDisplayInfo *info = xv_find_display(dpy);
   1075   XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata;
   1076   xvShmPutImageReq *req;
   1077 
   1078   XvCheckExtension(dpy, info, XvBadExtension);
   1079 
   1080   LockDisplay(dpy);
   1081 
   1082   FlushGC(dpy, gc);
   1083 
   1084   XvGetReq(ShmPutImage, req);
   1085 
   1086   req->port = port;
   1087   req->drawable = d;
   1088   req->gc = gc->gid;
   1089   req->shmseg = shminfo->shmseg;
   1090   req->id = image->id;
   1091   req->src_x = src_x;
   1092   req->src_y = src_y;
   1093   req->src_w = src_w;
   1094   req->src_h = src_h;
   1095   req->drw_x = dest_x;
   1096   req->drw_y = dest_y;
   1097   req->drw_w = dest_w;
   1098   req->drw_h = dest_h;
   1099   req->offset = image->data - shminfo->shmaddr;
   1100   req->width = image->width;
   1101   req->height = image->height;
   1102   req->send_event = send_event;
   1103 
   1104   UnlockDisplay(dpy);
   1105   SyncHandle();
   1106 
   1107   return Success;
   1108 }
   1109 
   1110 
   1111 static Bool
   1112 xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
   1113 {
   1114   XExtDisplayInfo *info = xv_find_display(dpy);
   1115   SDL_NAME(XvEvent) *re    = (SDL_NAME(XvEvent) *)host;
   1116   xvEvent *event = (xvEvent *)wire;
   1117 
   1118   XvCheckExtension(dpy, info, False);
   1119 
   1120   switch((event->u.u.type & 0x7F) - info->codes->first_event)
   1121   {
   1122     case XvVideoNotify:
   1123       re->xvvideo.type = event->u.u.type & 0x7f;
   1124       re->xvvideo.serial =
   1125 	_XSetLastRequestRead(dpy, (xGenericReply *)event);
   1126       re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
   1127       re->xvvideo.display = dpy;
   1128       re->xvvideo.time = event->u.videoNotify.time;
   1129       re->xvvideo.reason = event->u.videoNotify.reason;
   1130       re->xvvideo.drawable = event->u.videoNotify.drawable;
   1131       re->xvvideo.port_id = event->u.videoNotify.port;
   1132       break;
   1133     case XvPortNotify:
   1134       re->xvport.type = event->u.u.type & 0x7f;
   1135       re->xvport.serial =
   1136 	_XSetLastRequestRead(dpy, (xGenericReply *)event);
   1137       re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
   1138       re->xvport.display = dpy;
   1139       re->xvport.time = event->u.portNotify.time;
   1140       re->xvport.port_id = event->u.portNotify.port;
   1141       re->xvport.attribute = event->u.portNotify.attribute;
   1142       re->xvport.value = event->u.portNotify.value;
   1143       break;
   1144     default:
   1145       return False;
   1146   }
   1147 
   1148   return (True);
   1149 }
   1150 
   1151 
   1152