Xv.c revision 444fb138
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; 135fef5d1ffSmrg *p_requestBase = info->codes->major_opcode; 136fef5d1ffSmrg *p_eventBase = info->codes->first_event; 137fef5d1ffSmrg *p_errorBase = 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 unsigned int ii, jj; 160fef5d1ffSmrg char *name; 161444fb138Smrg char *end; 162fef5d1ffSmrg XvAdaptorInfo *pas = NULL, *pa; 163fef5d1ffSmrg XvFormat *pfs, *pf; 164fef5d1ffSmrg char *buffer = NULL; 165fef5d1ffSmrg union { 166fef5d1ffSmrg char *buffer; 167fef5d1ffSmrg char *string; 168fef5d1ffSmrg xvAdaptorInfo *pa; 169fef5d1ffSmrg xvFormat *pf; 1709f606849Smrg } u; 171fef5d1ffSmrg int status; 172fef5d1ffSmrg 173fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 174fef5d1ffSmrg 175fef5d1ffSmrg LockDisplay(dpy); 176fef5d1ffSmrg 177fef5d1ffSmrg XvGetReq(QueryAdaptors, req); 178fef5d1ffSmrg req->window = window; 179fef5d1ffSmrg 180fef5d1ffSmrg /* READ THE REPLY */ 181fef5d1ffSmrg 182fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 183fef5d1ffSmrg rep.num_adaptors = 0; 184fef5d1ffSmrg status = XvBadReply; 185fef5d1ffSmrg goto out; 186fef5d1ffSmrg } 187fef5d1ffSmrg 188fef5d1ffSmrg size = rep.length << 2; 189fef5d1ffSmrg if (size > 0) { 190fef5d1ffSmrg if ((buffer = Xmalloc(size)) == NULL) { 191fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 192fef5d1ffSmrg status = XvBadAlloc; 193fef5d1ffSmrg goto out; 194fef5d1ffSmrg } 195fef5d1ffSmrg _XRead(dpy, buffer, (long) size); 196fef5d1ffSmrg } 197fef5d1ffSmrg 198fef5d1ffSmrg /* GET INPUT ADAPTORS */ 199fef5d1ffSmrg 200fef5d1ffSmrg if (rep.num_adaptors == 0) { 201444fb138Smrg /* If there are no adaptors, there's nothing more to do. */ 202fef5d1ffSmrg status = Success; 203fef5d1ffSmrg goto out; 204fef5d1ffSmrg } 205fef5d1ffSmrg 206444fb138Smrg u.buffer = buffer; 207444fb138Smrg end = buffer + size; 208fef5d1ffSmrg 209fef5d1ffSmrg size = rep.num_adaptors * sizeof(XvAdaptorInfo); 210fef5d1ffSmrg if ((pas = Xmalloc(size)) == NULL) { 211fef5d1ffSmrg status = XvBadAlloc; 212fef5d1ffSmrg goto out; 213fef5d1ffSmrg } 214fef5d1ffSmrg 215fef5d1ffSmrg /* INIT ADAPTOR FIELDS */ 216fef5d1ffSmrg 217fef5d1ffSmrg pa = pas; 218fef5d1ffSmrg for (ii = 0; ii < rep.num_adaptors; ii++) { 219fef5d1ffSmrg pa->num_adaptors = 0; 220fef5d1ffSmrg pa->name = (char *) NULL; 221fef5d1ffSmrg pa->formats = (XvFormat *) NULL; 222fef5d1ffSmrg pa++; 223fef5d1ffSmrg } 224fef5d1ffSmrg 225fef5d1ffSmrg pa = pas; 226fef5d1ffSmrg for (ii = 0; ii < rep.num_adaptors; ii++) { 227444fb138Smrg if (u.buffer + sz_xvAdaptorInfo > end) { 228444fb138Smrg status = XvBadReply; 229444fb138Smrg goto out; 230444fb138Smrg } 231fef5d1ffSmrg pa->type = 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; 265fef5d1ffSmrg for (jj = 0; jj < pa->num_formats; jj++) { 266444fb138Smrg if (u.buffer + sz_xvFormat > end) { 267444fb138Smrg Xfree(pfs); 268444fb138Smrg status = XvBadReply; 269444fb138Smrg goto out; 270444fb138Smrg } 271fef5d1ffSmrg pf->depth = 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; 307fef5d1ffSmrg unsigned int ii; 3089f606849Smrg 309fef5d1ffSmrg if (!pAdaptors) 310fef5d1ffSmrg return; 3119f606849Smrg 312fef5d1ffSmrg pa = pAdaptors; 3139f606849Smrg 314fef5d1ffSmrg for (ii = 0; ii < pAdaptors->num_adaptors; ii++, pa++) { 315fef5d1ffSmrg if (pa->name) { 316fef5d1ffSmrg Xfree(pa->name); 317fef5d1ffSmrg } 318fef5d1ffSmrg if (pa->formats) { 319fef5d1ffSmrg Xfree(pa->formats); 320fef5d1ffSmrg } 321cdbfa18aSmrg } 3229f606849Smrg 323fef5d1ffSmrg Xfree(pAdaptors); 3249f606849Smrg} 3259f606849Smrg 3269f606849Smrgint 3279f606849SmrgXvQueryEncodings( 328fef5d1ffSmrg Display *dpy, 329fef5d1ffSmrg XvPortID port, 330fef5d1ffSmrg unsigned int *p_nEncodings, 331fef5d1ffSmrg XvEncodingInfo ** p_pEncodings) 332fef5d1ffSmrg{ 333fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 334fef5d1ffSmrg xvQueryEncodingsReq *req; 335fef5d1ffSmrg xvQueryEncodingsReply rep; 336fef5d1ffSmrg size_t size; 337fef5d1ffSmrg unsigned int jj; 338fef5d1ffSmrg char *name; 339444fb138Smrg char *end; 340fef5d1ffSmrg XvEncodingInfo *pes = NULL, *pe; 341fef5d1ffSmrg char *buffer = NULL; 342fef5d1ffSmrg union { 343fef5d1ffSmrg char *buffer; 344fef5d1ffSmrg char *string; 345fef5d1ffSmrg xvEncodingInfo *pe; 3469f606849Smrg } u; 347fef5d1ffSmrg int status; 348fef5d1ffSmrg 349fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 350fef5d1ffSmrg 351fef5d1ffSmrg LockDisplay(dpy); 352fef5d1ffSmrg 353fef5d1ffSmrg XvGetReq(QueryEncodings, req); 354fef5d1ffSmrg req->port = port; 355fef5d1ffSmrg 356fef5d1ffSmrg /* READ THE REPLY */ 357fef5d1ffSmrg 358fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 359fef5d1ffSmrg rep.num_encodings = 0; 360fef5d1ffSmrg status = XvBadReply; 361fef5d1ffSmrg goto out; 362fef5d1ffSmrg } 363cdbfa18aSmrg 364fef5d1ffSmrg size = rep.length << 2; 365fef5d1ffSmrg if (size > 0) { 366fef5d1ffSmrg if ((buffer = Xmalloc(size)) == NULL) { 367fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 368fef5d1ffSmrg status = XvBadAlloc; 369fef5d1ffSmrg goto out; 370fef5d1ffSmrg } 371fef5d1ffSmrg _XRead(dpy, buffer, (long) size); 372fef5d1ffSmrg } 373fef5d1ffSmrg 374fef5d1ffSmrg /* GET ENCODINGS */ 375fef5d1ffSmrg 376fef5d1ffSmrg if (rep.num_encodings == 0) { 377444fb138Smrg /* If there are no encodings, there's nothing more to do. */ 378fef5d1ffSmrg status = Success; 379fef5d1ffSmrg goto out; 380fef5d1ffSmrg } 381fef5d1ffSmrg 382444fb138Smrg u.buffer = buffer; 383444fb138Smrg end = buffer + size; 384fef5d1ffSmrg 385fef5d1ffSmrg size = rep.num_encodings * sizeof(XvEncodingInfo); 386fef5d1ffSmrg if ((pes = Xmalloc(size)) == NULL) { 387fef5d1ffSmrg status = XvBadAlloc; 388fef5d1ffSmrg goto out; 389fef5d1ffSmrg } 390fef5d1ffSmrg 391fef5d1ffSmrg /* INITIALIZE THE ENCODING POINTER */ 392fef5d1ffSmrg 393fef5d1ffSmrg pe = pes; 394fef5d1ffSmrg for (jj = 0; jj < rep.num_encodings; jj++) { 395fef5d1ffSmrg pe->name = (char *) NULL; 396fef5d1ffSmrg pe->num_encodings = 0; 397fef5d1ffSmrg pe++; 398fef5d1ffSmrg } 399fef5d1ffSmrg 400fef5d1ffSmrg pe = pes; 401fef5d1ffSmrg for (jj = 0; jj < rep.num_encodings; jj++) { 402444fb138Smrg if (u.buffer + sz_xvEncodingInfo > end) { 403444fb138Smrg status = XvBadReply; 404444fb138Smrg goto out; 405444fb138Smrg } 406fef5d1ffSmrg pe->encoding_id = u.pe->encoding; 407fef5d1ffSmrg pe->width = u.pe->width; 408fef5d1ffSmrg pe->height = u.pe->height; 409fef5d1ffSmrg pe->rate.numerator = u.pe->rate.numerator; 410fef5d1ffSmrg pe->rate.denominator = u.pe->rate.denominator; 411fef5d1ffSmrg pe->num_encodings = rep.num_encodings - jj; 412fef5d1ffSmrg 413fef5d1ffSmrg size = u.pe->name_size; 414fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvEncodingInfo); 415fef5d1ffSmrg 416444fb138Smrg if (u.buffer + size > end) { 417444fb138Smrg status = XvBadReply; 418444fb138Smrg goto out; 419444fb138Smrg } 420fef5d1ffSmrg if ((name = Xmalloc(size + 1)) == NULL) { 421fef5d1ffSmrg status = XvBadAlloc; 422fef5d1ffSmrg goto out; 423fef5d1ffSmrg } 424fef5d1ffSmrg strncpy(name, u.string, size); 425fef5d1ffSmrg name[size] = '\0'; 426fef5d1ffSmrg pe->name = name; 427fef5d1ffSmrg pe++; 428fef5d1ffSmrg 429fef5d1ffSmrg u.buffer += pad_to_int32(size); 430fef5d1ffSmrg } 431fef5d1ffSmrg 432fef5d1ffSmrg status = Success; 433fef5d1ffSmrg 434fef5d1ffSmrg out: 435fef5d1ffSmrg if (status != Success) { 436fef5d1ffSmrg XvFreeEncodingInfo(pes); 437fef5d1ffSmrg pes = NULL; 438fef5d1ffSmrg } 439fef5d1ffSmrg 440fef5d1ffSmrg *p_nEncodings = rep.num_encodings; 441fef5d1ffSmrg *p_pEncodings = pes; 442fef5d1ffSmrg 443fef5d1ffSmrg Xfree(buffer); 444fef5d1ffSmrg UnlockDisplay(dpy); 445fef5d1ffSmrg SyncHandle(); 446fef5d1ffSmrg 447fef5d1ffSmrg return (Success); 4489f606849Smrg} 4499f606849Smrg 4509f606849Smrgvoid 4519f606849SmrgXvFreeEncodingInfo(XvEncodingInfo *pEncodings) 4529f606849Smrg{ 453fef5d1ffSmrg XvEncodingInfo *pe; 454fef5d1ffSmrg unsigned long ii; 4559f606849Smrg 456fef5d1ffSmrg if (!pEncodings) 457fef5d1ffSmrg return; 4589f606849Smrg 459fef5d1ffSmrg pe = pEncodings; 4609f606849Smrg 461fef5d1ffSmrg for (ii = 0; ii < pEncodings->num_encodings; ii++, pe++) { 462fef5d1ffSmrg if (pe->name) 463fef5d1ffSmrg Xfree(pe->name); 464fef5d1ffSmrg } 4659f606849Smrg 466fef5d1ffSmrg Xfree(pEncodings); 4679f606849Smrg} 4689f606849Smrg 4699f606849Smrgint 4709f606849SmrgXvPutVideo( 471fef5d1ffSmrg Display *dpy, 472fef5d1ffSmrg XvPortID port, 473fef5d1ffSmrg Drawable d, 474fef5d1ffSmrg GC gc, 475fef5d1ffSmrg int vx, int vy, 476fef5d1ffSmrg unsigned int vw, unsigned int vh, 477fef5d1ffSmrg int dx, int dy, 478fef5d1ffSmrg unsigned int dw, unsigned int dh) 479fef5d1ffSmrg{ 480fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 481fef5d1ffSmrg xvPutVideoReq *req; 482fef5d1ffSmrg 483fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 484fef5d1ffSmrg 485fef5d1ffSmrg LockDisplay(dpy); 486fef5d1ffSmrg 487fef5d1ffSmrg FlushGC(dpy, gc); 488fef5d1ffSmrg 489fef5d1ffSmrg XvGetReq(PutVideo, req); 490fef5d1ffSmrg 491fef5d1ffSmrg req->port = port; 492fef5d1ffSmrg req->drawable = d; 493fef5d1ffSmrg req->gc = gc->gid; 494fef5d1ffSmrg req->vid_x = vx; 495fef5d1ffSmrg req->vid_y = vy; 496fef5d1ffSmrg req->vid_w = vw; 497fef5d1ffSmrg req->vid_h = vh; 498fef5d1ffSmrg req->drw_x = dx; 499fef5d1ffSmrg req->drw_y = dy; 500fef5d1ffSmrg req->drw_w = dw; 501fef5d1ffSmrg req->drw_h = dh; 502fef5d1ffSmrg 503fef5d1ffSmrg UnlockDisplay(dpy); 504fef5d1ffSmrg SyncHandle(); 505fef5d1ffSmrg 506fef5d1ffSmrg return Success; 5079f606849Smrg} 5089f606849Smrg 5099f606849Smrgint 5109f606849SmrgXvPutStill( 511fef5d1ffSmrg Display *dpy, 512fef5d1ffSmrg XvPortID port, 513fef5d1ffSmrg Drawable d, 514fef5d1ffSmrg GC gc, 515fef5d1ffSmrg int vx, int vy, 516fef5d1ffSmrg unsigned int vw, unsigned int vh, 517fef5d1ffSmrg int dx, int dy, 518fef5d1ffSmrg unsigned int dw, unsigned int dh) 519fef5d1ffSmrg{ 520fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 521fef5d1ffSmrg xvPutStillReq *req; 522fef5d1ffSmrg 523fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 524fef5d1ffSmrg 525fef5d1ffSmrg LockDisplay(dpy); 526fef5d1ffSmrg 527fef5d1ffSmrg FlushGC(dpy, gc); 528fef5d1ffSmrg 529fef5d1ffSmrg XvGetReq(PutStill, req); 530fef5d1ffSmrg req->port = port; 531fef5d1ffSmrg req->drawable = d; 532fef5d1ffSmrg req->gc = gc->gid; 533fef5d1ffSmrg req->vid_x = vx; 534fef5d1ffSmrg req->vid_y = vy; 535fef5d1ffSmrg req->vid_w = vw; 536fef5d1ffSmrg req->vid_h = vh; 537fef5d1ffSmrg req->drw_x = dx; 538fef5d1ffSmrg req->drw_y = dy; 539fef5d1ffSmrg req->drw_w = dw; 540fef5d1ffSmrg req->drw_h = dh; 541fef5d1ffSmrg 542fef5d1ffSmrg UnlockDisplay(dpy); 543fef5d1ffSmrg SyncHandle(); 544fef5d1ffSmrg 545fef5d1ffSmrg return Success; 5469f606849Smrg} 5479f606849Smrg 5489f606849Smrgint 5499f606849SmrgXvGetVideo( 550fef5d1ffSmrg Display *dpy, 551fef5d1ffSmrg XvPortID port, 552fef5d1ffSmrg Drawable d, 553fef5d1ffSmrg GC gc, 554fef5d1ffSmrg int vx, int vy, 555fef5d1ffSmrg unsigned int vw, unsigned int vh, 556fef5d1ffSmrg int dx, int dy, 557fef5d1ffSmrg unsigned int dw, unsigned int dh) 558fef5d1ffSmrg{ 559fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 560fef5d1ffSmrg xvGetVideoReq *req; 561fef5d1ffSmrg 562fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 563fef5d1ffSmrg 564fef5d1ffSmrg LockDisplay(dpy); 565fef5d1ffSmrg 566fef5d1ffSmrg FlushGC(dpy, gc); 567fef5d1ffSmrg 568fef5d1ffSmrg XvGetReq(GetVideo, req); 569fef5d1ffSmrg req->port = port; 570fef5d1ffSmrg req->drawable = d; 571fef5d1ffSmrg req->gc = gc->gid; 572fef5d1ffSmrg req->vid_x = vx; 573fef5d1ffSmrg req->vid_y = vy; 574fef5d1ffSmrg req->vid_w = vw; 575fef5d1ffSmrg req->vid_h = vh; 576fef5d1ffSmrg req->drw_x = dx; 577fef5d1ffSmrg req->drw_y = dy; 578fef5d1ffSmrg req->drw_w = dw; 579fef5d1ffSmrg req->drw_h = dh; 580fef5d1ffSmrg 581fef5d1ffSmrg UnlockDisplay(dpy); 582fef5d1ffSmrg SyncHandle(); 583fef5d1ffSmrg 584fef5d1ffSmrg return Success; 5859f606849Smrg} 5869f606849Smrg 5879f606849Smrgint 5889f606849SmrgXvGetStill( 589fef5d1ffSmrg Display *dpy, 590fef5d1ffSmrg XvPortID port, 591fef5d1ffSmrg Drawable d, 592fef5d1ffSmrg GC gc, 593fef5d1ffSmrg int vx, int vy, 594fef5d1ffSmrg unsigned int vw, unsigned int vh, 595fef5d1ffSmrg int dx, int dy, 596fef5d1ffSmrg unsigned int dw, unsigned int dh) 597fef5d1ffSmrg{ 598fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 599fef5d1ffSmrg xvGetStillReq *req; 600fef5d1ffSmrg 601fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 602fef5d1ffSmrg 603fef5d1ffSmrg LockDisplay(dpy); 604fef5d1ffSmrg 605fef5d1ffSmrg FlushGC(dpy, gc); 606fef5d1ffSmrg 607fef5d1ffSmrg XvGetReq(GetStill, req); 608fef5d1ffSmrg req->port = port; 609fef5d1ffSmrg req->drawable = d; 610fef5d1ffSmrg req->gc = gc->gid; 611fef5d1ffSmrg req->vid_x = vx; 612fef5d1ffSmrg req->vid_y = vy; 613fef5d1ffSmrg req->vid_w = vw; 614fef5d1ffSmrg req->vid_h = vh; 615fef5d1ffSmrg req->drw_x = dx; 616fef5d1ffSmrg req->drw_y = dy; 617fef5d1ffSmrg req->drw_w = dw; 618fef5d1ffSmrg req->drw_h = dh; 619fef5d1ffSmrg 620fef5d1ffSmrg UnlockDisplay(dpy); 621fef5d1ffSmrg SyncHandle(); 622fef5d1ffSmrg 623fef5d1ffSmrg return Success; 6249f606849Smrg} 6259f606849Smrg 6269f606849Smrgint 627fef5d1ffSmrgXvStopVideo(Display *dpy, XvPortID port, Drawable draw) 628fef5d1ffSmrg{ 629fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 630fef5d1ffSmrg xvStopVideoReq *req; 6319f606849Smrg 632fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6339f606849Smrg 634fef5d1ffSmrg LockDisplay(dpy); 6359f606849Smrg 636fef5d1ffSmrg XvGetReq(StopVideo, req); 637fef5d1ffSmrg req->port = port; 638fef5d1ffSmrg req->drawable = draw; 6399f606849Smrg 640fef5d1ffSmrg UnlockDisplay(dpy); 641fef5d1ffSmrg SyncHandle(); 6429f606849Smrg 643fef5d1ffSmrg return Success; 6449f606849Smrg} 6459f606849Smrg 6469f606849Smrgint 647fef5d1ffSmrgXvGrabPort(Display *dpy, XvPortID port, Time time) 648fef5d1ffSmrg{ 649fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 650fef5d1ffSmrg int result; 651fef5d1ffSmrg xvGrabPortReply rep; 652fef5d1ffSmrg xvGrabPortReq *req; 6539f606849Smrg 654fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6559f606849Smrg 656fef5d1ffSmrg LockDisplay(dpy); 6579f606849Smrg 658fef5d1ffSmrg XvGetReq(GrabPort, req); 659fef5d1ffSmrg req->port = port; 660fef5d1ffSmrg req->time = time; 6619f606849Smrg 662fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xTrue) == 0) 663fef5d1ffSmrg rep.result = GrabSuccess; 6649f606849Smrg 665fef5d1ffSmrg result = rep.result; 6669f606849Smrg 667fef5d1ffSmrg UnlockDisplay(dpy); 668fef5d1ffSmrg SyncHandle(); 6699f606849Smrg 670fef5d1ffSmrg return result; 6719f606849Smrg} 6729f606849Smrg 6739f606849Smrgint 674fef5d1ffSmrgXvUngrabPort(Display *dpy, XvPortID port, Time time) 675fef5d1ffSmrg{ 676fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 677fef5d1ffSmrg xvUngrabPortReq *req; 6789f606849Smrg 679fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6809f606849Smrg 681fef5d1ffSmrg LockDisplay(dpy); 6829f606849Smrg 683fef5d1ffSmrg XvGetReq(UngrabPort, req); 684fef5d1ffSmrg req->port = port; 685fef5d1ffSmrg req->time = time; 6869f606849Smrg 687fef5d1ffSmrg UnlockDisplay(dpy); 688fef5d1ffSmrg SyncHandle(); 6899f606849Smrg 690fef5d1ffSmrg return Success; 6919f606849Smrg} 6929f606849Smrg 6939f606849Smrgint 694fef5d1ffSmrgXvSelectVideoNotify(Display *dpy, Drawable drawable, Bool onoff) 695fef5d1ffSmrg{ 696fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 697fef5d1ffSmrg xvSelectVideoNotifyReq *req; 6989f606849Smrg 699fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7009f606849Smrg 701fef5d1ffSmrg LockDisplay(dpy); 7029f606849Smrg 703fef5d1ffSmrg XvGetReq(SelectVideoNotify, req); 704fef5d1ffSmrg req->drawable = drawable; 705fef5d1ffSmrg req->onoff = onoff; 7069f606849Smrg 707fef5d1ffSmrg UnlockDisplay(dpy); 708fef5d1ffSmrg SyncHandle(); 7099f606849Smrg 710fef5d1ffSmrg return Success; 7119f606849Smrg} 7129f606849Smrg 7139f606849Smrgint 714fef5d1ffSmrgXvSelectPortNotify(Display *dpy, XvPortID port, Bool onoff) 715fef5d1ffSmrg{ 716fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 717fef5d1ffSmrg xvSelectPortNotifyReq *req; 7189f606849Smrg 719fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7209f606849Smrg 721fef5d1ffSmrg LockDisplay(dpy); 7229f606849Smrg 723fef5d1ffSmrg XvGetReq(SelectPortNotify, req); 724fef5d1ffSmrg req->port = port; 725fef5d1ffSmrg req->onoff = onoff; 7269f606849Smrg 727fef5d1ffSmrg UnlockDisplay(dpy); 728fef5d1ffSmrg SyncHandle(); 7299f606849Smrg 730fef5d1ffSmrg return Success; 7319f606849Smrg} 7329f606849Smrg 7339f606849Smrgint 734fef5d1ffSmrgXvSetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int value) 7359f606849Smrg{ 736fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 737fef5d1ffSmrg xvSetPortAttributeReq *req; 7389f606849Smrg 739fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7409f606849Smrg 741fef5d1ffSmrg LockDisplay(dpy); 7429f606849Smrg 743fef5d1ffSmrg XvGetReq(SetPortAttribute, req); 744fef5d1ffSmrg req->port = port; 745fef5d1ffSmrg req->attribute = attribute; 746fef5d1ffSmrg req->value = value; 7479f606849Smrg 748fef5d1ffSmrg UnlockDisplay(dpy); 749fef5d1ffSmrg SyncHandle(); 7509f606849Smrg 751fef5d1ffSmrg return (Success); 7529f606849Smrg} 7539f606849Smrg 7549f606849Smrgint 755fef5d1ffSmrgXvGetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int *p_value) 7569f606849Smrg{ 757fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 758fef5d1ffSmrg xvGetPortAttributeReq *req; 759fef5d1ffSmrg xvGetPortAttributeReply rep; 760fef5d1ffSmrg int status; 7619f606849Smrg 762fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7639f606849Smrg 764fef5d1ffSmrg LockDisplay(dpy); 7659f606849Smrg 766fef5d1ffSmrg XvGetReq(GetPortAttribute, req); 767fef5d1ffSmrg req->port = port; 768fef5d1ffSmrg req->attribute = attribute; 7699f606849Smrg 770fef5d1ffSmrg /* READ THE REPLY */ 7719f606849Smrg 772fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 773fef5d1ffSmrg status = XvBadReply; 774fef5d1ffSmrg } 775fef5d1ffSmrg else { 776fef5d1ffSmrg *p_value = rep.value; 777fef5d1ffSmrg status = Success; 778fef5d1ffSmrg } 779cdbfa18aSmrg 780fef5d1ffSmrg UnlockDisplay(dpy); 781fef5d1ffSmrg SyncHandle(); 7829f606849Smrg 783fef5d1ffSmrg return status; 7849f606849Smrg} 7859f606849Smrg 7869f606849Smrgint 7879f606849SmrgXvQueryBestSize( 788fef5d1ffSmrg Display *dpy, 789fef5d1ffSmrg XvPortID port, 790fef5d1ffSmrg Bool motion, 791fef5d1ffSmrg unsigned int vid_w, 792fef5d1ffSmrg unsigned int vid_h, 793fef5d1ffSmrg unsigned int drw_w, 794fef5d1ffSmrg unsigned int drw_h, 795fef5d1ffSmrg unsigned int *p_actual_width, 796fef5d1ffSmrg unsigned int *p_actual_height) 7979f606849Smrg{ 798fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 799fef5d1ffSmrg xvQueryBestSizeReq *req; 800fef5d1ffSmrg xvQueryBestSizeReply rep; 801fef5d1ffSmrg int status; 8029f606849Smrg 803fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 8049f606849Smrg 805fef5d1ffSmrg LockDisplay(dpy); 8069f606849Smrg 807fef5d1ffSmrg XvGetReq(QueryBestSize, req); 808fef5d1ffSmrg req->port = port; 809fef5d1ffSmrg req->motion = motion; 810fef5d1ffSmrg req->vid_w = vid_w; 811fef5d1ffSmrg req->vid_h = vid_h; 812fef5d1ffSmrg req->drw_w = drw_w; 813fef5d1ffSmrg req->drw_h = drw_h; 8149f606849Smrg 815fef5d1ffSmrg /* READ THE REPLY */ 8169f606849Smrg 817fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 818fef5d1ffSmrg status = XvBadReply; 819fef5d1ffSmrg } 820fef5d1ffSmrg else { 821fef5d1ffSmrg *p_actual_width = rep.actual_width; 822fef5d1ffSmrg *p_actual_height = rep.actual_height; 823fef5d1ffSmrg status = Success; 824fef5d1ffSmrg } 8259f606849Smrg 826fef5d1ffSmrg UnlockDisplay(dpy); 827fef5d1ffSmrg SyncHandle(); 8289f606849Smrg 829fef5d1ffSmrg return status; 8309f606849Smrg} 8319f606849Smrg 8329f606849Smrg 833fef5d1ffSmrgXvAttribute * 8349f606849SmrgXvQueryPortAttributes(Display *dpy, XvPortID port, int *num) 8359f606849Smrg{ 836fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 837fef5d1ffSmrg xvQueryPortAttributesReq *req; 838fef5d1ffSmrg xvQueryPortAttributesReply rep; 839fef5d1ffSmrg XvAttribute *ret = NULL; 840fef5d1ffSmrg 841fef5d1ffSmrg *num = 0; 842fef5d1ffSmrg 843fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 844fef5d1ffSmrg 845fef5d1ffSmrg LockDisplay(dpy); 846fef5d1ffSmrg 847fef5d1ffSmrg XvGetReq(QueryPortAttributes, req); 848fef5d1ffSmrg req->port = port; 849fef5d1ffSmrg 850fef5d1ffSmrg /* READ THE REPLY */ 851fef5d1ffSmrg 852fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 853fef5d1ffSmrg goto out; 854fef5d1ffSmrg } 855fef5d1ffSmrg 856fef5d1ffSmrg /* 857fef5d1ffSmrg * X server sends data packed as: 858fef5d1ffSmrg * attribute1, name1, attribute2, name2, ... 859fef5d1ffSmrg * We allocate a single buffer large enough to hold them all and 860fef5d1ffSmrg * then de-interleave the data so we return it to clients as: 861fef5d1ffSmrg * attribute1, attribute2, ..., name1, name2, ... 862fef5d1ffSmrg * so that clients may refer to attributes as a simple array of 863fef5d1ffSmrg * structs: attributes[0], attributes[1], ... 864fef5d1ffSmrg * and free it as a single/simple buffer. 865fef5d1ffSmrg */ 866fef5d1ffSmrg 867fef5d1ffSmrg if (rep.num_attributes) { 868fef5d1ffSmrg unsigned long size; 869fef5d1ffSmrg 870fef5d1ffSmrg /* limit each part to no more than one half the max size */ 871fef5d1ffSmrg if ((rep.num_attributes < ((INT_MAX / 2) / sizeof(XvAttribute))) && 872fef5d1ffSmrg (rep.text_size < (INT_MAX / 2) - 1)) { 873fef5d1ffSmrg size = (rep.num_attributes * sizeof(XvAttribute)) + 874fef5d1ffSmrg rep.text_size + 1; 875fef5d1ffSmrg ret = Xmalloc(size); 876fef5d1ffSmrg } 877fef5d1ffSmrg 878fef5d1ffSmrg if (ret != NULL) { 879fef5d1ffSmrg char *marker = (char *) (&ret[rep.num_attributes]); 880fef5d1ffSmrg xvAttributeInfo Info; 881fef5d1ffSmrg unsigned int i; 882fef5d1ffSmrg 883fef5d1ffSmrg /* keep track of remaining room for text strings */ 884fef5d1ffSmrg size = rep.text_size; 885fef5d1ffSmrg 886fef5d1ffSmrg for (i = 0; i < rep.num_attributes; i++) { 887fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvAttributeInfo); 888fef5d1ffSmrg ret[i].flags = (int) Info.flags; 889fef5d1ffSmrg ret[i].min_value = Info.min; 890fef5d1ffSmrg ret[i].max_value = Info.max; 891fef5d1ffSmrg ret[i].name = marker; 892fef5d1ffSmrg if (Info.size <= size) { 893fef5d1ffSmrg _XRead(dpy, marker, Info.size); 894fef5d1ffSmrg marker += Info.size; 895fef5d1ffSmrg size -= Info.size; 896fef5d1ffSmrg } 897fef5d1ffSmrg (*num)++; 898fef5d1ffSmrg } 899fef5d1ffSmrg 900fef5d1ffSmrg /* ensure final string is nil-terminated to avoid exposure of 901fef5d1ffSmrg uninitialized memory */ 902fef5d1ffSmrg *marker = '\0'; 903fef5d1ffSmrg } 904fef5d1ffSmrg else 905fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 906fef5d1ffSmrg } 907fef5d1ffSmrg 908fef5d1ffSmrg out: 909fef5d1ffSmrg UnlockDisplay(dpy); 910fef5d1ffSmrg SyncHandle(); 911fef5d1ffSmrg 912fef5d1ffSmrg return ret; 9139f606849Smrg} 9149f606849Smrg 915fef5d1ffSmrgXvImageFormatValues * 916fef5d1ffSmrgXvListImageFormats(Display *dpy, XvPortID port, int *num) 917fef5d1ffSmrg{ 918fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 919fef5d1ffSmrg xvListImageFormatsReq *req; 920fef5d1ffSmrg xvListImageFormatsReply rep; 921fef5d1ffSmrg XvImageFormatValues *ret = NULL; 922fef5d1ffSmrg 923fef5d1ffSmrg *num = 0; 924fef5d1ffSmrg 925fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 926fef5d1ffSmrg 927fef5d1ffSmrg LockDisplay(dpy); 928fef5d1ffSmrg 929fef5d1ffSmrg XvGetReq(ListImageFormats, req); 930fef5d1ffSmrg req->port = port; 931fef5d1ffSmrg 932fef5d1ffSmrg /* READ THE REPLY */ 933fef5d1ffSmrg 934fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 935fef5d1ffSmrg goto out; 936fef5d1ffSmrg } 937fef5d1ffSmrg 938fef5d1ffSmrg if (rep.num_formats) { 939fef5d1ffSmrg if (rep.num_formats < (INT_MAX / sizeof(XvImageFormatValues))) 940fef5d1ffSmrg ret = Xmalloc(rep.num_formats * sizeof(XvImageFormatValues)); 941fef5d1ffSmrg 942fef5d1ffSmrg if (ret != NULL) { 943fef5d1ffSmrg xvImageFormatInfo Info; 944fef5d1ffSmrg unsigned int i; 945fef5d1ffSmrg 946fef5d1ffSmrg for (i = 0; i < rep.num_formats; i++) { 947fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvImageFormatInfo); 948fef5d1ffSmrg ret[i].id = Info.id; 949fef5d1ffSmrg ret[i].type = Info.type; 950fef5d1ffSmrg ret[i].byte_order = Info.byte_order; 951fef5d1ffSmrg memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); 952fef5d1ffSmrg ret[i].bits_per_pixel = Info.bpp; 953fef5d1ffSmrg ret[i].format = Info.format; 954fef5d1ffSmrg ret[i].num_planes = Info.num_planes; 955fef5d1ffSmrg ret[i].depth = Info.depth; 956fef5d1ffSmrg ret[i].red_mask = Info.red_mask; 957fef5d1ffSmrg ret[i].green_mask = Info.green_mask; 958fef5d1ffSmrg ret[i].blue_mask = Info.blue_mask; 959fef5d1ffSmrg ret[i].y_sample_bits = Info.y_sample_bits; 960fef5d1ffSmrg ret[i].u_sample_bits = Info.u_sample_bits; 961fef5d1ffSmrg ret[i].v_sample_bits = Info.v_sample_bits; 962fef5d1ffSmrg ret[i].horz_y_period = Info.horz_y_period; 963fef5d1ffSmrg ret[i].horz_u_period = Info.horz_u_period; 964fef5d1ffSmrg ret[i].horz_v_period = Info.horz_v_period; 965fef5d1ffSmrg ret[i].vert_y_period = Info.vert_y_period; 966fef5d1ffSmrg ret[i].vert_u_period = Info.vert_u_period; 967fef5d1ffSmrg ret[i].vert_v_period = Info.vert_v_period; 968fef5d1ffSmrg memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); 969fef5d1ffSmrg ret[i].scanline_order = Info.scanline_order; 970fef5d1ffSmrg (*num)++; 971fef5d1ffSmrg } 972fef5d1ffSmrg } 973fef5d1ffSmrg else 974fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 975fef5d1ffSmrg } 976fef5d1ffSmrg 977fef5d1ffSmrg out: 978fef5d1ffSmrg UnlockDisplay(dpy); 979fef5d1ffSmrg SyncHandle(); 980fef5d1ffSmrg 981fef5d1ffSmrg return ret; 9829f606849Smrg} 9839f606849Smrg 984fef5d1ffSmrgXvImage * 985fef5d1ffSmrgXvCreateImage( 986fef5d1ffSmrg Display *dpy, 987fef5d1ffSmrg XvPortID port, 988fef5d1ffSmrg int id, 989fef5d1ffSmrg char *data, 990fef5d1ffSmrg int width, 991fef5d1ffSmrg int height) 992fef5d1ffSmrg{ 993fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 994fef5d1ffSmrg xvQueryImageAttributesReq *req; 995fef5d1ffSmrg xvQueryImageAttributesReply rep; 996fef5d1ffSmrg XvImage *ret = NULL; 997fef5d1ffSmrg 998fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 999fef5d1ffSmrg 1000fef5d1ffSmrg LockDisplay(dpy); 1001fef5d1ffSmrg 1002fef5d1ffSmrg XvGetReq(QueryImageAttributes, req); 1003fef5d1ffSmrg req->id = id; 1004fef5d1ffSmrg req->port = port; 1005fef5d1ffSmrg req->width = width; 1006fef5d1ffSmrg req->height = height; 1007fef5d1ffSmrg 1008fef5d1ffSmrg /* READ THE REPLY */ 1009fef5d1ffSmrg 1010fef5d1ffSmrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 1011fef5d1ffSmrg goto out; 1012fef5d1ffSmrg } 1013fef5d1ffSmrg 1014fef5d1ffSmrg if (rep.num_planes < ((INT_MAX >> 3) - sizeof(XvImage))) 1015fef5d1ffSmrg ret = Xmalloc(sizeof(XvImage) + (rep.num_planes << 3)); 1016fef5d1ffSmrg 1017fef5d1ffSmrg if (ret != NULL) { 1018fef5d1ffSmrg ret->id = id; 1019fef5d1ffSmrg ret->width = rep.width; 1020fef5d1ffSmrg ret->height = rep.height; 1021fef5d1ffSmrg ret->data_size = rep.data_size; 1022fef5d1ffSmrg ret->num_planes = rep.num_planes; 1023fef5d1ffSmrg ret->pitches = (int *) (&ret[1]); 1024fef5d1ffSmrg ret->offsets = ret->pitches + rep.num_planes; 1025fef5d1ffSmrg ret->data = data; 1026fef5d1ffSmrg ret->obdata = NULL; 1027fef5d1ffSmrg _XRead(dpy, (char *) (ret->pitches), rep.num_planes << 2); 1028fef5d1ffSmrg _XRead(dpy, (char *) (ret->offsets), rep.num_planes << 2); 1029fef5d1ffSmrg } 1030fef5d1ffSmrg else 1031fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 1032fef5d1ffSmrg 1033fef5d1ffSmrg out: 1034fef5d1ffSmrg UnlockDisplay(dpy); 1035fef5d1ffSmrg SyncHandle(); 1036fef5d1ffSmrg 1037fef5d1ffSmrg return ret; 10389f606849Smrg} 10399f606849Smrg 1040fef5d1ffSmrgXvImage * 1041fef5d1ffSmrgXvShmCreateImage( 1042fef5d1ffSmrg Display *dpy, 1043fef5d1ffSmrg XvPortID port, 1044fef5d1ffSmrg int id, 1045fef5d1ffSmrg char *data, 1046fef5d1ffSmrg int width, 1047fef5d1ffSmrg int height, 1048fef5d1ffSmrg XShmSegmentInfo *shminfo) 1049fef5d1ffSmrg{ 1050fef5d1ffSmrg XvImage *ret; 10519f606849Smrg 1052fef5d1ffSmrg ret = XvCreateImage(dpy, port, id, data, width, height); 10539f606849Smrg 1054fef5d1ffSmrg if (ret) 1055fef5d1ffSmrg ret->obdata = (XPointer) shminfo; 10569f606849Smrg 1057fef5d1ffSmrg return ret; 10589f606849Smrg} 10599f606849Smrg 1060fef5d1ffSmrgint 1061fef5d1ffSmrgXvPutImage( 1062fef5d1ffSmrg Display *dpy, 1063fef5d1ffSmrg XvPortID port, 1064fef5d1ffSmrg Drawable d, 1065fef5d1ffSmrg GC gc, 1066fef5d1ffSmrg XvImage *image, 1067fef5d1ffSmrg int src_x, int src_y, 1068fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1069fef5d1ffSmrg int dest_x, int dest_y, 1070fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h) 1071fef5d1ffSmrg{ 1072fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1073fef5d1ffSmrg xvPutImageReq *req; 1074fef5d1ffSmrg unsigned int len; 1075fef5d1ffSmrg 1076fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1077fef5d1ffSmrg 1078fef5d1ffSmrg LockDisplay(dpy); 1079fef5d1ffSmrg 1080fef5d1ffSmrg FlushGC(dpy, gc); 1081fef5d1ffSmrg 1082fef5d1ffSmrg XvGetReq(PutImage, req); 1083fef5d1ffSmrg 1084fef5d1ffSmrg req->port = port; 1085fef5d1ffSmrg req->drawable = d; 1086fef5d1ffSmrg req->gc = gc->gid; 1087fef5d1ffSmrg req->id = image->id; 1088fef5d1ffSmrg req->src_x = src_x; 1089fef5d1ffSmrg req->src_y = src_y; 1090fef5d1ffSmrg req->src_w = src_w; 1091fef5d1ffSmrg req->src_h = src_h; 1092fef5d1ffSmrg req->drw_x = dest_x; 1093fef5d1ffSmrg req->drw_y = dest_y; 1094fef5d1ffSmrg req->drw_w = dest_w; 1095fef5d1ffSmrg req->drw_h = dest_h; 1096fef5d1ffSmrg req->width = image->width; 1097fef5d1ffSmrg req->height = image->height; 1098fef5d1ffSmrg 1099fef5d1ffSmrg len = ((unsigned int) image->data_size + 3) >> 2; 1100fef5d1ffSmrg SetReqLen(req, len, len); 1101fef5d1ffSmrg 1102fef5d1ffSmrg /* Yes it's kindof lame that we are sending the whole thing, 1103fef5d1ffSmrg but for video all of it may be needed even if displaying 1104fef5d1ffSmrg only a subsection, and I don't want to go through the 1105fef5d1ffSmrg trouble of creating subregions to send */ 1106fef5d1ffSmrg Data(dpy, (char *) image->data, image->data_size); 1107fef5d1ffSmrg 1108fef5d1ffSmrg UnlockDisplay(dpy); 1109fef5d1ffSmrg SyncHandle(); 1110fef5d1ffSmrg 1111fef5d1ffSmrg return Success; 11129f606849Smrg} 11139f606849Smrg 1114fef5d1ffSmrgint 1115fef5d1ffSmrgXvShmPutImage( 1116fef5d1ffSmrg Display *dpy, 1117fef5d1ffSmrg XvPortID port, 1118fef5d1ffSmrg Drawable d, 1119fef5d1ffSmrg GC gc, 1120fef5d1ffSmrg XvImage *image, 1121fef5d1ffSmrg int src_x, int src_y, 1122fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1123fef5d1ffSmrg int dest_x, int dest_y, 1124fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h, 1125fef5d1ffSmrg Bool send_event) 1126fef5d1ffSmrg{ 1127fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1128fef5d1ffSmrg XShmSegmentInfo *shminfo = (XShmSegmentInfo *) image->obdata; 1129fef5d1ffSmrg xvShmPutImageReq *req; 1130fef5d1ffSmrg 1131fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1132fef5d1ffSmrg 1133fef5d1ffSmrg LockDisplay(dpy); 1134fef5d1ffSmrg 1135fef5d1ffSmrg FlushGC(dpy, gc); 1136fef5d1ffSmrg 1137fef5d1ffSmrg XvGetReq(ShmPutImage, req); 1138fef5d1ffSmrg 1139fef5d1ffSmrg req->port = port; 1140fef5d1ffSmrg req->drawable = d; 1141fef5d1ffSmrg req->gc = gc->gid; 1142fef5d1ffSmrg req->shmseg = shminfo->shmseg; 1143fef5d1ffSmrg req->id = image->id; 1144fef5d1ffSmrg req->src_x = src_x; 1145fef5d1ffSmrg req->src_y = src_y; 1146fef5d1ffSmrg req->src_w = src_w; 1147fef5d1ffSmrg req->src_h = src_h; 1148fef5d1ffSmrg req->drw_x = dest_x; 1149fef5d1ffSmrg req->drw_y = dest_y; 1150fef5d1ffSmrg req->drw_w = dest_w; 1151fef5d1ffSmrg req->drw_h = dest_h; 1152fef5d1ffSmrg req->offset = image->data - shminfo->shmaddr; 1153fef5d1ffSmrg req->width = image->width; 1154fef5d1ffSmrg req->height = image->height; 1155fef5d1ffSmrg req->send_event = send_event; 1156fef5d1ffSmrg 1157fef5d1ffSmrg UnlockDisplay(dpy); 1158fef5d1ffSmrg SyncHandle(); 1159fef5d1ffSmrg 1160fef5d1ffSmrg return Success; 11619f606849Smrg} 11629f606849Smrg 11639f606849Smrg 11649f606849Smrgstatic Bool 11659f606849Smrgxv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) 11669f606849Smrg{ 1167fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1168fef5d1ffSmrg XvEvent *re = (XvEvent *) host; 1169fef5d1ffSmrg xvEvent *event = (xvEvent *) wire; 11709f606849Smrg 1171fef5d1ffSmrg XvCheckExtension(dpy, info, False); 11729f606849Smrg 1173fef5d1ffSmrg switch ((event->u.u.type & 0x7F) - info->codes->first_event) { 11749f606849Smrg case XvVideoNotify: 1175fef5d1ffSmrg re->xvvideo.type = event->u.u.type & 0x7f; 1176fef5d1ffSmrg re->xvvideo.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1177fef5d1ffSmrg re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); 1178fef5d1ffSmrg re->xvvideo.display = dpy; 1179fef5d1ffSmrg re->xvvideo.time = event->u.videoNotify.time; 1180fef5d1ffSmrg re->xvvideo.reason = event->u.videoNotify.reason; 1181fef5d1ffSmrg re->xvvideo.drawable = event->u.videoNotify.drawable; 1182fef5d1ffSmrg re->xvvideo.port_id = event->u.videoNotify.port; 1183fef5d1ffSmrg break; 11849f606849Smrg case XvPortNotify: 1185fef5d1ffSmrg re->xvport.type = event->u.u.type & 0x7f; 1186fef5d1ffSmrg re->xvport.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1187fef5d1ffSmrg re->xvport.send_event = ((event->u.u.type & 0x80) != 0); 1188fef5d1ffSmrg re->xvport.display = dpy; 1189fef5d1ffSmrg re->xvport.time = event->u.portNotify.time; 1190fef5d1ffSmrg re->xvport.port_id = event->u.portNotify.port; 1191fef5d1ffSmrg re->xvport.attribute = event->u.portNotify.attribute; 1192fef5d1ffSmrg re->xvport.value = event->u.portNotify.value; 1193fef5d1ffSmrg break; 11949f606849Smrg default: 1195fef5d1ffSmrg return False; 1196fef5d1ffSmrg } 11979f606849Smrg 1198fef5d1ffSmrg return (True); 11999f606849Smrg} 1200