Xv.c revision fef5d1ff
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; 161fef5d1ffSmrg XvAdaptorInfo *pas = NULL, *pa; 162fef5d1ffSmrg XvFormat *pfs, *pf; 163fef5d1ffSmrg char *buffer = NULL; 164fef5d1ffSmrg union { 165fef5d1ffSmrg char *buffer; 166fef5d1ffSmrg char *string; 167fef5d1ffSmrg xvAdaptorInfo *pa; 168fef5d1ffSmrg xvFormat *pf; 1699f606849Smrg } u; 170fef5d1ffSmrg int status; 171fef5d1ffSmrg 172fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 173fef5d1ffSmrg 174fef5d1ffSmrg LockDisplay(dpy); 175fef5d1ffSmrg 176fef5d1ffSmrg XvGetReq(QueryAdaptors, req); 177fef5d1ffSmrg req->window = window; 178fef5d1ffSmrg 179fef5d1ffSmrg /* READ THE REPLY */ 180fef5d1ffSmrg 181fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 182fef5d1ffSmrg rep.num_adaptors = 0; 183fef5d1ffSmrg status = XvBadReply; 184fef5d1ffSmrg goto out; 185fef5d1ffSmrg } 186fef5d1ffSmrg 187fef5d1ffSmrg size = rep.length << 2; 188fef5d1ffSmrg if (size > 0) { 189fef5d1ffSmrg if ((buffer = Xmalloc(size)) == NULL) { 190fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 191fef5d1ffSmrg status = XvBadAlloc; 192fef5d1ffSmrg goto out; 193fef5d1ffSmrg } 194fef5d1ffSmrg _XRead(dpy, buffer, (long) size); 195fef5d1ffSmrg } 196fef5d1ffSmrg 197fef5d1ffSmrg /* GET INPUT ADAPTORS */ 198fef5d1ffSmrg 199fef5d1ffSmrg if (rep.num_adaptors == 0) { 200fef5d1ffSmrg /* If there's no adaptors, there's nothing more to do. */ 201fef5d1ffSmrg status = Success; 202fef5d1ffSmrg goto out; 203fef5d1ffSmrg } 204fef5d1ffSmrg 205fef5d1ffSmrg if (size < (rep.num_adaptors * sz_xvAdaptorInfo)) { 206fef5d1ffSmrg /* If there's not enough data for the number of adaptors, 207fef5d1ffSmrg then we have a problem. */ 208fef5d1ffSmrg status = XvBadReply; 209fef5d1ffSmrg goto out; 210fef5d1ffSmrg } 211fef5d1ffSmrg 212fef5d1ffSmrg size = rep.num_adaptors * sizeof(XvAdaptorInfo); 213fef5d1ffSmrg if ((pas = Xmalloc(size)) == NULL) { 214fef5d1ffSmrg status = XvBadAlloc; 215fef5d1ffSmrg goto out; 216fef5d1ffSmrg } 217fef5d1ffSmrg 218fef5d1ffSmrg /* INIT ADAPTOR FIELDS */ 219fef5d1ffSmrg 220fef5d1ffSmrg pa = pas; 221fef5d1ffSmrg for (ii = 0; ii < rep.num_adaptors; ii++) { 222fef5d1ffSmrg pa->num_adaptors = 0; 223fef5d1ffSmrg pa->name = (char *) NULL; 224fef5d1ffSmrg pa->formats = (XvFormat *) NULL; 225fef5d1ffSmrg pa++; 226fef5d1ffSmrg } 227fef5d1ffSmrg 228fef5d1ffSmrg u.buffer = buffer; 229fef5d1ffSmrg pa = pas; 230fef5d1ffSmrg for (ii = 0; ii < rep.num_adaptors; ii++) { 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 242fef5d1ffSmrg if ((name = Xmalloc(size + 1)) == NULL) { 243fef5d1ffSmrg status = XvBadAlloc; 244fef5d1ffSmrg goto out; 245fef5d1ffSmrg } 246fef5d1ffSmrg (void) strncpy(name, u.string, size); 247fef5d1ffSmrg name[size] = '\0'; 248fef5d1ffSmrg pa->name = name; 249fef5d1ffSmrg 250fef5d1ffSmrg u.buffer += pad_to_int32(size); 251cdbfa18aSmrg 252fef5d1ffSmrg /* GET FORMATS */ 253fef5d1ffSmrg 254fef5d1ffSmrg size = pa->num_formats * sizeof(XvFormat); 255fef5d1ffSmrg if ((pfs = Xmalloc(size)) == NULL) { 256fef5d1ffSmrg status = XvBadAlloc; 257fef5d1ffSmrg goto out; 258fef5d1ffSmrg } 259fef5d1ffSmrg 260fef5d1ffSmrg pf = pfs; 261fef5d1ffSmrg for (jj = 0; jj < pa->num_formats; jj++) { 262fef5d1ffSmrg pf->depth = u.pf->depth; 263fef5d1ffSmrg pf->visual_id = u.pf->visual; 264fef5d1ffSmrg pf++; 265fef5d1ffSmrg 266fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvFormat); 267fef5d1ffSmrg } 268fef5d1ffSmrg 269fef5d1ffSmrg pa->formats = pfs; 270fef5d1ffSmrg 271fef5d1ffSmrg pa++; 272fef5d1ffSmrg 273fef5d1ffSmrg } 274fef5d1ffSmrg 275fef5d1ffSmrg status = Success; 276fef5d1ffSmrg 277fef5d1ffSmrg out: 278fef5d1ffSmrg if (status != Success) { 279fef5d1ffSmrg XvFreeAdaptorInfo(pas); 280fef5d1ffSmrg pas = NULL; 281fef5d1ffSmrg } 282fef5d1ffSmrg 283fef5d1ffSmrg *p_nAdaptors = rep.num_adaptors; 284fef5d1ffSmrg *p_pAdaptors = pas; 285fef5d1ffSmrg 286fef5d1ffSmrg Xfree(buffer); 287fef5d1ffSmrg UnlockDisplay(dpy); 288fef5d1ffSmrg SyncHandle(); 289fef5d1ffSmrg 290fef5d1ffSmrg return status; 2919f606849Smrg} 2929f606849Smrg 2939f606849Smrg 2949f606849Smrgvoid 2959f606849SmrgXvFreeAdaptorInfo(XvAdaptorInfo *pAdaptors) 2969f606849Smrg{ 297fef5d1ffSmrg XvAdaptorInfo *pa; 298fef5d1ffSmrg unsigned int ii; 2999f606849Smrg 300fef5d1ffSmrg if (!pAdaptors) 301fef5d1ffSmrg return; 3029f606849Smrg 303fef5d1ffSmrg pa = pAdaptors; 3049f606849Smrg 305fef5d1ffSmrg for (ii = 0; ii < pAdaptors->num_adaptors; ii++, pa++) { 306fef5d1ffSmrg if (pa->name) { 307fef5d1ffSmrg Xfree(pa->name); 308fef5d1ffSmrg } 309fef5d1ffSmrg if (pa->formats) { 310fef5d1ffSmrg Xfree(pa->formats); 311fef5d1ffSmrg } 312cdbfa18aSmrg } 3139f606849Smrg 314fef5d1ffSmrg Xfree(pAdaptors); 3159f606849Smrg} 3169f606849Smrg 3179f606849Smrgint 3189f606849SmrgXvQueryEncodings( 319fef5d1ffSmrg Display *dpy, 320fef5d1ffSmrg XvPortID port, 321fef5d1ffSmrg unsigned int *p_nEncodings, 322fef5d1ffSmrg XvEncodingInfo ** p_pEncodings) 323fef5d1ffSmrg{ 324fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 325fef5d1ffSmrg xvQueryEncodingsReq *req; 326fef5d1ffSmrg xvQueryEncodingsReply rep; 327fef5d1ffSmrg size_t size; 328fef5d1ffSmrg unsigned int jj; 329fef5d1ffSmrg char *name; 330fef5d1ffSmrg XvEncodingInfo *pes = NULL, *pe; 331fef5d1ffSmrg char *buffer = NULL; 332fef5d1ffSmrg union { 333fef5d1ffSmrg char *buffer; 334fef5d1ffSmrg char *string; 335fef5d1ffSmrg xvEncodingInfo *pe; 3369f606849Smrg } u; 337fef5d1ffSmrg int status; 338fef5d1ffSmrg 339fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 340fef5d1ffSmrg 341fef5d1ffSmrg LockDisplay(dpy); 342fef5d1ffSmrg 343fef5d1ffSmrg XvGetReq(QueryEncodings, req); 344fef5d1ffSmrg req->port = port; 345fef5d1ffSmrg 346fef5d1ffSmrg /* READ THE REPLY */ 347fef5d1ffSmrg 348fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 349fef5d1ffSmrg rep.num_encodings = 0; 350fef5d1ffSmrg status = XvBadReply; 351fef5d1ffSmrg goto out; 352fef5d1ffSmrg } 353cdbfa18aSmrg 354fef5d1ffSmrg size = rep.length << 2; 355fef5d1ffSmrg if (size > 0) { 356fef5d1ffSmrg if ((buffer = Xmalloc(size)) == NULL) { 357fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 358fef5d1ffSmrg status = XvBadAlloc; 359fef5d1ffSmrg goto out; 360fef5d1ffSmrg } 361fef5d1ffSmrg _XRead(dpy, buffer, (long) size); 362fef5d1ffSmrg } 363fef5d1ffSmrg 364fef5d1ffSmrg /* GET ENCODINGS */ 365fef5d1ffSmrg 366fef5d1ffSmrg if (rep.num_encodings == 0) { 367fef5d1ffSmrg /* If there's no encodings, there's nothing more to do. */ 368fef5d1ffSmrg status = Success; 369fef5d1ffSmrg goto out; 370fef5d1ffSmrg } 371fef5d1ffSmrg 372fef5d1ffSmrg if (size < (rep.num_encodings * sz_xvEncodingInfo)) { 373fef5d1ffSmrg /* If there's not enough data for the number of adaptors, 374fef5d1ffSmrg then we have a problem. */ 375fef5d1ffSmrg status = XvBadReply; 376fef5d1ffSmrg goto out; 377fef5d1ffSmrg } 378fef5d1ffSmrg 379fef5d1ffSmrg size = rep.num_encodings * sizeof(XvEncodingInfo); 380fef5d1ffSmrg if ((pes = Xmalloc(size)) == NULL) { 381fef5d1ffSmrg status = XvBadAlloc; 382fef5d1ffSmrg goto out; 383fef5d1ffSmrg } 384fef5d1ffSmrg 385fef5d1ffSmrg /* INITIALIZE THE ENCODING POINTER */ 386fef5d1ffSmrg 387fef5d1ffSmrg pe = pes; 388fef5d1ffSmrg for (jj = 0; jj < rep.num_encodings; jj++) { 389fef5d1ffSmrg pe->name = (char *) NULL; 390fef5d1ffSmrg pe->num_encodings = 0; 391fef5d1ffSmrg pe++; 392fef5d1ffSmrg } 393fef5d1ffSmrg 394fef5d1ffSmrg u.buffer = buffer; 395fef5d1ffSmrg 396fef5d1ffSmrg pe = pes; 397fef5d1ffSmrg for (jj = 0; jj < rep.num_encodings; jj++) { 398fef5d1ffSmrg pe->encoding_id = u.pe->encoding; 399fef5d1ffSmrg pe->width = u.pe->width; 400fef5d1ffSmrg pe->height = u.pe->height; 401fef5d1ffSmrg pe->rate.numerator = u.pe->rate.numerator; 402fef5d1ffSmrg pe->rate.denominator = u.pe->rate.denominator; 403fef5d1ffSmrg pe->num_encodings = rep.num_encodings - jj; 404fef5d1ffSmrg 405fef5d1ffSmrg size = u.pe->name_size; 406fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvEncodingInfo); 407fef5d1ffSmrg 408fef5d1ffSmrg if ((name = Xmalloc(size + 1)) == NULL) { 409fef5d1ffSmrg status = XvBadAlloc; 410fef5d1ffSmrg goto out; 411fef5d1ffSmrg } 412fef5d1ffSmrg strncpy(name, u.string, size); 413fef5d1ffSmrg name[size] = '\0'; 414fef5d1ffSmrg pe->name = name; 415fef5d1ffSmrg pe++; 416fef5d1ffSmrg 417fef5d1ffSmrg u.buffer += pad_to_int32(size); 418fef5d1ffSmrg } 419fef5d1ffSmrg 420fef5d1ffSmrg status = Success; 421fef5d1ffSmrg 422fef5d1ffSmrg out: 423fef5d1ffSmrg if (status != Success) { 424fef5d1ffSmrg XvFreeEncodingInfo(pes); 425fef5d1ffSmrg pes = NULL; 426fef5d1ffSmrg } 427fef5d1ffSmrg 428fef5d1ffSmrg *p_nEncodings = rep.num_encodings; 429fef5d1ffSmrg *p_pEncodings = pes; 430fef5d1ffSmrg 431fef5d1ffSmrg Xfree(buffer); 432fef5d1ffSmrg UnlockDisplay(dpy); 433fef5d1ffSmrg SyncHandle(); 434fef5d1ffSmrg 435fef5d1ffSmrg return (Success); 4369f606849Smrg} 4379f606849Smrg 4389f606849Smrgvoid 4399f606849SmrgXvFreeEncodingInfo(XvEncodingInfo *pEncodings) 4409f606849Smrg{ 441fef5d1ffSmrg XvEncodingInfo *pe; 442fef5d1ffSmrg unsigned long ii; 4439f606849Smrg 444fef5d1ffSmrg if (!pEncodings) 445fef5d1ffSmrg return; 4469f606849Smrg 447fef5d1ffSmrg pe = pEncodings; 4489f606849Smrg 449fef5d1ffSmrg for (ii = 0; ii < pEncodings->num_encodings; ii++, pe++) { 450fef5d1ffSmrg if (pe->name) 451fef5d1ffSmrg Xfree(pe->name); 452fef5d1ffSmrg } 4539f606849Smrg 454fef5d1ffSmrg Xfree(pEncodings); 4559f606849Smrg} 4569f606849Smrg 4579f606849Smrgint 4589f606849SmrgXvPutVideo( 459fef5d1ffSmrg Display *dpy, 460fef5d1ffSmrg XvPortID port, 461fef5d1ffSmrg Drawable d, 462fef5d1ffSmrg GC gc, 463fef5d1ffSmrg int vx, int vy, 464fef5d1ffSmrg unsigned int vw, unsigned int vh, 465fef5d1ffSmrg int dx, int dy, 466fef5d1ffSmrg unsigned int dw, unsigned int dh) 467fef5d1ffSmrg{ 468fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 469fef5d1ffSmrg xvPutVideoReq *req; 470fef5d1ffSmrg 471fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 472fef5d1ffSmrg 473fef5d1ffSmrg LockDisplay(dpy); 474fef5d1ffSmrg 475fef5d1ffSmrg FlushGC(dpy, gc); 476fef5d1ffSmrg 477fef5d1ffSmrg XvGetReq(PutVideo, req); 478fef5d1ffSmrg 479fef5d1ffSmrg req->port = port; 480fef5d1ffSmrg req->drawable = d; 481fef5d1ffSmrg req->gc = gc->gid; 482fef5d1ffSmrg req->vid_x = vx; 483fef5d1ffSmrg req->vid_y = vy; 484fef5d1ffSmrg req->vid_w = vw; 485fef5d1ffSmrg req->vid_h = vh; 486fef5d1ffSmrg req->drw_x = dx; 487fef5d1ffSmrg req->drw_y = dy; 488fef5d1ffSmrg req->drw_w = dw; 489fef5d1ffSmrg req->drw_h = dh; 490fef5d1ffSmrg 491fef5d1ffSmrg UnlockDisplay(dpy); 492fef5d1ffSmrg SyncHandle(); 493fef5d1ffSmrg 494fef5d1ffSmrg return Success; 4959f606849Smrg} 4969f606849Smrg 4979f606849Smrgint 4989f606849SmrgXvPutStill( 499fef5d1ffSmrg Display *dpy, 500fef5d1ffSmrg XvPortID port, 501fef5d1ffSmrg Drawable d, 502fef5d1ffSmrg GC gc, 503fef5d1ffSmrg int vx, int vy, 504fef5d1ffSmrg unsigned int vw, unsigned int vh, 505fef5d1ffSmrg int dx, int dy, 506fef5d1ffSmrg unsigned int dw, unsigned int dh) 507fef5d1ffSmrg{ 508fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 509fef5d1ffSmrg xvPutStillReq *req; 510fef5d1ffSmrg 511fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 512fef5d1ffSmrg 513fef5d1ffSmrg LockDisplay(dpy); 514fef5d1ffSmrg 515fef5d1ffSmrg FlushGC(dpy, gc); 516fef5d1ffSmrg 517fef5d1ffSmrg XvGetReq(PutStill, req); 518fef5d1ffSmrg req->port = port; 519fef5d1ffSmrg req->drawable = d; 520fef5d1ffSmrg req->gc = gc->gid; 521fef5d1ffSmrg req->vid_x = vx; 522fef5d1ffSmrg req->vid_y = vy; 523fef5d1ffSmrg req->vid_w = vw; 524fef5d1ffSmrg req->vid_h = vh; 525fef5d1ffSmrg req->drw_x = dx; 526fef5d1ffSmrg req->drw_y = dy; 527fef5d1ffSmrg req->drw_w = dw; 528fef5d1ffSmrg req->drw_h = dh; 529fef5d1ffSmrg 530fef5d1ffSmrg UnlockDisplay(dpy); 531fef5d1ffSmrg SyncHandle(); 532fef5d1ffSmrg 533fef5d1ffSmrg return Success; 5349f606849Smrg} 5359f606849Smrg 5369f606849Smrgint 5379f606849SmrgXvGetVideo( 538fef5d1ffSmrg Display *dpy, 539fef5d1ffSmrg XvPortID port, 540fef5d1ffSmrg Drawable d, 541fef5d1ffSmrg GC gc, 542fef5d1ffSmrg int vx, int vy, 543fef5d1ffSmrg unsigned int vw, unsigned int vh, 544fef5d1ffSmrg int dx, int dy, 545fef5d1ffSmrg unsigned int dw, unsigned int dh) 546fef5d1ffSmrg{ 547fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 548fef5d1ffSmrg xvGetVideoReq *req; 549fef5d1ffSmrg 550fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 551fef5d1ffSmrg 552fef5d1ffSmrg LockDisplay(dpy); 553fef5d1ffSmrg 554fef5d1ffSmrg FlushGC(dpy, gc); 555fef5d1ffSmrg 556fef5d1ffSmrg XvGetReq(GetVideo, req); 557fef5d1ffSmrg req->port = port; 558fef5d1ffSmrg req->drawable = d; 559fef5d1ffSmrg req->gc = gc->gid; 560fef5d1ffSmrg req->vid_x = vx; 561fef5d1ffSmrg req->vid_y = vy; 562fef5d1ffSmrg req->vid_w = vw; 563fef5d1ffSmrg req->vid_h = vh; 564fef5d1ffSmrg req->drw_x = dx; 565fef5d1ffSmrg req->drw_y = dy; 566fef5d1ffSmrg req->drw_w = dw; 567fef5d1ffSmrg req->drw_h = dh; 568fef5d1ffSmrg 569fef5d1ffSmrg UnlockDisplay(dpy); 570fef5d1ffSmrg SyncHandle(); 571fef5d1ffSmrg 572fef5d1ffSmrg return Success; 5739f606849Smrg} 5749f606849Smrg 5759f606849Smrgint 5769f606849SmrgXvGetStill( 577fef5d1ffSmrg Display *dpy, 578fef5d1ffSmrg XvPortID port, 579fef5d1ffSmrg Drawable d, 580fef5d1ffSmrg GC gc, 581fef5d1ffSmrg int vx, int vy, 582fef5d1ffSmrg unsigned int vw, unsigned int vh, 583fef5d1ffSmrg int dx, int dy, 584fef5d1ffSmrg unsigned int dw, unsigned int dh) 585fef5d1ffSmrg{ 586fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 587fef5d1ffSmrg xvGetStillReq *req; 588fef5d1ffSmrg 589fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 590fef5d1ffSmrg 591fef5d1ffSmrg LockDisplay(dpy); 592fef5d1ffSmrg 593fef5d1ffSmrg FlushGC(dpy, gc); 594fef5d1ffSmrg 595fef5d1ffSmrg XvGetReq(GetStill, req); 596fef5d1ffSmrg req->port = port; 597fef5d1ffSmrg req->drawable = d; 598fef5d1ffSmrg req->gc = gc->gid; 599fef5d1ffSmrg req->vid_x = vx; 600fef5d1ffSmrg req->vid_y = vy; 601fef5d1ffSmrg req->vid_w = vw; 602fef5d1ffSmrg req->vid_h = vh; 603fef5d1ffSmrg req->drw_x = dx; 604fef5d1ffSmrg req->drw_y = dy; 605fef5d1ffSmrg req->drw_w = dw; 606fef5d1ffSmrg req->drw_h = dh; 607fef5d1ffSmrg 608fef5d1ffSmrg UnlockDisplay(dpy); 609fef5d1ffSmrg SyncHandle(); 610fef5d1ffSmrg 611fef5d1ffSmrg return Success; 6129f606849Smrg} 6139f606849Smrg 6149f606849Smrgint 615fef5d1ffSmrgXvStopVideo(Display *dpy, XvPortID port, Drawable draw) 616fef5d1ffSmrg{ 617fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 618fef5d1ffSmrg xvStopVideoReq *req; 6199f606849Smrg 620fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6219f606849Smrg 622fef5d1ffSmrg LockDisplay(dpy); 6239f606849Smrg 624fef5d1ffSmrg XvGetReq(StopVideo, req); 625fef5d1ffSmrg req->port = port; 626fef5d1ffSmrg req->drawable = draw; 6279f606849Smrg 628fef5d1ffSmrg UnlockDisplay(dpy); 629fef5d1ffSmrg SyncHandle(); 6309f606849Smrg 631fef5d1ffSmrg return Success; 6329f606849Smrg} 6339f606849Smrg 6349f606849Smrgint 635fef5d1ffSmrgXvGrabPort(Display *dpy, XvPortID port, Time time) 636fef5d1ffSmrg{ 637fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 638fef5d1ffSmrg int result; 639fef5d1ffSmrg xvGrabPortReply rep; 640fef5d1ffSmrg xvGrabPortReq *req; 6419f606849Smrg 642fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6439f606849Smrg 644fef5d1ffSmrg LockDisplay(dpy); 6459f606849Smrg 646fef5d1ffSmrg XvGetReq(GrabPort, req); 647fef5d1ffSmrg req->port = port; 648fef5d1ffSmrg req->time = time; 6499f606849Smrg 650fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xTrue) == 0) 651fef5d1ffSmrg rep.result = GrabSuccess; 6529f606849Smrg 653fef5d1ffSmrg result = rep.result; 6549f606849Smrg 655fef5d1ffSmrg UnlockDisplay(dpy); 656fef5d1ffSmrg SyncHandle(); 6579f606849Smrg 658fef5d1ffSmrg return result; 6599f606849Smrg} 6609f606849Smrg 6619f606849Smrgint 662fef5d1ffSmrgXvUngrabPort(Display *dpy, XvPortID port, Time time) 663fef5d1ffSmrg{ 664fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 665fef5d1ffSmrg xvUngrabPortReq *req; 6669f606849Smrg 667fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6689f606849Smrg 669fef5d1ffSmrg LockDisplay(dpy); 6709f606849Smrg 671fef5d1ffSmrg XvGetReq(UngrabPort, req); 672fef5d1ffSmrg req->port = port; 673fef5d1ffSmrg req->time = time; 6749f606849Smrg 675fef5d1ffSmrg UnlockDisplay(dpy); 676fef5d1ffSmrg SyncHandle(); 6779f606849Smrg 678fef5d1ffSmrg return Success; 6799f606849Smrg} 6809f606849Smrg 6819f606849Smrgint 682fef5d1ffSmrgXvSelectVideoNotify(Display *dpy, Drawable drawable, Bool onoff) 683fef5d1ffSmrg{ 684fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 685fef5d1ffSmrg xvSelectVideoNotifyReq *req; 6869f606849Smrg 687fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 6889f606849Smrg 689fef5d1ffSmrg LockDisplay(dpy); 6909f606849Smrg 691fef5d1ffSmrg XvGetReq(SelectVideoNotify, req); 692fef5d1ffSmrg req->drawable = drawable; 693fef5d1ffSmrg req->onoff = onoff; 6949f606849Smrg 695fef5d1ffSmrg UnlockDisplay(dpy); 696fef5d1ffSmrg SyncHandle(); 6979f606849Smrg 698fef5d1ffSmrg return Success; 6999f606849Smrg} 7009f606849Smrg 7019f606849Smrgint 702fef5d1ffSmrgXvSelectPortNotify(Display *dpy, XvPortID port, Bool onoff) 703fef5d1ffSmrg{ 704fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 705fef5d1ffSmrg xvSelectPortNotifyReq *req; 7069f606849Smrg 707fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7089f606849Smrg 709fef5d1ffSmrg LockDisplay(dpy); 7109f606849Smrg 711fef5d1ffSmrg XvGetReq(SelectPortNotify, req); 712fef5d1ffSmrg req->port = port; 713fef5d1ffSmrg req->onoff = onoff; 7149f606849Smrg 715fef5d1ffSmrg UnlockDisplay(dpy); 716fef5d1ffSmrg SyncHandle(); 7179f606849Smrg 718fef5d1ffSmrg return Success; 7199f606849Smrg} 7209f606849Smrg 7219f606849Smrgint 722fef5d1ffSmrgXvSetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int value) 7239f606849Smrg{ 724fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 725fef5d1ffSmrg xvSetPortAttributeReq *req; 7269f606849Smrg 727fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7289f606849Smrg 729fef5d1ffSmrg LockDisplay(dpy); 7309f606849Smrg 731fef5d1ffSmrg XvGetReq(SetPortAttribute, req); 732fef5d1ffSmrg req->port = port; 733fef5d1ffSmrg req->attribute = attribute; 734fef5d1ffSmrg req->value = value; 7359f606849Smrg 736fef5d1ffSmrg UnlockDisplay(dpy); 737fef5d1ffSmrg SyncHandle(); 7389f606849Smrg 739fef5d1ffSmrg return (Success); 7409f606849Smrg} 7419f606849Smrg 7429f606849Smrgint 743fef5d1ffSmrgXvGetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int *p_value) 7449f606849Smrg{ 745fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 746fef5d1ffSmrg xvGetPortAttributeReq *req; 747fef5d1ffSmrg xvGetPortAttributeReply rep; 748fef5d1ffSmrg int status; 7499f606849Smrg 750fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7519f606849Smrg 752fef5d1ffSmrg LockDisplay(dpy); 7539f606849Smrg 754fef5d1ffSmrg XvGetReq(GetPortAttribute, req); 755fef5d1ffSmrg req->port = port; 756fef5d1ffSmrg req->attribute = attribute; 7579f606849Smrg 758fef5d1ffSmrg /* READ THE REPLY */ 7599f606849Smrg 760fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 761fef5d1ffSmrg status = XvBadReply; 762fef5d1ffSmrg } 763fef5d1ffSmrg else { 764fef5d1ffSmrg *p_value = rep.value; 765fef5d1ffSmrg status = Success; 766fef5d1ffSmrg } 767cdbfa18aSmrg 768fef5d1ffSmrg UnlockDisplay(dpy); 769fef5d1ffSmrg SyncHandle(); 7709f606849Smrg 771fef5d1ffSmrg return status; 7729f606849Smrg} 7739f606849Smrg 7749f606849Smrgint 7759f606849SmrgXvQueryBestSize( 776fef5d1ffSmrg Display *dpy, 777fef5d1ffSmrg XvPortID port, 778fef5d1ffSmrg Bool motion, 779fef5d1ffSmrg unsigned int vid_w, 780fef5d1ffSmrg unsigned int vid_h, 781fef5d1ffSmrg unsigned int drw_w, 782fef5d1ffSmrg unsigned int drw_h, 783fef5d1ffSmrg unsigned int *p_actual_width, 784fef5d1ffSmrg unsigned int *p_actual_height) 7859f606849Smrg{ 786fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 787fef5d1ffSmrg xvQueryBestSizeReq *req; 788fef5d1ffSmrg xvQueryBestSizeReply rep; 789fef5d1ffSmrg int status; 7909f606849Smrg 791fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 7929f606849Smrg 793fef5d1ffSmrg LockDisplay(dpy); 7949f606849Smrg 795fef5d1ffSmrg XvGetReq(QueryBestSize, req); 796fef5d1ffSmrg req->port = port; 797fef5d1ffSmrg req->motion = motion; 798fef5d1ffSmrg req->vid_w = vid_w; 799fef5d1ffSmrg req->vid_h = vid_h; 800fef5d1ffSmrg req->drw_w = drw_w; 801fef5d1ffSmrg req->drw_h = drw_h; 8029f606849Smrg 803fef5d1ffSmrg /* READ THE REPLY */ 8049f606849Smrg 805fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 806fef5d1ffSmrg status = XvBadReply; 807fef5d1ffSmrg } 808fef5d1ffSmrg else { 809fef5d1ffSmrg *p_actual_width = rep.actual_width; 810fef5d1ffSmrg *p_actual_height = rep.actual_height; 811fef5d1ffSmrg status = Success; 812fef5d1ffSmrg } 8139f606849Smrg 814fef5d1ffSmrg UnlockDisplay(dpy); 815fef5d1ffSmrg SyncHandle(); 8169f606849Smrg 817fef5d1ffSmrg return status; 8189f606849Smrg} 8199f606849Smrg 8209f606849Smrg 821fef5d1ffSmrgXvAttribute * 8229f606849SmrgXvQueryPortAttributes(Display *dpy, XvPortID port, int *num) 8239f606849Smrg{ 824fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 825fef5d1ffSmrg xvQueryPortAttributesReq *req; 826fef5d1ffSmrg xvQueryPortAttributesReply rep; 827fef5d1ffSmrg XvAttribute *ret = NULL; 828fef5d1ffSmrg 829fef5d1ffSmrg *num = 0; 830fef5d1ffSmrg 831fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 832fef5d1ffSmrg 833fef5d1ffSmrg LockDisplay(dpy); 834fef5d1ffSmrg 835fef5d1ffSmrg XvGetReq(QueryPortAttributes, req); 836fef5d1ffSmrg req->port = port; 837fef5d1ffSmrg 838fef5d1ffSmrg /* READ THE REPLY */ 839fef5d1ffSmrg 840fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 841fef5d1ffSmrg goto out; 842fef5d1ffSmrg } 843fef5d1ffSmrg 844fef5d1ffSmrg /* 845fef5d1ffSmrg * X server sends data packed as: 846fef5d1ffSmrg * attribute1, name1, attribute2, name2, ... 847fef5d1ffSmrg * We allocate a single buffer large enough to hold them all and 848fef5d1ffSmrg * then de-interleave the data so we return it to clients as: 849fef5d1ffSmrg * attribute1, attribute2, ..., name1, name2, ... 850fef5d1ffSmrg * so that clients may refer to attributes as a simple array of 851fef5d1ffSmrg * structs: attributes[0], attributes[1], ... 852fef5d1ffSmrg * and free it as a single/simple buffer. 853fef5d1ffSmrg */ 854fef5d1ffSmrg 855fef5d1ffSmrg if (rep.num_attributes) { 856fef5d1ffSmrg unsigned long size; 857fef5d1ffSmrg 858fef5d1ffSmrg /* limit each part to no more than one half the max size */ 859fef5d1ffSmrg if ((rep.num_attributes < ((INT_MAX / 2) / sizeof(XvAttribute))) && 860fef5d1ffSmrg (rep.text_size < (INT_MAX / 2) - 1)) { 861fef5d1ffSmrg size = (rep.num_attributes * sizeof(XvAttribute)) + 862fef5d1ffSmrg rep.text_size + 1; 863fef5d1ffSmrg ret = Xmalloc(size); 864fef5d1ffSmrg } 865fef5d1ffSmrg 866fef5d1ffSmrg if (ret != NULL) { 867fef5d1ffSmrg char *marker = (char *) (&ret[rep.num_attributes]); 868fef5d1ffSmrg xvAttributeInfo Info; 869fef5d1ffSmrg unsigned int i; 870fef5d1ffSmrg 871fef5d1ffSmrg /* keep track of remaining room for text strings */ 872fef5d1ffSmrg size = rep.text_size; 873fef5d1ffSmrg 874fef5d1ffSmrg for (i = 0; i < rep.num_attributes; i++) { 875fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvAttributeInfo); 876fef5d1ffSmrg ret[i].flags = (int) Info.flags; 877fef5d1ffSmrg ret[i].min_value = Info.min; 878fef5d1ffSmrg ret[i].max_value = Info.max; 879fef5d1ffSmrg ret[i].name = marker; 880fef5d1ffSmrg if (Info.size <= size) { 881fef5d1ffSmrg _XRead(dpy, marker, Info.size); 882fef5d1ffSmrg marker += Info.size; 883fef5d1ffSmrg size -= Info.size; 884fef5d1ffSmrg } 885fef5d1ffSmrg (*num)++; 886fef5d1ffSmrg } 887fef5d1ffSmrg 888fef5d1ffSmrg /* ensure final string is nil-terminated to avoid exposure of 889fef5d1ffSmrg uninitialized memory */ 890fef5d1ffSmrg *marker = '\0'; 891fef5d1ffSmrg } 892fef5d1ffSmrg else 893fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 894fef5d1ffSmrg } 895fef5d1ffSmrg 896fef5d1ffSmrg out: 897fef5d1ffSmrg UnlockDisplay(dpy); 898fef5d1ffSmrg SyncHandle(); 899fef5d1ffSmrg 900fef5d1ffSmrg return ret; 9019f606849Smrg} 9029f606849Smrg 903fef5d1ffSmrgXvImageFormatValues * 904fef5d1ffSmrgXvListImageFormats(Display *dpy, XvPortID port, int *num) 905fef5d1ffSmrg{ 906fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 907fef5d1ffSmrg xvListImageFormatsReq *req; 908fef5d1ffSmrg xvListImageFormatsReply rep; 909fef5d1ffSmrg XvImageFormatValues *ret = NULL; 910fef5d1ffSmrg 911fef5d1ffSmrg *num = 0; 912fef5d1ffSmrg 913fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 914fef5d1ffSmrg 915fef5d1ffSmrg LockDisplay(dpy); 916fef5d1ffSmrg 917fef5d1ffSmrg XvGetReq(ListImageFormats, req); 918fef5d1ffSmrg req->port = port; 919fef5d1ffSmrg 920fef5d1ffSmrg /* READ THE REPLY */ 921fef5d1ffSmrg 922fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 923fef5d1ffSmrg goto out; 924fef5d1ffSmrg } 925fef5d1ffSmrg 926fef5d1ffSmrg if (rep.num_formats) { 927fef5d1ffSmrg if (rep.num_formats < (INT_MAX / sizeof(XvImageFormatValues))) 928fef5d1ffSmrg ret = Xmalloc(rep.num_formats * sizeof(XvImageFormatValues)); 929fef5d1ffSmrg 930fef5d1ffSmrg if (ret != NULL) { 931fef5d1ffSmrg xvImageFormatInfo Info; 932fef5d1ffSmrg unsigned int i; 933fef5d1ffSmrg 934fef5d1ffSmrg for (i = 0; i < rep.num_formats; i++) { 935fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvImageFormatInfo); 936fef5d1ffSmrg ret[i].id = Info.id; 937fef5d1ffSmrg ret[i].type = Info.type; 938fef5d1ffSmrg ret[i].byte_order = Info.byte_order; 939fef5d1ffSmrg memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); 940fef5d1ffSmrg ret[i].bits_per_pixel = Info.bpp; 941fef5d1ffSmrg ret[i].format = Info.format; 942fef5d1ffSmrg ret[i].num_planes = Info.num_planes; 943fef5d1ffSmrg ret[i].depth = Info.depth; 944fef5d1ffSmrg ret[i].red_mask = Info.red_mask; 945fef5d1ffSmrg ret[i].green_mask = Info.green_mask; 946fef5d1ffSmrg ret[i].blue_mask = Info.blue_mask; 947fef5d1ffSmrg ret[i].y_sample_bits = Info.y_sample_bits; 948fef5d1ffSmrg ret[i].u_sample_bits = Info.u_sample_bits; 949fef5d1ffSmrg ret[i].v_sample_bits = Info.v_sample_bits; 950fef5d1ffSmrg ret[i].horz_y_period = Info.horz_y_period; 951fef5d1ffSmrg ret[i].horz_u_period = Info.horz_u_period; 952fef5d1ffSmrg ret[i].horz_v_period = Info.horz_v_period; 953fef5d1ffSmrg ret[i].vert_y_period = Info.vert_y_period; 954fef5d1ffSmrg ret[i].vert_u_period = Info.vert_u_period; 955fef5d1ffSmrg ret[i].vert_v_period = Info.vert_v_period; 956fef5d1ffSmrg memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); 957fef5d1ffSmrg ret[i].scanline_order = Info.scanline_order; 958fef5d1ffSmrg (*num)++; 959fef5d1ffSmrg } 960fef5d1ffSmrg } 961fef5d1ffSmrg else 962fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 963fef5d1ffSmrg } 964fef5d1ffSmrg 965fef5d1ffSmrg out: 966fef5d1ffSmrg UnlockDisplay(dpy); 967fef5d1ffSmrg SyncHandle(); 968fef5d1ffSmrg 969fef5d1ffSmrg return ret; 9709f606849Smrg} 9719f606849Smrg 972fef5d1ffSmrgXvImage * 973fef5d1ffSmrgXvCreateImage( 974fef5d1ffSmrg Display *dpy, 975fef5d1ffSmrg XvPortID port, 976fef5d1ffSmrg int id, 977fef5d1ffSmrg char *data, 978fef5d1ffSmrg int width, 979fef5d1ffSmrg int height) 980fef5d1ffSmrg{ 981fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 982fef5d1ffSmrg xvQueryImageAttributesReq *req; 983fef5d1ffSmrg xvQueryImageAttributesReply rep; 984fef5d1ffSmrg XvImage *ret = NULL; 985fef5d1ffSmrg 986fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 987fef5d1ffSmrg 988fef5d1ffSmrg LockDisplay(dpy); 989fef5d1ffSmrg 990fef5d1ffSmrg XvGetReq(QueryImageAttributes, req); 991fef5d1ffSmrg req->id = id; 992fef5d1ffSmrg req->port = port; 993fef5d1ffSmrg req->width = width; 994fef5d1ffSmrg req->height = height; 995fef5d1ffSmrg 996fef5d1ffSmrg /* READ THE REPLY */ 997fef5d1ffSmrg 998fef5d1ffSmrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 999fef5d1ffSmrg goto out; 1000fef5d1ffSmrg } 1001fef5d1ffSmrg 1002fef5d1ffSmrg if (rep.num_planes < ((INT_MAX >> 3) - sizeof(XvImage))) 1003fef5d1ffSmrg ret = Xmalloc(sizeof(XvImage) + (rep.num_planes << 3)); 1004fef5d1ffSmrg 1005fef5d1ffSmrg if (ret != NULL) { 1006fef5d1ffSmrg ret->id = id; 1007fef5d1ffSmrg ret->width = rep.width; 1008fef5d1ffSmrg ret->height = rep.height; 1009fef5d1ffSmrg ret->data_size = rep.data_size; 1010fef5d1ffSmrg ret->num_planes = rep.num_planes; 1011fef5d1ffSmrg ret->pitches = (int *) (&ret[1]); 1012fef5d1ffSmrg ret->offsets = ret->pitches + rep.num_planes; 1013fef5d1ffSmrg ret->data = data; 1014fef5d1ffSmrg ret->obdata = NULL; 1015fef5d1ffSmrg _XRead(dpy, (char *) (ret->pitches), rep.num_planes << 2); 1016fef5d1ffSmrg _XRead(dpy, (char *) (ret->offsets), rep.num_planes << 2); 1017fef5d1ffSmrg } 1018fef5d1ffSmrg else 1019fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 1020fef5d1ffSmrg 1021fef5d1ffSmrg out: 1022fef5d1ffSmrg UnlockDisplay(dpy); 1023fef5d1ffSmrg SyncHandle(); 1024fef5d1ffSmrg 1025fef5d1ffSmrg return ret; 10269f606849Smrg} 10279f606849Smrg 1028fef5d1ffSmrgXvImage * 1029fef5d1ffSmrgXvShmCreateImage( 1030fef5d1ffSmrg Display *dpy, 1031fef5d1ffSmrg XvPortID port, 1032fef5d1ffSmrg int id, 1033fef5d1ffSmrg char *data, 1034fef5d1ffSmrg int width, 1035fef5d1ffSmrg int height, 1036fef5d1ffSmrg XShmSegmentInfo *shminfo) 1037fef5d1ffSmrg{ 1038fef5d1ffSmrg XvImage *ret; 10399f606849Smrg 1040fef5d1ffSmrg ret = XvCreateImage(dpy, port, id, data, width, height); 10419f606849Smrg 1042fef5d1ffSmrg if (ret) 1043fef5d1ffSmrg ret->obdata = (XPointer) shminfo; 10449f606849Smrg 1045fef5d1ffSmrg return ret; 10469f606849Smrg} 10479f606849Smrg 1048fef5d1ffSmrgint 1049fef5d1ffSmrgXvPutImage( 1050fef5d1ffSmrg Display *dpy, 1051fef5d1ffSmrg XvPortID port, 1052fef5d1ffSmrg Drawable d, 1053fef5d1ffSmrg GC gc, 1054fef5d1ffSmrg XvImage *image, 1055fef5d1ffSmrg int src_x, int src_y, 1056fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1057fef5d1ffSmrg int dest_x, int dest_y, 1058fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h) 1059fef5d1ffSmrg{ 1060fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1061fef5d1ffSmrg xvPutImageReq *req; 1062fef5d1ffSmrg unsigned int len; 1063fef5d1ffSmrg 1064fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1065fef5d1ffSmrg 1066fef5d1ffSmrg LockDisplay(dpy); 1067fef5d1ffSmrg 1068fef5d1ffSmrg FlushGC(dpy, gc); 1069fef5d1ffSmrg 1070fef5d1ffSmrg XvGetReq(PutImage, req); 1071fef5d1ffSmrg 1072fef5d1ffSmrg req->port = port; 1073fef5d1ffSmrg req->drawable = d; 1074fef5d1ffSmrg req->gc = gc->gid; 1075fef5d1ffSmrg req->id = image->id; 1076fef5d1ffSmrg req->src_x = src_x; 1077fef5d1ffSmrg req->src_y = src_y; 1078fef5d1ffSmrg req->src_w = src_w; 1079fef5d1ffSmrg req->src_h = src_h; 1080fef5d1ffSmrg req->drw_x = dest_x; 1081fef5d1ffSmrg req->drw_y = dest_y; 1082fef5d1ffSmrg req->drw_w = dest_w; 1083fef5d1ffSmrg req->drw_h = dest_h; 1084fef5d1ffSmrg req->width = image->width; 1085fef5d1ffSmrg req->height = image->height; 1086fef5d1ffSmrg 1087fef5d1ffSmrg len = ((unsigned int) image->data_size + 3) >> 2; 1088fef5d1ffSmrg SetReqLen(req, len, len); 1089fef5d1ffSmrg 1090fef5d1ffSmrg /* Yes it's kindof lame that we are sending the whole thing, 1091fef5d1ffSmrg but for video all of it may be needed even if displaying 1092fef5d1ffSmrg only a subsection, and I don't want to go through the 1093fef5d1ffSmrg trouble of creating subregions to send */ 1094fef5d1ffSmrg Data(dpy, (char *) image->data, image->data_size); 1095fef5d1ffSmrg 1096fef5d1ffSmrg UnlockDisplay(dpy); 1097fef5d1ffSmrg SyncHandle(); 1098fef5d1ffSmrg 1099fef5d1ffSmrg return Success; 11009f606849Smrg} 11019f606849Smrg 1102fef5d1ffSmrgint 1103fef5d1ffSmrgXvShmPutImage( 1104fef5d1ffSmrg Display *dpy, 1105fef5d1ffSmrg XvPortID port, 1106fef5d1ffSmrg Drawable d, 1107fef5d1ffSmrg GC gc, 1108fef5d1ffSmrg XvImage *image, 1109fef5d1ffSmrg int src_x, int src_y, 1110fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1111fef5d1ffSmrg int dest_x, int dest_y, 1112fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h, 1113fef5d1ffSmrg Bool send_event) 1114fef5d1ffSmrg{ 1115fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1116fef5d1ffSmrg XShmSegmentInfo *shminfo = (XShmSegmentInfo *) image->obdata; 1117fef5d1ffSmrg xvShmPutImageReq *req; 1118fef5d1ffSmrg 1119fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1120fef5d1ffSmrg 1121fef5d1ffSmrg LockDisplay(dpy); 1122fef5d1ffSmrg 1123fef5d1ffSmrg FlushGC(dpy, gc); 1124fef5d1ffSmrg 1125fef5d1ffSmrg XvGetReq(ShmPutImage, req); 1126fef5d1ffSmrg 1127fef5d1ffSmrg req->port = port; 1128fef5d1ffSmrg req->drawable = d; 1129fef5d1ffSmrg req->gc = gc->gid; 1130fef5d1ffSmrg req->shmseg = shminfo->shmseg; 1131fef5d1ffSmrg req->id = image->id; 1132fef5d1ffSmrg req->src_x = src_x; 1133fef5d1ffSmrg req->src_y = src_y; 1134fef5d1ffSmrg req->src_w = src_w; 1135fef5d1ffSmrg req->src_h = src_h; 1136fef5d1ffSmrg req->drw_x = dest_x; 1137fef5d1ffSmrg req->drw_y = dest_y; 1138fef5d1ffSmrg req->drw_w = dest_w; 1139fef5d1ffSmrg req->drw_h = dest_h; 1140fef5d1ffSmrg req->offset = image->data - shminfo->shmaddr; 1141fef5d1ffSmrg req->width = image->width; 1142fef5d1ffSmrg req->height = image->height; 1143fef5d1ffSmrg req->send_event = send_event; 1144fef5d1ffSmrg 1145fef5d1ffSmrg UnlockDisplay(dpy); 1146fef5d1ffSmrg SyncHandle(); 1147fef5d1ffSmrg 1148fef5d1ffSmrg return Success; 11499f606849Smrg} 11509f606849Smrg 11519f606849Smrg 11529f606849Smrgstatic Bool 11539f606849Smrgxv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) 11549f606849Smrg{ 1155fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1156fef5d1ffSmrg XvEvent *re = (XvEvent *) host; 1157fef5d1ffSmrg xvEvent *event = (xvEvent *) wire; 11589f606849Smrg 1159fef5d1ffSmrg XvCheckExtension(dpy, info, False); 11609f606849Smrg 1161fef5d1ffSmrg switch ((event->u.u.type & 0x7F) - info->codes->first_event) { 11629f606849Smrg case XvVideoNotify: 1163fef5d1ffSmrg re->xvvideo.type = event->u.u.type & 0x7f; 1164fef5d1ffSmrg re->xvvideo.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1165fef5d1ffSmrg re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); 1166fef5d1ffSmrg re->xvvideo.display = dpy; 1167fef5d1ffSmrg re->xvvideo.time = event->u.videoNotify.time; 1168fef5d1ffSmrg re->xvvideo.reason = event->u.videoNotify.reason; 1169fef5d1ffSmrg re->xvvideo.drawable = event->u.videoNotify.drawable; 1170fef5d1ffSmrg re->xvvideo.port_id = event->u.videoNotify.port; 1171fef5d1ffSmrg break; 11729f606849Smrg case XvPortNotify: 1173fef5d1ffSmrg re->xvport.type = event->u.u.type & 0x7f; 1174fef5d1ffSmrg re->xvport.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1175fef5d1ffSmrg re->xvport.send_event = ((event->u.u.type & 0x80) != 0); 1176fef5d1ffSmrg re->xvport.display = dpy; 1177fef5d1ffSmrg re->xvport.time = event->u.portNotify.time; 1178fef5d1ffSmrg re->xvport.port_id = event->u.portNotify.port; 1179fef5d1ffSmrg re->xvport.attribute = event->u.portNotify.attribute; 1180fef5d1ffSmrg re->xvport.value = event->u.portNotify.value; 1181fef5d1ffSmrg break; 11829f606849Smrg default: 1183fef5d1ffSmrg return False; 1184fef5d1ffSmrg } 11859f606849Smrg 1186fef5d1ffSmrg return (True); 11879f606849Smrg} 1188