Xv.c revision 949d0342
19f606849Smrg/*********************************************************** 29f606849SmrgCopyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, 39f606849Smrgand the Massachusetts Institute of Technology, Cambridge, Massachusetts. 49f606849Smrg 59f606849Smrg All Rights Reserved 69f606849Smrg 7cdbfa18aSmrgPermission to use, copy, modify, and distribute this software and its 8cdbfa18aSmrgdocumentation for any purpose and without fee is hereby granted, 99f606849Smrgprovided that the above copyright notice appear in all copies and that 10cdbfa18aSmrgboth that copyright notice and this permission notice appear in 119f606849Smrgsupporting documentation, and that the names of Digital or MIT not be 129f606849Smrgused in advertising or publicity pertaining to distribution of the 13cdbfa18aSmrgsoftware without specific, written prior permission. 149f606849Smrg 159f606849SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 169f606849SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 179f606849SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 189f606849SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 199f606849SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 209f606849SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 219f606849SmrgSOFTWARE. 229f606849Smrg 239f606849Smrg******************************************************************/ 249f606849Smrg/* 25cdbfa18aSmrg** File: 269f606849Smrg** 279f606849Smrg** Xv.c --- Xv library extension module. 289f606849Smrg** 29cdbfa18aSmrg** Author: 309f606849Smrg** 319f606849Smrg** David Carver (Digital Workstation Engineering/Project Athena) 329f606849Smrg** 339f606849Smrg** Revisions: 349f606849Smrg** 359f606849Smrg** 26.06.91 Carver 369f606849Smrg** - changed XvFreeAdaptors to XvFreeAdaptorInfo 379f606849Smrg** - changed XvFreeEncodings to XvFreeEncodingInfo 389f606849Smrg** 399f606849Smrg** 11.06.91 Carver 409f606849Smrg** - changed SetPortControl to SetPortAttribute 419f606849Smrg** - changed GetPortControl to GetPortAttribute 429f606849Smrg** - changed QueryBestSize 439f606849Smrg** 449f606849Smrg** 15.05.91 Carver 459f606849Smrg** - version 2.0 upgrade 469f606849Smrg** 479f606849Smrg** 240.01.91 Carver 489f606849Smrg** - version 1.4 upgrade 499f606849Smrg** 509f606849Smrg*/ 519f606849Smrg 52cdbfa18aSmrg#ifdef HAVE_CONFIG_H 53cdbfa18aSmrg# include "config.h" 54cdbfa18aSmrg#endif 55cdbfa18aSmrg 569f606849Smrg#include <stdio.h> 579f606849Smrg#include "Xvlibint.h" 589f606849Smrg#include <X11/extensions/Xext.h> 599f606849Smrg#include <X11/extensions/extutil.h> 609f606849Smrg#include <X11/extensions/XShm.h> 61cdbfa18aSmrg#include <limits.h> 62cdbfa18aSmrg 639f606849Smrgstatic XExtensionInfo _xv_info_data; 649f606849Smrgstatic XExtensionInfo *xv_info = &_xv_info_data; 65cdbfa18aSmrgstatic const char *xv_extension_name = XvName; 669f606849Smrg 679f606849Smrg#define XvCheckExtension(dpy, i, val) \ 689f606849Smrg XextCheckExtension(dpy, i, xv_extension_name, val) 699f606849Smrg 70fef5d1ffSmrg#define pad_to_int32(bytes) (((bytes) + 3) & ~3U) 71fef5d1ffSmrg 729f606849Smrgstatic char *xv_error_string(Display *dpy, int code, XExtCodes *codes, 73fef5d1ffSmrg char *buf, int n); 749f606849Smrgstatic int xv_close_display(Display *dpy, XExtCodes *codes); 759f606849Smrgstatic Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire); 769f606849Smrg 779f606849Smrgstatic XExtensionHooks xv_extension_hooks = { 78fef5d1ffSmrg NULL, /* create_gc */ 79fef5d1ffSmrg NULL, /* copy_gc */ 80fef5d1ffSmrg NULL, /* flush_gc */ 81fef5d1ffSmrg NULL, /* free_gc */ 82fef5d1ffSmrg NULL, /* create_font */ 83fef5d1ffSmrg NULL, /* free_font */ 84fef5d1ffSmrg xv_close_display, /* close_display */ 85fef5d1ffSmrg xv_wire_to_event, /* wire_to_event */ 86fef5d1ffSmrg NULL, /* event_to_wire */ 87fef5d1ffSmrg NULL, /* error */ 88fef5d1ffSmrg xv_error_string /* error_string */ 899f606849Smrg}; 909f606849Smrg 919f606849Smrg 92fef5d1ffSmrgstatic const char *xv_error_list[] = { 93fef5d1ffSmrg "BadPort", /* XvBadPort */ 94fef5d1ffSmrg "BadEncoding", /* XvBadEncoding */ 95fef5d1ffSmrg "BadControl" /* XvBadControl */ 969f606849Smrg}; 979f606849Smrg 98fef5d1ffSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY(xv_close_display, xv_info) 999f606849Smrg 100fef5d1ffSmrgstatic XEXT_GENERATE_FIND_DISPLAY(xv_find_display, xv_info, 101fef5d1ffSmrg xv_extension_name, &xv_extension_hooks, 102fef5d1ffSmrg XvNumEvents, NULL) 1039f606849Smrg 104fef5d1ffSmrgstatic XEXT_GENERATE_ERROR_STRING(xv_error_string, xv_extension_name, 105fef5d1ffSmrg XvNumErrors, xv_error_list) 1069f606849Smrg 1079f606849Smrg 1089f606849Smrgint 1099f606849SmrgXvQueryExtension( 110fef5d1ffSmrg Display *dpy, 111fef5d1ffSmrg unsigned int *p_version, 112fef5d1ffSmrg unsigned int *p_revision, 113fef5d1ffSmrg unsigned int *p_requestBase, 114fef5d1ffSmrg unsigned int *p_eventBase, 115fef5d1ffSmrg unsigned int *p_errorBase) 116fef5d1ffSmrg{ 117fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 118fef5d1ffSmrg xvQueryExtensionReq *req; 119fef5d1ffSmrg xvQueryExtensionReply rep; 120fef5d1ffSmrg int status; 121fef5d1ffSmrg 122fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 123fef5d1ffSmrg 124fef5d1ffSmrg LockDisplay(dpy); 125fef5d1ffSmrg 126fef5d1ffSmrg XvGetReq(QueryExtension, req); 127fef5d1ffSmrg 128fef5d1ffSmrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 129fef5d1ffSmrg status = XvBadExtension; 130fef5d1ffSmrg goto out; 131fef5d1ffSmrg } 132fef5d1ffSmrg 133fef5d1ffSmrg *p_version = rep.version; 134fef5d1ffSmrg *p_revision = rep.revision; 135949d0342Smrg *p_requestBase = (unsigned int) info->codes->major_opcode; 136949d0342Smrg *p_eventBase = (unsigned int) info->codes->first_event; 137949d0342Smrg *p_errorBase = (unsigned int) info->codes->first_error; 138fef5d1ffSmrg 139fef5d1ffSmrg status = Success; 140fef5d1ffSmrg 141fef5d1ffSmrg out: 142fef5d1ffSmrg UnlockDisplay(dpy); 143fef5d1ffSmrg SyncHandle(); 144fef5d1ffSmrg 145fef5d1ffSmrg return status; 1469f606849Smrg} 1479f606849Smrg 1489f606849Smrgint 1499f606849SmrgXvQueryAdaptors( 150fef5d1ffSmrg Display *dpy, 151fef5d1ffSmrg Window window, 152fef5d1ffSmrg unsigned int *p_nAdaptors, 153fef5d1ffSmrg XvAdaptorInfo **p_pAdaptors) 154fef5d1ffSmrg{ 155fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 156fef5d1ffSmrg xvQueryAdaptorsReq *req; 157fef5d1ffSmrg xvQueryAdaptorsReply rep; 158fef5d1ffSmrg size_t size; 159fef5d1ffSmrg XvAdaptorInfo *pas = NULL, *pa; 160fef5d1ffSmrg XvFormat *pfs, *pf; 161fef5d1ffSmrg char *buffer = NULL; 162949d0342Smrg char *end; 163fef5d1ffSmrg union { 164fef5d1ffSmrg char *buffer; 165fef5d1ffSmrg char *string; 166fef5d1ffSmrg xvAdaptorInfo *pa; 167fef5d1ffSmrg xvFormat *pf; 1689f606849Smrg } u; 169fef5d1ffSmrg int status; 170fef5d1ffSmrg 171fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 172fef5d1ffSmrg 173fef5d1ffSmrg LockDisplay(dpy); 174fef5d1ffSmrg 175fef5d1ffSmrg XvGetReq(QueryAdaptors, req); 176949d0342Smrg req->window = (CARD32) window; 177fef5d1ffSmrg 178fef5d1ffSmrg /* READ THE REPLY */ 179fef5d1ffSmrg 180fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 181fef5d1ffSmrg rep.num_adaptors = 0; 182fef5d1ffSmrg status = XvBadReply; 183fef5d1ffSmrg goto out; 184fef5d1ffSmrg } 185fef5d1ffSmrg 186fef5d1ffSmrg size = rep.length << 2; 187fef5d1ffSmrg if (size > 0) { 188fef5d1ffSmrg if ((buffer = Xmalloc(size)) == NULL) { 189fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 190fef5d1ffSmrg status = XvBadAlloc; 191fef5d1ffSmrg goto out; 192fef5d1ffSmrg } 193fef5d1ffSmrg _XRead(dpy, buffer, (long) size); 194fef5d1ffSmrg } 195fef5d1ffSmrg 196fef5d1ffSmrg /* GET INPUT ADAPTORS */ 197fef5d1ffSmrg 198fef5d1ffSmrg if (rep.num_adaptors == 0) { 199444fb138Smrg /* If there are no adaptors, there's nothing more to do. */ 200fef5d1ffSmrg status = Success; 201fef5d1ffSmrg goto out; 202fef5d1ffSmrg } 203fef5d1ffSmrg 204444fb138Smrg u.buffer = buffer; 205444fb138Smrg end = buffer + size; 206fef5d1ffSmrg 207fef5d1ffSmrg size = rep.num_adaptors * sizeof(XvAdaptorInfo); 208fef5d1ffSmrg if ((pas = Xmalloc(size)) == NULL) { 209fef5d1ffSmrg status = XvBadAlloc; 210fef5d1ffSmrg goto out; 211fef5d1ffSmrg } 212fef5d1ffSmrg 213fef5d1ffSmrg /* INIT ADAPTOR FIELDS */ 214fef5d1ffSmrg 215fef5d1ffSmrg pa = pas; 216949d0342Smrg for (unsigned int ii = 0; ii < rep.num_adaptors; ii++) { 217fef5d1ffSmrg pa->num_adaptors = 0; 218fef5d1ffSmrg pa->name = (char *) NULL; 219fef5d1ffSmrg pa->formats = (XvFormat *) NULL; 220fef5d1ffSmrg pa++; 221fef5d1ffSmrg } 222fef5d1ffSmrg 223fef5d1ffSmrg pa = pas; 224949d0342Smrg for (unsigned int ii = 0; ii < rep.num_adaptors; ii++) { 225949d0342Smrg char *name; 226949d0342Smrg 227444fb138Smrg if (u.buffer + sz_xvAdaptorInfo > end) { 228444fb138Smrg status = XvBadReply; 229444fb138Smrg goto out; 230444fb138Smrg } 231949d0342Smrg pa->type = (char) u.pa->type; 232fef5d1ffSmrg pa->base_id = u.pa->base_id; 233fef5d1ffSmrg pa->num_ports = u.pa->num_ports; 234fef5d1ffSmrg pa->num_formats = u.pa->num_formats; 235fef5d1ffSmrg pa->num_adaptors = rep.num_adaptors - ii; 236fef5d1ffSmrg 237fef5d1ffSmrg /* GET ADAPTOR NAME */ 238fef5d1ffSmrg 239fef5d1ffSmrg size = u.pa->name_size; 240fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvAdaptorInfo); 241fef5d1ffSmrg 242444fb138Smrg if (u.buffer + size > end) { 243444fb138Smrg status = XvBadReply; 244444fb138Smrg goto out; 245444fb138Smrg } 246fef5d1ffSmrg if ((name = Xmalloc(size + 1)) == NULL) { 247fef5d1ffSmrg status = XvBadAlloc; 248fef5d1ffSmrg goto out; 249fef5d1ffSmrg } 250fef5d1ffSmrg (void) strncpy(name, u.string, size); 251fef5d1ffSmrg name[size] = '\0'; 252fef5d1ffSmrg pa->name = name; 253fef5d1ffSmrg 254fef5d1ffSmrg u.buffer += pad_to_int32(size); 255cdbfa18aSmrg 256fef5d1ffSmrg /* GET FORMATS */ 257fef5d1ffSmrg 258fef5d1ffSmrg size = pa->num_formats * sizeof(XvFormat); 259fef5d1ffSmrg if ((pfs = Xmalloc(size)) == NULL) { 260fef5d1ffSmrg status = XvBadAlloc; 261fef5d1ffSmrg goto out; 262fef5d1ffSmrg } 263fef5d1ffSmrg 264fef5d1ffSmrg pf = pfs; 265949d0342Smrg for (unsigned int jj = 0; jj < pa->num_formats; jj++) { 266444fb138Smrg if (u.buffer + sz_xvFormat > end) { 267444fb138Smrg Xfree(pfs); 268444fb138Smrg status = XvBadReply; 269444fb138Smrg goto out; 270444fb138Smrg } 271949d0342Smrg pf->depth = (char) u.pf->depth; 272fef5d1ffSmrg pf->visual_id = u.pf->visual; 273fef5d1ffSmrg pf++; 274fef5d1ffSmrg 275fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvFormat); 276fef5d1ffSmrg } 277fef5d1ffSmrg 278fef5d1ffSmrg pa->formats = pfs; 279fef5d1ffSmrg 280fef5d1ffSmrg pa++; 281fef5d1ffSmrg 282fef5d1ffSmrg } 283fef5d1ffSmrg 284fef5d1ffSmrg status = Success; 285fef5d1ffSmrg 286fef5d1ffSmrg out: 287fef5d1ffSmrg if (status != Success) { 288fef5d1ffSmrg XvFreeAdaptorInfo(pas); 289fef5d1ffSmrg pas = NULL; 290fef5d1ffSmrg } 291fef5d1ffSmrg 292fef5d1ffSmrg *p_nAdaptors = rep.num_adaptors; 293fef5d1ffSmrg *p_pAdaptors = pas; 294fef5d1ffSmrg 295fef5d1ffSmrg Xfree(buffer); 296fef5d1ffSmrg UnlockDisplay(dpy); 297fef5d1ffSmrg SyncHandle(); 298fef5d1ffSmrg 299fef5d1ffSmrg return status; 3009f606849Smrg} 3019f606849Smrg 3029f606849Smrg 3039f606849Smrgvoid 3049f606849SmrgXvFreeAdaptorInfo(XvAdaptorInfo *pAdaptors) 3059f606849Smrg{ 306fef5d1ffSmrg XvAdaptorInfo *pa; 3079f606849Smrg 308fef5d1ffSmrg if (!pAdaptors) 309fef5d1ffSmrg return; 3109f606849Smrg 311fef5d1ffSmrg pa = pAdaptors; 3129f606849Smrg 313949d0342Smrg for (unsigned int ii = 0; ii < pAdaptors->num_adaptors; ii++, pa++) { 314fef5d1ffSmrg if (pa->name) { 315fef5d1ffSmrg Xfree(pa->name); 316fef5d1ffSmrg } 317fef5d1ffSmrg if (pa->formats) { 318fef5d1ffSmrg Xfree(pa->formats); 319fef5d1ffSmrg } 320cdbfa18aSmrg } 3219f606849Smrg 322fef5d1ffSmrg Xfree(pAdaptors); 3239f606849Smrg} 3249f606849Smrg 3259f606849Smrgint 3269f606849SmrgXvQueryEncodings( 327fef5d1ffSmrg Display *dpy, 328fef5d1ffSmrg XvPortID port, 329fef5d1ffSmrg unsigned int *p_nEncodings, 330fef5d1ffSmrg XvEncodingInfo ** p_pEncodings) 331fef5d1ffSmrg{ 332fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 333fef5d1ffSmrg xvQueryEncodingsReq *req; 334fef5d1ffSmrg xvQueryEncodingsReply rep; 335fef5d1ffSmrg size_t size; 336fef5d1ffSmrg XvEncodingInfo *pes = NULL, *pe; 337fef5d1ffSmrg char *buffer = NULL; 338949d0342Smrg char *end; 339fef5d1ffSmrg union { 340fef5d1ffSmrg char *buffer; 341fef5d1ffSmrg char *string; 342fef5d1ffSmrg xvEncodingInfo *pe; 3439f606849Smrg } u; 344fef5d1ffSmrg int status; 345fef5d1ffSmrg 346fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 347fef5d1ffSmrg 348fef5d1ffSmrg LockDisplay(dpy); 349fef5d1ffSmrg 350fef5d1ffSmrg XvGetReq(QueryEncodings, req); 351949d0342Smrg req->port = (CARD32) port; 352fef5d1ffSmrg 353fef5d1ffSmrg /* READ THE REPLY */ 354fef5d1ffSmrg 355fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 356fef5d1ffSmrg rep.num_encodings = 0; 357fef5d1ffSmrg status = XvBadReply; 358fef5d1ffSmrg goto out; 359fef5d1ffSmrg } 360cdbfa18aSmrg 361fef5d1ffSmrg size = rep.length << 2; 362fef5d1ffSmrg if (size > 0) { 363fef5d1ffSmrg if ((buffer = Xmalloc(size)) == NULL) { 364fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 365fef5d1ffSmrg status = XvBadAlloc; 366fef5d1ffSmrg goto out; 367fef5d1ffSmrg } 368fef5d1ffSmrg _XRead(dpy, buffer, (long) size); 369fef5d1ffSmrg } 370fef5d1ffSmrg 371fef5d1ffSmrg /* GET ENCODINGS */ 372fef5d1ffSmrg 373fef5d1ffSmrg if (rep.num_encodings == 0) { 374444fb138Smrg /* If there are no encodings, there's nothing more to do. */ 375fef5d1ffSmrg status = Success; 376fef5d1ffSmrg goto out; 377fef5d1ffSmrg } 378fef5d1ffSmrg 379444fb138Smrg u.buffer = buffer; 380444fb138Smrg end = buffer + size; 381fef5d1ffSmrg 382fef5d1ffSmrg size = rep.num_encodings * sizeof(XvEncodingInfo); 383fef5d1ffSmrg if ((pes = Xmalloc(size)) == NULL) { 384fef5d1ffSmrg status = XvBadAlloc; 385fef5d1ffSmrg goto out; 386fef5d1ffSmrg } 387fef5d1ffSmrg 388fef5d1ffSmrg /* INITIALIZE THE ENCODING POINTER */ 389fef5d1ffSmrg 390fef5d1ffSmrg pe = pes; 391949d0342Smrg for (unsigned int jj = 0; jj < rep.num_encodings; jj++) { 392fef5d1ffSmrg pe->name = (char *) NULL; 393fef5d1ffSmrg pe->num_encodings = 0; 394fef5d1ffSmrg pe++; 395fef5d1ffSmrg } 396fef5d1ffSmrg 397fef5d1ffSmrg pe = pes; 398949d0342Smrg for (unsigned int jj = 0; jj < rep.num_encodings; jj++) { 399949d0342Smrg char *name; 400949d0342Smrg 401444fb138Smrg if (u.buffer + sz_xvEncodingInfo > end) { 402444fb138Smrg status = XvBadReply; 403444fb138Smrg goto out; 404444fb138Smrg } 405fef5d1ffSmrg pe->encoding_id = u.pe->encoding; 406fef5d1ffSmrg pe->width = u.pe->width; 407fef5d1ffSmrg pe->height = u.pe->height; 408fef5d1ffSmrg pe->rate.numerator = u.pe->rate.numerator; 409fef5d1ffSmrg pe->rate.denominator = u.pe->rate.denominator; 410fef5d1ffSmrg pe->num_encodings = rep.num_encodings - jj; 411fef5d1ffSmrg 412fef5d1ffSmrg size = u.pe->name_size; 413fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvEncodingInfo); 414fef5d1ffSmrg 415444fb138Smrg if (u.buffer + size > end) { 416444fb138Smrg status = XvBadReply; 417444fb138Smrg goto out; 418444fb138Smrg } 419fef5d1ffSmrg if ((name = Xmalloc(size + 1)) == NULL) { 420fef5d1ffSmrg status = XvBadAlloc; 421fef5d1ffSmrg goto out; 422fef5d1ffSmrg } 423fef5d1ffSmrg strncpy(name, u.string, size); 424fef5d1ffSmrg name[size] = '\0'; 425fef5d1ffSmrg pe->name = name; 426fef5d1ffSmrg pe++; 427fef5d1ffSmrg 428fef5d1ffSmrg u.buffer += pad_to_int32(size); 429fef5d1ffSmrg } 430fef5d1ffSmrg 431fef5d1ffSmrg status = Success; 432fef5d1ffSmrg 433fef5d1ffSmrg out: 434fef5d1ffSmrg if (status != Success) { 435fef5d1ffSmrg XvFreeEncodingInfo(pes); 436fef5d1ffSmrg pes = NULL; 437fef5d1ffSmrg } 438fef5d1ffSmrg 439fef5d1ffSmrg *p_nEncodings = rep.num_encodings; 440fef5d1ffSmrg *p_pEncodings = pes; 441fef5d1ffSmrg 442fef5d1ffSmrg Xfree(buffer); 443fef5d1ffSmrg UnlockDisplay(dpy); 444fef5d1ffSmrg SyncHandle(); 445fef5d1ffSmrg 446fef5d1ffSmrg return (Success); 4479f606849Smrg} 4489f606849Smrg 4499f606849Smrgvoid 4509f606849SmrgXvFreeEncodingInfo(XvEncodingInfo *pEncodings) 4519f606849Smrg{ 452fef5d1ffSmrg XvEncodingInfo *pe; 4539f606849Smrg 454fef5d1ffSmrg if (!pEncodings) 455fef5d1ffSmrg return; 4569f606849Smrg 457fef5d1ffSmrg pe = pEncodings; 4589f606849Smrg 459949d0342Smrg for (unsigned long ii = 0; ii < pEncodings->num_encodings; ii++, pe++) { 460fef5d1ffSmrg if (pe->name) 461fef5d1ffSmrg Xfree(pe->name); 462fef5d1ffSmrg } 4639f606849Smrg 464fef5d1ffSmrg Xfree(pEncodings); 4659f606849Smrg} 4669f606849Smrg 4679f606849Smrgint 4689f606849SmrgXvPutVideo( 469fef5d1ffSmrg Display *dpy, 470fef5d1ffSmrg XvPortID port, 471fef5d1ffSmrg Drawable d, 472fef5d1ffSmrg GC gc, 473fef5d1ffSmrg int vx, int vy, 474fef5d1ffSmrg unsigned int vw, unsigned int vh, 475fef5d1ffSmrg int dx, int dy, 476fef5d1ffSmrg unsigned int dw, unsigned int dh) 477fef5d1ffSmrg{ 478fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 479fef5d1ffSmrg xvPutVideoReq *req; 480fef5d1ffSmrg 481fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 482fef5d1ffSmrg 483fef5d1ffSmrg LockDisplay(dpy); 484fef5d1ffSmrg 485fef5d1ffSmrg FlushGC(dpy, gc); 486fef5d1ffSmrg 487fef5d1ffSmrg XvGetReq(PutVideo, req); 488fef5d1ffSmrg 489949d0342Smrg req->port = (CARD32) port; 490949d0342Smrg req->drawable = (CARD32) d; 491949d0342Smrg req->gc = (CARD32) gc->gid; 492949d0342Smrg req->vid_x = (INT16) vx; 493949d0342Smrg req->vid_y = (INT16) vy; 494949d0342Smrg req->vid_w = (CARD16) vw; 495949d0342Smrg req->vid_h = (CARD16) vh; 496949d0342Smrg req->drw_x = (INT16) dx; 497949d0342Smrg req->drw_y = (INT16) dy; 498949d0342Smrg req->drw_w = (CARD16) dw; 499949d0342Smrg req->drw_h = (CARD16) dh; 500fef5d1ffSmrg 501fef5d1ffSmrg UnlockDisplay(dpy); 502fef5d1ffSmrg SyncHandle(); 503fef5d1ffSmrg 504fef5d1ffSmrg return Success; 5059f606849Smrg} 5069f606849Smrg 5079f606849Smrgint 5089f606849SmrgXvPutStill( 509fef5d1ffSmrg Display *dpy, 510fef5d1ffSmrg XvPortID port, 511fef5d1ffSmrg Drawable d, 512fef5d1ffSmrg GC gc, 513fef5d1ffSmrg int vx, int vy, 514fef5d1ffSmrg unsigned int vw, unsigned int vh, 515fef5d1ffSmrg int dx, int dy, 516fef5d1ffSmrg unsigned int dw, unsigned int dh) 517fef5d1ffSmrg{ 518fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 519fef5d1ffSmrg xvPutStillReq *req; 520fef5d1ffSmrg 521fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 522fef5d1ffSmrg 523fef5d1ffSmrg LockDisplay(dpy); 524fef5d1ffSmrg 525fef5d1ffSmrg FlushGC(dpy, gc); 526fef5d1ffSmrg 527fef5d1ffSmrg XvGetReq(PutStill, req); 528949d0342Smrg req->port = (CARD32) port; 529949d0342Smrg req->drawable = (CARD32) d; 530949d0342Smrg req->gc = (CARD32) gc->gid; 531949d0342Smrg req->vid_x = (INT16) vx; 532949d0342Smrg req->vid_y = (INT16) vy; 533949d0342Smrg req->vid_w = (CARD16) vw; 534949d0342Smrg req->vid_h = (CARD16) vh; 535949d0342Smrg req->drw_x = (INT16) dx; 536949d0342Smrg req->drw_y = (INT16) dy; 537949d0342Smrg req->drw_w = (CARD16) dw; 538949d0342Smrg req->drw_h = (CARD16) dh; 539fef5d1ffSmrg 540fef5d1ffSmrg UnlockDisplay(dpy); 541fef5d1ffSmrg SyncHandle(); 542fef5d1ffSmrg 543fef5d1ffSmrg return Success; 5449f606849Smrg} 5459f606849Smrg 5469f606849Smrgint 5479f606849SmrgXvGetVideo( 548fef5d1ffSmrg Display *dpy, 549fef5d1ffSmrg XvPortID port, 550fef5d1ffSmrg Drawable d, 551fef5d1ffSmrg GC gc, 552fef5d1ffSmrg int vx, int vy, 553fef5d1ffSmrg unsigned int vw, unsigned int vh, 554fef5d1ffSmrg int dx, int dy, 555fef5d1ffSmrg unsigned int dw, unsigned int dh) 556fef5d1ffSmrg{ 557fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 558fef5d1ffSmrg xvGetVideoReq *req; 559fef5d1ffSmrg 560fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 561fef5d1ffSmrg 562fef5d1ffSmrg LockDisplay(dpy); 563fef5d1ffSmrg 564fef5d1ffSmrg FlushGC(dpy, gc); 565fef5d1ffSmrg 566fef5d1ffSmrg XvGetReq(GetVideo, req); 567949d0342Smrg req->port = (CARD32) port; 568949d0342Smrg req->drawable = (CARD32) d; 569949d0342Smrg req->gc = (CARD32) gc->gid; 570949d0342Smrg req->vid_x = (INT16) vx; 571949d0342Smrg req->vid_y = (INT16) vy; 572949d0342Smrg req->vid_w = (CARD16) vw; 573949d0342Smrg req->vid_h = (CARD16) vh; 574949d0342Smrg req->drw_x = (INT16) dx; 575949d0342Smrg req->drw_y = (INT16) dy; 576949d0342Smrg req->drw_w = (CARD16) dw; 577949d0342Smrg req->drw_h = (CARD16) dh; 578fef5d1ffSmrg 579fef5d1ffSmrg UnlockDisplay(dpy); 580fef5d1ffSmrg SyncHandle(); 581fef5d1ffSmrg 582fef5d1ffSmrg return Success; 5839f606849Smrg} 5849f606849Smrg 5859f606849Smrgint 5869f606849SmrgXvGetStill( 587fef5d1ffSmrg Display *dpy, 588fef5d1ffSmrg XvPortID port, 589fef5d1ffSmrg Drawable d, 590fef5d1ffSmrg GC gc, 591fef5d1ffSmrg int vx, int vy, 592fef5d1ffSmrg unsigned int vw, unsigned int vh, 593fef5d1ffSmrg int dx, int dy, 594fef5d1ffSmrg unsigned int dw, unsigned int dh) 595fef5d1ffSmrg{ 596fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 597fef5d1ffSmrg xvGetStillReq *req; 598fef5d1ffSmrg 599fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 600fef5d1ffSmrg 601fef5d1ffSmrg LockDisplay(dpy); 602fef5d1ffSmrg 603fef5d1ffSmrg FlushGC(dpy, gc); 604fef5d1ffSmrg 605fef5d1ffSmrg XvGetReq(GetStill, req); 606949d0342Smrg req->port = (CARD32) port; 607949d0342Smrg req->drawable = (CARD32) d; 608949d0342Smrg req->gc = (CARD32) gc->gid; 609949d0342Smrg req->vid_x = (INT16) vx; 610949d0342Smrg req->vid_y = (INT16) vy; 611949d0342Smrg req->vid_w = (CARD16) vw; 612949d0342Smrg req->vid_h = (CARD16) vh; 613949d0342Smrg req->drw_x = (INT16) dx; 614949d0342Smrg req->drw_y = (INT16) dy; 615949d0342Smrg req->drw_w = (CARD16) dw; 616949d0342Smrg req->drw_h = (CARD16) dh; 617fef5d1ffSmrg 618fef5d1ffSmrg UnlockDisplay(dpy); 619fef5d1ffSmrg SyncHandle(); 620fef5d1ffSmrg 621fef5d1ffSmrg return Success; 6229f606849Smrg} 6239f606849Smrg 6249f606849Smrgint 625fef5d1ffSmrgXvStopVideo(Display *dpy, XvPortID port, Drawable draw) 626fef5d1ffSmrg{ 627fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 628fef5d1ffSmrg xvStopVideoReq *req; 6299f606849Smrg 630fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6319f606849Smrg 632fef5d1ffSmrg LockDisplay(dpy); 6339f606849Smrg 634fef5d1ffSmrg XvGetReq(StopVideo, req); 635949d0342Smrg req->port = (CARD32) port; 636949d0342Smrg req->drawable = (CARD32) draw; 6379f606849Smrg 638fef5d1ffSmrg UnlockDisplay(dpy); 639fef5d1ffSmrg SyncHandle(); 6409f606849Smrg 641fef5d1ffSmrg return Success; 6429f606849Smrg} 6439f606849Smrg 6449f606849Smrgint 645fef5d1ffSmrgXvGrabPort(Display *dpy, XvPortID port, Time time) 646fef5d1ffSmrg{ 647fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 648fef5d1ffSmrg int result; 649fef5d1ffSmrg xvGrabPortReply rep; 650fef5d1ffSmrg xvGrabPortReq *req; 6519f606849Smrg 652fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6539f606849Smrg 654fef5d1ffSmrg LockDisplay(dpy); 6559f606849Smrg 656fef5d1ffSmrg XvGetReq(GrabPort, req); 657949d0342Smrg req->port = (CARD32) port; 658949d0342Smrg req->time = (CARD32) time; 6599f606849Smrg 660fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xTrue) == 0) 661fef5d1ffSmrg rep.result = GrabSuccess; 6629f606849Smrg 663fef5d1ffSmrg result = rep.result; 6649f606849Smrg 665fef5d1ffSmrg UnlockDisplay(dpy); 666fef5d1ffSmrg SyncHandle(); 6679f606849Smrg 668fef5d1ffSmrg return result; 6699f606849Smrg} 6709f606849Smrg 6719f606849Smrgint 672fef5d1ffSmrgXvUngrabPort(Display *dpy, XvPortID port, Time time) 673fef5d1ffSmrg{ 674fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 675fef5d1ffSmrg xvUngrabPortReq *req; 6769f606849Smrg 677fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6789f606849Smrg 679fef5d1ffSmrg LockDisplay(dpy); 6809f606849Smrg 681fef5d1ffSmrg XvGetReq(UngrabPort, req); 682949d0342Smrg req->port = (CARD32) port; 683949d0342Smrg req->time = (CARD32) time; 6849f606849Smrg 685fef5d1ffSmrg UnlockDisplay(dpy); 686fef5d1ffSmrg SyncHandle(); 6879f606849Smrg 688fef5d1ffSmrg return Success; 6899f606849Smrg} 6909f606849Smrg 6919f606849Smrgint 692fef5d1ffSmrgXvSelectVideoNotify(Display *dpy, Drawable drawable, Bool onoff) 693fef5d1ffSmrg{ 694fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 695fef5d1ffSmrg xvSelectVideoNotifyReq *req; 6969f606849Smrg 697fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6989f606849Smrg 699fef5d1ffSmrg LockDisplay(dpy); 7009f606849Smrg 701fef5d1ffSmrg XvGetReq(SelectVideoNotify, req); 702949d0342Smrg req->drawable = (CARD32) drawable; 703949d0342Smrg req->onoff = (BOOL) onoff; 7049f606849Smrg 705fef5d1ffSmrg UnlockDisplay(dpy); 706fef5d1ffSmrg SyncHandle(); 7079f606849Smrg 708fef5d1ffSmrg return Success; 7099f606849Smrg} 7109f606849Smrg 7119f606849Smrgint 712fef5d1ffSmrgXvSelectPortNotify(Display *dpy, XvPortID port, Bool onoff) 713fef5d1ffSmrg{ 714fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 715fef5d1ffSmrg xvSelectPortNotifyReq *req; 7169f606849Smrg 717fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7189f606849Smrg 719fef5d1ffSmrg LockDisplay(dpy); 7209f606849Smrg 721fef5d1ffSmrg XvGetReq(SelectPortNotify, req); 722949d0342Smrg req->port = (CARD32) port; 723949d0342Smrg req->onoff = (BOOL) onoff; 7249f606849Smrg 725fef5d1ffSmrg UnlockDisplay(dpy); 726fef5d1ffSmrg SyncHandle(); 7279f606849Smrg 728fef5d1ffSmrg return Success; 7299f606849Smrg} 7309f606849Smrg 7319f606849Smrgint 732fef5d1ffSmrgXvSetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int value) 7339f606849Smrg{ 734fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 735fef5d1ffSmrg xvSetPortAttributeReq *req; 7369f606849Smrg 737fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7389f606849Smrg 739fef5d1ffSmrg LockDisplay(dpy); 7409f606849Smrg 741fef5d1ffSmrg XvGetReq(SetPortAttribute, req); 742949d0342Smrg req->port = (CARD32) port; 743949d0342Smrg req->attribute = (CARD32) attribute; 744fef5d1ffSmrg req->value = value; 7459f606849Smrg 746fef5d1ffSmrg UnlockDisplay(dpy); 747fef5d1ffSmrg SyncHandle(); 7489f606849Smrg 749fef5d1ffSmrg return (Success); 7509f606849Smrg} 7519f606849Smrg 7529f606849Smrgint 753fef5d1ffSmrgXvGetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int *p_value) 7549f606849Smrg{ 755fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 756fef5d1ffSmrg xvGetPortAttributeReq *req; 757fef5d1ffSmrg xvGetPortAttributeReply rep; 758fef5d1ffSmrg int status; 7599f606849Smrg 760fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7619f606849Smrg 762fef5d1ffSmrg LockDisplay(dpy); 7639f606849Smrg 764fef5d1ffSmrg XvGetReq(GetPortAttribute, req); 765949d0342Smrg req->port = (CARD32) port; 766949d0342Smrg req->attribute = (CARD32) attribute; 7679f606849Smrg 768fef5d1ffSmrg /* READ THE REPLY */ 7699f606849Smrg 770fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 771fef5d1ffSmrg status = XvBadReply; 772fef5d1ffSmrg } 773fef5d1ffSmrg else { 774fef5d1ffSmrg *p_value = rep.value; 775fef5d1ffSmrg status = Success; 776fef5d1ffSmrg } 777cdbfa18aSmrg 778fef5d1ffSmrg UnlockDisplay(dpy); 779fef5d1ffSmrg SyncHandle(); 7809f606849Smrg 781fef5d1ffSmrg return status; 7829f606849Smrg} 7839f606849Smrg 7849f606849Smrgint 7859f606849SmrgXvQueryBestSize( 786fef5d1ffSmrg Display *dpy, 787fef5d1ffSmrg XvPortID port, 788fef5d1ffSmrg Bool motion, 789fef5d1ffSmrg unsigned int vid_w, 790fef5d1ffSmrg unsigned int vid_h, 791fef5d1ffSmrg unsigned int drw_w, 792fef5d1ffSmrg unsigned int drw_h, 793fef5d1ffSmrg unsigned int *p_actual_width, 794fef5d1ffSmrg unsigned int *p_actual_height) 7959f606849Smrg{ 796fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 797fef5d1ffSmrg xvQueryBestSizeReq *req; 798fef5d1ffSmrg xvQueryBestSizeReply rep; 799fef5d1ffSmrg int status; 8009f606849Smrg 801fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 8029f606849Smrg 803fef5d1ffSmrg LockDisplay(dpy); 8049f606849Smrg 805fef5d1ffSmrg XvGetReq(QueryBestSize, req); 806949d0342Smrg req->port = (CARD32) port; 807949d0342Smrg req->motion = (CARD8) motion; 808949d0342Smrg req->vid_w = (CARD16) vid_w; 809949d0342Smrg req->vid_h = (CARD16) vid_h; 810949d0342Smrg req->drw_w = (CARD16) drw_w; 811949d0342Smrg req->drw_h = (CARD16) drw_h; 8129f606849Smrg 813fef5d1ffSmrg /* READ THE REPLY */ 8149f606849Smrg 815fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 816fef5d1ffSmrg status = XvBadReply; 817fef5d1ffSmrg } 818fef5d1ffSmrg else { 819fef5d1ffSmrg *p_actual_width = rep.actual_width; 820fef5d1ffSmrg *p_actual_height = rep.actual_height; 821fef5d1ffSmrg status = Success; 822fef5d1ffSmrg } 8239f606849Smrg 824fef5d1ffSmrg UnlockDisplay(dpy); 825fef5d1ffSmrg SyncHandle(); 8269f606849Smrg 827fef5d1ffSmrg return status; 8289f606849Smrg} 8299f606849Smrg 8309f606849Smrg 831fef5d1ffSmrgXvAttribute * 8329f606849SmrgXvQueryPortAttributes(Display *dpy, XvPortID port, int *num) 8339f606849Smrg{ 834fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 835fef5d1ffSmrg xvQueryPortAttributesReq *req; 836fef5d1ffSmrg xvQueryPortAttributesReply rep; 837fef5d1ffSmrg XvAttribute *ret = NULL; 838fef5d1ffSmrg 839fef5d1ffSmrg *num = 0; 840fef5d1ffSmrg 841fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 842fef5d1ffSmrg 843fef5d1ffSmrg LockDisplay(dpy); 844fef5d1ffSmrg 845fef5d1ffSmrg XvGetReq(QueryPortAttributes, req); 846949d0342Smrg req->port = (CARD32) port; 847fef5d1ffSmrg 848fef5d1ffSmrg /* READ THE REPLY */ 849fef5d1ffSmrg 850fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 851fef5d1ffSmrg goto out; 852fef5d1ffSmrg } 853fef5d1ffSmrg 854fef5d1ffSmrg /* 855fef5d1ffSmrg * X server sends data packed as: 856fef5d1ffSmrg * attribute1, name1, attribute2, name2, ... 857fef5d1ffSmrg * We allocate a single buffer large enough to hold them all and 858fef5d1ffSmrg * then de-interleave the data so we return it to clients as: 859fef5d1ffSmrg * attribute1, attribute2, ..., name1, name2, ... 860fef5d1ffSmrg * so that clients may refer to attributes as a simple array of 861fef5d1ffSmrg * structs: attributes[0], attributes[1], ... 862fef5d1ffSmrg * and free it as a single/simple buffer. 863fef5d1ffSmrg */ 864fef5d1ffSmrg 865fef5d1ffSmrg if (rep.num_attributes) { 866fef5d1ffSmrg /* limit each part to no more than one half the max size */ 867fef5d1ffSmrg if ((rep.num_attributes < ((INT_MAX / 2) / sizeof(XvAttribute))) && 868fef5d1ffSmrg (rep.text_size < (INT_MAX / 2) - 1)) { 869949d0342Smrg unsigned long size; 870949d0342Smrg 871fef5d1ffSmrg size = (rep.num_attributes * sizeof(XvAttribute)) + 872fef5d1ffSmrg rep.text_size + 1; 873fef5d1ffSmrg ret = Xmalloc(size); 874fef5d1ffSmrg } 875fef5d1ffSmrg 876fef5d1ffSmrg if (ret != NULL) { 877fef5d1ffSmrg char *marker = (char *) (&ret[rep.num_attributes]); 878fef5d1ffSmrg xvAttributeInfo Info; 879fef5d1ffSmrg 880fef5d1ffSmrg /* keep track of remaining room for text strings */ 881949d0342Smrg unsigned long size = rep.text_size; 882fef5d1ffSmrg 883949d0342Smrg for (unsigned int i = 0; i < rep.num_attributes; i++) { 884fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvAttributeInfo); 885fef5d1ffSmrg ret[i].flags = (int) Info.flags; 886fef5d1ffSmrg ret[i].min_value = Info.min; 887fef5d1ffSmrg ret[i].max_value = Info.max; 888fef5d1ffSmrg ret[i].name = marker; 889fef5d1ffSmrg if (Info.size <= size) { 890fef5d1ffSmrg _XRead(dpy, marker, Info.size); 891fef5d1ffSmrg marker += Info.size; 892fef5d1ffSmrg size -= Info.size; 893fef5d1ffSmrg } 894fef5d1ffSmrg (*num)++; 895fef5d1ffSmrg } 896fef5d1ffSmrg 897fef5d1ffSmrg /* ensure final string is nil-terminated to avoid exposure of 898fef5d1ffSmrg uninitialized memory */ 899fef5d1ffSmrg *marker = '\0'; 900fef5d1ffSmrg } 901fef5d1ffSmrg else 902fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 903fef5d1ffSmrg } 904fef5d1ffSmrg 905fef5d1ffSmrg out: 906fef5d1ffSmrg UnlockDisplay(dpy); 907fef5d1ffSmrg SyncHandle(); 908fef5d1ffSmrg 909fef5d1ffSmrg return ret; 9109f606849Smrg} 9119f606849Smrg 912fef5d1ffSmrgXvImageFormatValues * 913fef5d1ffSmrgXvListImageFormats(Display *dpy, XvPortID port, int *num) 914fef5d1ffSmrg{ 915fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 916fef5d1ffSmrg xvListImageFormatsReq *req; 917fef5d1ffSmrg xvListImageFormatsReply rep; 918fef5d1ffSmrg XvImageFormatValues *ret = NULL; 919fef5d1ffSmrg 920fef5d1ffSmrg *num = 0; 921fef5d1ffSmrg 922fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 923fef5d1ffSmrg 924fef5d1ffSmrg LockDisplay(dpy); 925fef5d1ffSmrg 926fef5d1ffSmrg XvGetReq(ListImageFormats, req); 927949d0342Smrg req->port = (CARD32) port; 928fef5d1ffSmrg 929fef5d1ffSmrg /* READ THE REPLY */ 930fef5d1ffSmrg 931fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 932fef5d1ffSmrg goto out; 933fef5d1ffSmrg } 934fef5d1ffSmrg 935fef5d1ffSmrg if (rep.num_formats) { 936fef5d1ffSmrg if (rep.num_formats < (INT_MAX / sizeof(XvImageFormatValues))) 937fef5d1ffSmrg ret = Xmalloc(rep.num_formats * sizeof(XvImageFormatValues)); 938fef5d1ffSmrg 939fef5d1ffSmrg if (ret != NULL) { 940949d0342Smrg for (unsigned int i = 0; i < rep.num_formats; i++) { 941949d0342Smrg xvImageFormatInfo Info; 942fef5d1ffSmrg 943fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvImageFormatInfo); 944949d0342Smrg ret[i].id = (int) Info.id; 945fef5d1ffSmrg ret[i].type = Info.type; 946fef5d1ffSmrg ret[i].byte_order = Info.byte_order; 947fef5d1ffSmrg memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); 948fef5d1ffSmrg ret[i].bits_per_pixel = Info.bpp; 949fef5d1ffSmrg ret[i].format = Info.format; 950fef5d1ffSmrg ret[i].num_planes = Info.num_planes; 951fef5d1ffSmrg ret[i].depth = Info.depth; 952fef5d1ffSmrg ret[i].red_mask = Info.red_mask; 953fef5d1ffSmrg ret[i].green_mask = Info.green_mask; 954fef5d1ffSmrg ret[i].blue_mask = Info.blue_mask; 955fef5d1ffSmrg ret[i].y_sample_bits = Info.y_sample_bits; 956fef5d1ffSmrg ret[i].u_sample_bits = Info.u_sample_bits; 957fef5d1ffSmrg ret[i].v_sample_bits = Info.v_sample_bits; 958fef5d1ffSmrg ret[i].horz_y_period = Info.horz_y_period; 959fef5d1ffSmrg ret[i].horz_u_period = Info.horz_u_period; 960fef5d1ffSmrg ret[i].horz_v_period = Info.horz_v_period; 961fef5d1ffSmrg ret[i].vert_y_period = Info.vert_y_period; 962fef5d1ffSmrg ret[i].vert_u_period = Info.vert_u_period; 963fef5d1ffSmrg ret[i].vert_v_period = Info.vert_v_period; 964fef5d1ffSmrg memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); 965fef5d1ffSmrg ret[i].scanline_order = Info.scanline_order; 966fef5d1ffSmrg (*num)++; 967fef5d1ffSmrg } 968fef5d1ffSmrg } 969fef5d1ffSmrg else 970fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 971fef5d1ffSmrg } 972fef5d1ffSmrg 973fef5d1ffSmrg out: 974fef5d1ffSmrg UnlockDisplay(dpy); 975fef5d1ffSmrg SyncHandle(); 976fef5d1ffSmrg 977fef5d1ffSmrg return ret; 9789f606849Smrg} 9799f606849Smrg 980fef5d1ffSmrgXvImage * 981fef5d1ffSmrgXvCreateImage( 982fef5d1ffSmrg Display *dpy, 983fef5d1ffSmrg XvPortID port, 984fef5d1ffSmrg int id, 985fef5d1ffSmrg char *data, 986fef5d1ffSmrg int width, 987fef5d1ffSmrg int height) 988fef5d1ffSmrg{ 989fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 990fef5d1ffSmrg xvQueryImageAttributesReq *req; 991fef5d1ffSmrg xvQueryImageAttributesReply rep; 992fef5d1ffSmrg XvImage *ret = NULL; 993fef5d1ffSmrg 994fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 995fef5d1ffSmrg 996fef5d1ffSmrg LockDisplay(dpy); 997fef5d1ffSmrg 998fef5d1ffSmrg XvGetReq(QueryImageAttributes, req); 999949d0342Smrg req->id = (CARD32) id; 1000949d0342Smrg req->port = (CARD32) port; 1001949d0342Smrg req->width = (CARD16) width; 1002949d0342Smrg req->height = (CARD16) height; 1003fef5d1ffSmrg 1004fef5d1ffSmrg /* READ THE REPLY */ 1005fef5d1ffSmrg 1006fef5d1ffSmrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 1007fef5d1ffSmrg goto out; 1008fef5d1ffSmrg } 1009fef5d1ffSmrg 1010fef5d1ffSmrg if (rep.num_planes < ((INT_MAX >> 3) - sizeof(XvImage))) 1011fef5d1ffSmrg ret = Xmalloc(sizeof(XvImage) + (rep.num_planes << 3)); 1012fef5d1ffSmrg 1013fef5d1ffSmrg if (ret != NULL) { 1014fef5d1ffSmrg ret->id = id; 1015fef5d1ffSmrg ret->width = rep.width; 1016fef5d1ffSmrg ret->height = rep.height; 1017949d0342Smrg ret->data_size = (int) rep.data_size; 1018949d0342Smrg ret->num_planes = (int) rep.num_planes; 1019fef5d1ffSmrg ret->pitches = (int *) (&ret[1]); 1020fef5d1ffSmrg ret->offsets = ret->pitches + rep.num_planes; 1021fef5d1ffSmrg ret->data = data; 1022fef5d1ffSmrg ret->obdata = NULL; 1023fef5d1ffSmrg _XRead(dpy, (char *) (ret->pitches), rep.num_planes << 2); 1024fef5d1ffSmrg _XRead(dpy, (char *) (ret->offsets), rep.num_planes << 2); 1025fef5d1ffSmrg } 1026fef5d1ffSmrg else 1027fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 1028fef5d1ffSmrg 1029fef5d1ffSmrg out: 1030fef5d1ffSmrg UnlockDisplay(dpy); 1031fef5d1ffSmrg SyncHandle(); 1032fef5d1ffSmrg 1033fef5d1ffSmrg return ret; 10349f606849Smrg} 10359f606849Smrg 1036fef5d1ffSmrgXvImage * 1037fef5d1ffSmrgXvShmCreateImage( 1038fef5d1ffSmrg Display *dpy, 1039fef5d1ffSmrg XvPortID port, 1040fef5d1ffSmrg int id, 1041fef5d1ffSmrg char *data, 1042fef5d1ffSmrg int width, 1043fef5d1ffSmrg int height, 1044fef5d1ffSmrg XShmSegmentInfo *shminfo) 1045fef5d1ffSmrg{ 1046fef5d1ffSmrg XvImage *ret; 10479f606849Smrg 1048fef5d1ffSmrg ret = XvCreateImage(dpy, port, id, data, width, height); 10499f606849Smrg 1050fef5d1ffSmrg if (ret) 1051fef5d1ffSmrg ret->obdata = (XPointer) shminfo; 10529f606849Smrg 1053fef5d1ffSmrg return ret; 10549f606849Smrg} 10559f606849Smrg 1056fef5d1ffSmrgint 1057fef5d1ffSmrgXvPutImage( 1058fef5d1ffSmrg Display *dpy, 1059fef5d1ffSmrg XvPortID port, 1060fef5d1ffSmrg Drawable d, 1061fef5d1ffSmrg GC gc, 1062fef5d1ffSmrg XvImage *image, 1063fef5d1ffSmrg int src_x, int src_y, 1064fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1065fef5d1ffSmrg int dest_x, int dest_y, 1066fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h) 1067fef5d1ffSmrg{ 1068fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1069fef5d1ffSmrg xvPutImageReq *req; 1070fef5d1ffSmrg unsigned int len; 1071fef5d1ffSmrg 1072fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1073fef5d1ffSmrg 1074fef5d1ffSmrg LockDisplay(dpy); 1075fef5d1ffSmrg 1076fef5d1ffSmrg FlushGC(dpy, gc); 1077fef5d1ffSmrg 1078fef5d1ffSmrg XvGetReq(PutImage, req); 1079fef5d1ffSmrg 1080949d0342Smrg req->port = (CARD32) port; 1081949d0342Smrg req->drawable = (CARD32) d; 1082949d0342Smrg req->gc = (CARD32) gc->gid; 1083949d0342Smrg req->id = (CARD32) image->id; 1084949d0342Smrg req->src_x = (INT16) src_x; 1085949d0342Smrg req->src_y = (INT16) src_y; 1086949d0342Smrg req->src_w = (CARD16) src_w; 1087949d0342Smrg req->src_h = (CARD16) src_h; 1088949d0342Smrg req->drw_x = (INT16) dest_x; 1089949d0342Smrg req->drw_y = (INT16) dest_y; 1090949d0342Smrg req->drw_w = (CARD16) dest_w; 1091949d0342Smrg req->drw_h = (CARD16) dest_h; 1092949d0342Smrg req->width = (CARD16) image->width; 1093949d0342Smrg req->height = (CARD16) image->height; 1094fef5d1ffSmrg 1095fef5d1ffSmrg len = ((unsigned int) image->data_size + 3) >> 2; 1096fef5d1ffSmrg SetReqLen(req, len, len); 1097fef5d1ffSmrg 1098fef5d1ffSmrg /* Yes it's kindof lame that we are sending the whole thing, 1099fef5d1ffSmrg but for video all of it may be needed even if displaying 1100fef5d1ffSmrg only a subsection, and I don't want to go through the 1101fef5d1ffSmrg trouble of creating subregions to send */ 1102fef5d1ffSmrg Data(dpy, (char *) image->data, image->data_size); 1103fef5d1ffSmrg 1104fef5d1ffSmrg UnlockDisplay(dpy); 1105fef5d1ffSmrg SyncHandle(); 1106fef5d1ffSmrg 1107fef5d1ffSmrg return Success; 11089f606849Smrg} 11099f606849Smrg 1110fef5d1ffSmrgint 1111fef5d1ffSmrgXvShmPutImage( 1112fef5d1ffSmrg Display *dpy, 1113fef5d1ffSmrg XvPortID port, 1114fef5d1ffSmrg Drawable d, 1115fef5d1ffSmrg GC gc, 1116fef5d1ffSmrg XvImage *image, 1117fef5d1ffSmrg int src_x, int src_y, 1118fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1119fef5d1ffSmrg int dest_x, int dest_y, 1120fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h, 1121fef5d1ffSmrg Bool send_event) 1122fef5d1ffSmrg{ 1123fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1124fef5d1ffSmrg XShmSegmentInfo *shminfo = (XShmSegmentInfo *) image->obdata; 1125fef5d1ffSmrg xvShmPutImageReq *req; 1126fef5d1ffSmrg 1127fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1128fef5d1ffSmrg 1129fef5d1ffSmrg LockDisplay(dpy); 1130fef5d1ffSmrg 1131fef5d1ffSmrg FlushGC(dpy, gc); 1132fef5d1ffSmrg 1133fef5d1ffSmrg XvGetReq(ShmPutImage, req); 1134fef5d1ffSmrg 1135949d0342Smrg req->port = (CARD32) port; 1136949d0342Smrg req->drawable = (CARD32) d; 1137949d0342Smrg req->gc = (CARD32) gc->gid; 1138949d0342Smrg req->shmseg = (CARD32) shminfo->shmseg; 1139949d0342Smrg req->id = (CARD32) image->id; 1140949d0342Smrg req->src_x = (INT16) src_x; 1141949d0342Smrg req->src_y = (INT16) src_y; 1142949d0342Smrg req->src_w = (CARD16) src_w; 1143949d0342Smrg req->src_h = (CARD16) src_h; 1144949d0342Smrg req->drw_x = (INT16) dest_x; 1145949d0342Smrg req->drw_y = (INT16) dest_y; 1146949d0342Smrg req->drw_w = (CARD16) dest_w; 1147949d0342Smrg req->drw_h = (CARD16) dest_h; 1148949d0342Smrg req->offset = (CARD32) (image->data - shminfo->shmaddr); 1149949d0342Smrg req->width = (CARD16) image->width; 1150949d0342Smrg req->height = (CARD16) image->height; 1151949d0342Smrg req->send_event = (CARD8) send_event; 1152fef5d1ffSmrg 1153fef5d1ffSmrg UnlockDisplay(dpy); 1154fef5d1ffSmrg SyncHandle(); 1155fef5d1ffSmrg 1156fef5d1ffSmrg return Success; 11579f606849Smrg} 11589f606849Smrg 11599f606849Smrg 11609f606849Smrgstatic Bool 11619f606849Smrgxv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) 11629f606849Smrg{ 1163fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1164fef5d1ffSmrg XvEvent *re = (XvEvent *) host; 1165fef5d1ffSmrg xvEvent *event = (xvEvent *) wire; 11669f606849Smrg 1167fef5d1ffSmrg XvCheckExtension(dpy, info, False); 11689f606849Smrg 1169fef5d1ffSmrg switch ((event->u.u.type & 0x7F) - info->codes->first_event) { 11709f606849Smrg case XvVideoNotify: 1171fef5d1ffSmrg re->xvvideo.type = event->u.u.type & 0x7f; 1172fef5d1ffSmrg re->xvvideo.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1173fef5d1ffSmrg re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); 1174fef5d1ffSmrg re->xvvideo.display = dpy; 1175fef5d1ffSmrg re->xvvideo.time = event->u.videoNotify.time; 1176fef5d1ffSmrg re->xvvideo.reason = event->u.videoNotify.reason; 1177fef5d1ffSmrg re->xvvideo.drawable = event->u.videoNotify.drawable; 1178fef5d1ffSmrg re->xvvideo.port_id = event->u.videoNotify.port; 1179fef5d1ffSmrg break; 11809f606849Smrg case XvPortNotify: 1181fef5d1ffSmrg re->xvport.type = event->u.u.type & 0x7f; 1182fef5d1ffSmrg re->xvport.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1183fef5d1ffSmrg re->xvport.send_event = ((event->u.u.type & 0x80) != 0); 1184fef5d1ffSmrg re->xvport.display = dpy; 1185fef5d1ffSmrg re->xvport.time = event->u.portNotify.time; 1186fef5d1ffSmrg re->xvport.port_id = event->u.portNotify.port; 1187fef5d1ffSmrg re->xvport.attribute = event->u.portNotify.attribute; 1188fef5d1ffSmrg re->xvport.value = event->u.portNotify.value; 1189fef5d1ffSmrg break; 11909f606849Smrg default: 1191fef5d1ffSmrg return False; 1192fef5d1ffSmrg } 11939f606849Smrg 1194fef5d1ffSmrg return (True); 11959f606849Smrg} 1196