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 } 195dc088bc7Smrg else if (rep.num_adaptors != 0) { 196dc088bc7Smrg status = XvBadReply; 197dc088bc7Smrg goto out; 198dc088bc7Smrg } 199fef5d1ffSmrg 200fef5d1ffSmrg /* GET INPUT ADAPTORS */ 201fef5d1ffSmrg 202fef5d1ffSmrg if (rep.num_adaptors == 0) { 203444fb138Smrg /* If there are no adaptors, there's nothing more to do. */ 204fef5d1ffSmrg status = Success; 205fef5d1ffSmrg goto out; 206fef5d1ffSmrg } 207fef5d1ffSmrg 208444fb138Smrg u.buffer = buffer; 209444fb138Smrg end = buffer + size; 210fef5d1ffSmrg 211dc088bc7Smrg if ((pas = Xcalloc(rep.num_adaptors, sizeof(XvAdaptorInfo))) == NULL) { 212fef5d1ffSmrg status = XvBadAlloc; 213fef5d1ffSmrg goto out; 214fef5d1ffSmrg } 215fef5d1ffSmrg 216fef5d1ffSmrg /* INIT ADAPTOR FIELDS */ 217fef5d1ffSmrg 218fef5d1ffSmrg pa = pas; 219949d0342Smrg for (unsigned int ii = 0; ii < rep.num_adaptors; ii++) { 220949d0342Smrg char *name; 221949d0342Smrg 222444fb138Smrg if (u.buffer + sz_xvAdaptorInfo > end) { 223444fb138Smrg status = XvBadReply; 224444fb138Smrg goto out; 225444fb138Smrg } 226949d0342Smrg pa->type = (char) u.pa->type; 227fef5d1ffSmrg pa->base_id = u.pa->base_id; 228fef5d1ffSmrg pa->num_ports = u.pa->num_ports; 229fef5d1ffSmrg pa->num_formats = u.pa->num_formats; 230fef5d1ffSmrg pa->num_adaptors = rep.num_adaptors - ii; 231fef5d1ffSmrg 232fef5d1ffSmrg /* GET ADAPTOR NAME */ 233fef5d1ffSmrg 234fef5d1ffSmrg size = u.pa->name_size; 235fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvAdaptorInfo); 236fef5d1ffSmrg 237444fb138Smrg if (u.buffer + size > end) { 238444fb138Smrg status = XvBadReply; 239444fb138Smrg goto out; 240444fb138Smrg } 241fef5d1ffSmrg if ((name = Xmalloc(size + 1)) == NULL) { 242fef5d1ffSmrg status = XvBadAlloc; 243fef5d1ffSmrg goto out; 244fef5d1ffSmrg } 245fef5d1ffSmrg (void) strncpy(name, u.string, size); 246fef5d1ffSmrg name[size] = '\0'; 247fef5d1ffSmrg pa->name = name; 248fef5d1ffSmrg 249fef5d1ffSmrg u.buffer += pad_to_int32(size); 250cdbfa18aSmrg 251fef5d1ffSmrg /* GET FORMATS */ 252fef5d1ffSmrg 253dc088bc7Smrg if ((pfs = Xcalloc(pa->num_formats, sizeof(XvFormat))) == NULL) { 254fef5d1ffSmrg status = XvBadAlloc; 255fef5d1ffSmrg goto out; 256fef5d1ffSmrg } 257fef5d1ffSmrg 258fef5d1ffSmrg pf = pfs; 259949d0342Smrg for (unsigned int jj = 0; jj < pa->num_formats; jj++) { 260444fb138Smrg if (u.buffer + sz_xvFormat > end) { 261444fb138Smrg Xfree(pfs); 262444fb138Smrg status = XvBadReply; 263444fb138Smrg goto out; 264444fb138Smrg } 265949d0342Smrg pf->depth = (char) u.pf->depth; 266fef5d1ffSmrg pf->visual_id = u.pf->visual; 267fef5d1ffSmrg pf++; 268fef5d1ffSmrg 269fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvFormat); 270fef5d1ffSmrg } 271fef5d1ffSmrg 272fef5d1ffSmrg pa->formats = pfs; 273fef5d1ffSmrg 274fef5d1ffSmrg pa++; 275fef5d1ffSmrg 276fef5d1ffSmrg } 277fef5d1ffSmrg 278fef5d1ffSmrg status = Success; 279fef5d1ffSmrg 280fef5d1ffSmrg out: 281fef5d1ffSmrg if (status != Success) { 282fef5d1ffSmrg XvFreeAdaptorInfo(pas); 283fef5d1ffSmrg pas = NULL; 284fef5d1ffSmrg } 285fef5d1ffSmrg 286fef5d1ffSmrg *p_nAdaptors = rep.num_adaptors; 287fef5d1ffSmrg *p_pAdaptors = pas; 288fef5d1ffSmrg 289fef5d1ffSmrg Xfree(buffer); 290fef5d1ffSmrg UnlockDisplay(dpy); 291fef5d1ffSmrg SyncHandle(); 292fef5d1ffSmrg 293fef5d1ffSmrg return status; 2949f606849Smrg} 2959f606849Smrg 2969f606849Smrg 2979f606849Smrgvoid 2989f606849SmrgXvFreeAdaptorInfo(XvAdaptorInfo *pAdaptors) 2999f606849Smrg{ 300fef5d1ffSmrg XvAdaptorInfo *pa; 3019f606849Smrg 302fef5d1ffSmrg if (!pAdaptors) 303fef5d1ffSmrg return; 3049f606849Smrg 305fef5d1ffSmrg pa = pAdaptors; 3069f606849Smrg 307949d0342Smrg for (unsigned int ii = 0; ii < pAdaptors->num_adaptors; ii++, pa++) { 308fef5d1ffSmrg if (pa->name) { 309fef5d1ffSmrg Xfree(pa->name); 310fef5d1ffSmrg } 311fef5d1ffSmrg if (pa->formats) { 312fef5d1ffSmrg Xfree(pa->formats); 313fef5d1ffSmrg } 314cdbfa18aSmrg } 3159f606849Smrg 316fef5d1ffSmrg Xfree(pAdaptors); 3179f606849Smrg} 3189f606849Smrg 3199f606849Smrgint 3209f606849SmrgXvQueryEncodings( 321fef5d1ffSmrg Display *dpy, 322fef5d1ffSmrg XvPortID port, 323fef5d1ffSmrg unsigned int *p_nEncodings, 324fef5d1ffSmrg XvEncodingInfo ** p_pEncodings) 325fef5d1ffSmrg{ 326fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 327fef5d1ffSmrg xvQueryEncodingsReq *req; 328fef5d1ffSmrg xvQueryEncodingsReply rep; 329fef5d1ffSmrg size_t size; 330fef5d1ffSmrg XvEncodingInfo *pes = NULL, *pe; 331fef5d1ffSmrg char *buffer = NULL; 332949d0342Smrg char *end; 333fef5d1ffSmrg union { 334fef5d1ffSmrg char *buffer; 335fef5d1ffSmrg char *string; 336fef5d1ffSmrg xvEncodingInfo *pe; 3379f606849Smrg } u; 338fef5d1ffSmrg int status; 339fef5d1ffSmrg 340fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 341fef5d1ffSmrg 342fef5d1ffSmrg LockDisplay(dpy); 343fef5d1ffSmrg 344fef5d1ffSmrg XvGetReq(QueryEncodings, req); 345949d0342Smrg req->port = (CARD32) port; 346fef5d1ffSmrg 347fef5d1ffSmrg /* READ THE REPLY */ 348fef5d1ffSmrg 349fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 350fef5d1ffSmrg rep.num_encodings = 0; 351fef5d1ffSmrg status = XvBadReply; 352fef5d1ffSmrg goto out; 353fef5d1ffSmrg } 354cdbfa18aSmrg 355fef5d1ffSmrg size = rep.length << 2; 356fef5d1ffSmrg if (size > 0) { 357fef5d1ffSmrg if ((buffer = Xmalloc(size)) == NULL) { 358fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 359fef5d1ffSmrg status = XvBadAlloc; 360fef5d1ffSmrg goto out; 361fef5d1ffSmrg } 362fef5d1ffSmrg _XRead(dpy, buffer, (long) size); 363fef5d1ffSmrg } 364dc088bc7Smrg else if (rep.num_encodings != 0) { 365dc088bc7Smrg status = XvBadReply; 366dc088bc7Smrg goto out; 367dc088bc7Smrg } 368fef5d1ffSmrg 369fef5d1ffSmrg /* GET ENCODINGS */ 370fef5d1ffSmrg 371fef5d1ffSmrg if (rep.num_encodings == 0) { 372444fb138Smrg /* If there are no encodings, there's nothing more to do. */ 373fef5d1ffSmrg status = Success; 374fef5d1ffSmrg goto out; 375fef5d1ffSmrg } 376fef5d1ffSmrg 377444fb138Smrg u.buffer = buffer; 378444fb138Smrg end = buffer + size; 379fef5d1ffSmrg 380dc088bc7Smrg if ((pes = Xcalloc(rep.num_encodings, sizeof(XvEncodingInfo))) == NULL) { 381fef5d1ffSmrg status = XvBadAlloc; 382fef5d1ffSmrg goto out; 383fef5d1ffSmrg } 384fef5d1ffSmrg 385fef5d1ffSmrg /* INITIALIZE THE ENCODING POINTER */ 386fef5d1ffSmrg 387fef5d1ffSmrg pe = pes; 388949d0342Smrg for (unsigned int jj = 0; jj < rep.num_encodings; jj++) { 389949d0342Smrg char *name; 390949d0342Smrg 391444fb138Smrg if (u.buffer + sz_xvEncodingInfo > end) { 392444fb138Smrg status = XvBadReply; 393444fb138Smrg goto out; 394444fb138Smrg } 395fef5d1ffSmrg pe->encoding_id = u.pe->encoding; 396fef5d1ffSmrg pe->width = u.pe->width; 397fef5d1ffSmrg pe->height = u.pe->height; 398fef5d1ffSmrg pe->rate.numerator = u.pe->rate.numerator; 399fef5d1ffSmrg pe->rate.denominator = u.pe->rate.denominator; 400fef5d1ffSmrg pe->num_encodings = rep.num_encodings - jj; 401fef5d1ffSmrg 402fef5d1ffSmrg size = u.pe->name_size; 403fef5d1ffSmrg u.buffer += pad_to_int32(sz_xvEncodingInfo); 404fef5d1ffSmrg 405444fb138Smrg if (u.buffer + size > end) { 406444fb138Smrg status = XvBadReply; 407444fb138Smrg goto out; 408444fb138Smrg } 409fef5d1ffSmrg if ((name = Xmalloc(size + 1)) == NULL) { 410fef5d1ffSmrg status = XvBadAlloc; 411fef5d1ffSmrg goto out; 412fef5d1ffSmrg } 413fef5d1ffSmrg strncpy(name, u.string, size); 414fef5d1ffSmrg name[size] = '\0'; 415fef5d1ffSmrg pe->name = name; 416fef5d1ffSmrg pe++; 417fef5d1ffSmrg 418fef5d1ffSmrg u.buffer += pad_to_int32(size); 419fef5d1ffSmrg } 420fef5d1ffSmrg 421fef5d1ffSmrg status = Success; 422fef5d1ffSmrg 423fef5d1ffSmrg out: 424fef5d1ffSmrg if (status != Success) { 425fef5d1ffSmrg XvFreeEncodingInfo(pes); 426fef5d1ffSmrg pes = NULL; 427fef5d1ffSmrg } 428fef5d1ffSmrg 429fef5d1ffSmrg *p_nEncodings = rep.num_encodings; 430fef5d1ffSmrg *p_pEncodings = pes; 431fef5d1ffSmrg 432fef5d1ffSmrg Xfree(buffer); 433fef5d1ffSmrg UnlockDisplay(dpy); 434fef5d1ffSmrg SyncHandle(); 435fef5d1ffSmrg 436fef5d1ffSmrg return (Success); 4379f606849Smrg} 4389f606849Smrg 4399f606849Smrgvoid 4409f606849SmrgXvFreeEncodingInfo(XvEncodingInfo *pEncodings) 4419f606849Smrg{ 442fef5d1ffSmrg XvEncodingInfo *pe; 4439f606849Smrg 444fef5d1ffSmrg if (!pEncodings) 445fef5d1ffSmrg return; 4469f606849Smrg 447fef5d1ffSmrg pe = pEncodings; 4489f606849Smrg 449949d0342Smrg for (unsigned long 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 479949d0342Smrg req->port = (CARD32) port; 480949d0342Smrg req->drawable = (CARD32) d; 481949d0342Smrg req->gc = (CARD32) gc->gid; 482949d0342Smrg req->vid_x = (INT16) vx; 483949d0342Smrg req->vid_y = (INT16) vy; 484949d0342Smrg req->vid_w = (CARD16) vw; 485949d0342Smrg req->vid_h = (CARD16) vh; 486949d0342Smrg req->drw_x = (INT16) dx; 487949d0342Smrg req->drw_y = (INT16) dy; 488949d0342Smrg req->drw_w = (CARD16) dw; 489949d0342Smrg req->drw_h = (CARD16) 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); 518949d0342Smrg req->port = (CARD32) port; 519949d0342Smrg req->drawable = (CARD32) d; 520949d0342Smrg req->gc = (CARD32) gc->gid; 521949d0342Smrg req->vid_x = (INT16) vx; 522949d0342Smrg req->vid_y = (INT16) vy; 523949d0342Smrg req->vid_w = (CARD16) vw; 524949d0342Smrg req->vid_h = (CARD16) vh; 525949d0342Smrg req->drw_x = (INT16) dx; 526949d0342Smrg req->drw_y = (INT16) dy; 527949d0342Smrg req->drw_w = (CARD16) dw; 528949d0342Smrg req->drw_h = (CARD16) 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); 557949d0342Smrg req->port = (CARD32) port; 558949d0342Smrg req->drawable = (CARD32) d; 559949d0342Smrg req->gc = (CARD32) gc->gid; 560949d0342Smrg req->vid_x = (INT16) vx; 561949d0342Smrg req->vid_y = (INT16) vy; 562949d0342Smrg req->vid_w = (CARD16) vw; 563949d0342Smrg req->vid_h = (CARD16) vh; 564949d0342Smrg req->drw_x = (INT16) dx; 565949d0342Smrg req->drw_y = (INT16) dy; 566949d0342Smrg req->drw_w = (CARD16) dw; 567949d0342Smrg req->drw_h = (CARD16) 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); 596949d0342Smrg req->port = (CARD32) port; 597949d0342Smrg req->drawable = (CARD32) d; 598949d0342Smrg req->gc = (CARD32) gc->gid; 599949d0342Smrg req->vid_x = (INT16) vx; 600949d0342Smrg req->vid_y = (INT16) vy; 601949d0342Smrg req->vid_w = (CARD16) vw; 602949d0342Smrg req->vid_h = (CARD16) vh; 603949d0342Smrg req->drw_x = (INT16) dx; 604949d0342Smrg req->drw_y = (INT16) dy; 605949d0342Smrg req->drw_w = (CARD16) dw; 606949d0342Smrg req->drw_h = (CARD16) 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); 625949d0342Smrg req->port = (CARD32) port; 626949d0342Smrg req->drawable = (CARD32) 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); 647949d0342Smrg req->port = (CARD32) port; 648949d0342Smrg req->time = (CARD32) 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); 672949d0342Smrg req->port = (CARD32) port; 673949d0342Smrg req->time = (CARD32) 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); 692949d0342Smrg req->drawable = (CARD32) drawable; 693949d0342Smrg req->onoff = (BOOL) 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); 712949d0342Smrg req->port = (CARD32) port; 713949d0342Smrg req->onoff = (BOOL) 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); 732949d0342Smrg req->port = (CARD32) port; 733949d0342Smrg req->attribute = (CARD32) 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); 755949d0342Smrg req->port = (CARD32) port; 756949d0342Smrg req->attribute = (CARD32) 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); 796949d0342Smrg req->port = (CARD32) port; 797949d0342Smrg req->motion = (CARD8) motion; 798949d0342Smrg req->vid_w = (CARD16) vid_w; 799949d0342Smrg req->vid_h = (CARD16) vid_h; 800949d0342Smrg req->drw_w = (CARD16) drw_w; 801949d0342Smrg req->drw_h = (CARD16) 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); 836949d0342Smrg req->port = (CARD32) 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 /* limit each part to no more than one half the max size */ 857fef5d1ffSmrg if ((rep.num_attributes < ((INT_MAX / 2) / sizeof(XvAttribute))) && 858fef5d1ffSmrg (rep.text_size < (INT_MAX / 2) - 1)) { 859949d0342Smrg unsigned long size; 860949d0342Smrg 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 870fef5d1ffSmrg /* keep track of remaining room for text strings */ 871949d0342Smrg unsigned long size = rep.text_size; 872fef5d1ffSmrg 873949d0342Smrg for (unsigned int i = 0; i < rep.num_attributes; i++) { 874fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvAttributeInfo); 875fef5d1ffSmrg ret[i].flags = (int) Info.flags; 876fef5d1ffSmrg ret[i].min_value = Info.min; 877fef5d1ffSmrg ret[i].max_value = Info.max; 878fef5d1ffSmrg ret[i].name = marker; 879fef5d1ffSmrg if (Info.size <= size) { 880fef5d1ffSmrg _XRead(dpy, marker, Info.size); 881fef5d1ffSmrg marker += Info.size; 882fef5d1ffSmrg size -= Info.size; 883fef5d1ffSmrg } 884fef5d1ffSmrg (*num)++; 885fef5d1ffSmrg } 886fef5d1ffSmrg 887fef5d1ffSmrg /* ensure final string is nil-terminated to avoid exposure of 888fef5d1ffSmrg uninitialized memory */ 889fef5d1ffSmrg *marker = '\0'; 890fef5d1ffSmrg } 891fef5d1ffSmrg else 892fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 893fef5d1ffSmrg } 894fef5d1ffSmrg 895fef5d1ffSmrg out: 896fef5d1ffSmrg UnlockDisplay(dpy); 897fef5d1ffSmrg SyncHandle(); 898fef5d1ffSmrg 899fef5d1ffSmrg return ret; 9009f606849Smrg} 9019f606849Smrg 902fef5d1ffSmrgXvImageFormatValues * 903fef5d1ffSmrgXvListImageFormats(Display *dpy, XvPortID port, int *num) 904fef5d1ffSmrg{ 905fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 906fef5d1ffSmrg xvListImageFormatsReq *req; 907fef5d1ffSmrg xvListImageFormatsReply rep; 908fef5d1ffSmrg XvImageFormatValues *ret = NULL; 909fef5d1ffSmrg 910fef5d1ffSmrg *num = 0; 911fef5d1ffSmrg 912fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 913fef5d1ffSmrg 914fef5d1ffSmrg LockDisplay(dpy); 915fef5d1ffSmrg 916fef5d1ffSmrg XvGetReq(ListImageFormats, req); 917949d0342Smrg req->port = (CARD32) port; 918fef5d1ffSmrg 919fef5d1ffSmrg /* READ THE REPLY */ 920fef5d1ffSmrg 921fef5d1ffSmrg if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { 922fef5d1ffSmrg goto out; 923fef5d1ffSmrg } 924fef5d1ffSmrg 925fef5d1ffSmrg if (rep.num_formats) { 926fef5d1ffSmrg if (rep.num_formats < (INT_MAX / sizeof(XvImageFormatValues))) 927dc088bc7Smrg ret = Xcalloc(rep.num_formats, sizeof(XvImageFormatValues)); 928fef5d1ffSmrg 929fef5d1ffSmrg if (ret != NULL) { 930949d0342Smrg for (unsigned int i = 0; i < rep.num_formats; i++) { 931949d0342Smrg xvImageFormatInfo Info; 932fef5d1ffSmrg 933fef5d1ffSmrg _XRead(dpy, (char *) (&Info), sz_xvImageFormatInfo); 934949d0342Smrg ret[i].id = (int) Info.id; 935fef5d1ffSmrg ret[i].type = Info.type; 936fef5d1ffSmrg ret[i].byte_order = Info.byte_order; 937fef5d1ffSmrg memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); 938fef5d1ffSmrg ret[i].bits_per_pixel = Info.bpp; 939fef5d1ffSmrg ret[i].format = Info.format; 940fef5d1ffSmrg ret[i].num_planes = Info.num_planes; 941fef5d1ffSmrg ret[i].depth = Info.depth; 942fef5d1ffSmrg ret[i].red_mask = Info.red_mask; 943fef5d1ffSmrg ret[i].green_mask = Info.green_mask; 944fef5d1ffSmrg ret[i].blue_mask = Info.blue_mask; 945fef5d1ffSmrg ret[i].y_sample_bits = Info.y_sample_bits; 946fef5d1ffSmrg ret[i].u_sample_bits = Info.u_sample_bits; 947fef5d1ffSmrg ret[i].v_sample_bits = Info.v_sample_bits; 948fef5d1ffSmrg ret[i].horz_y_period = Info.horz_y_period; 949fef5d1ffSmrg ret[i].horz_u_period = Info.horz_u_period; 950fef5d1ffSmrg ret[i].horz_v_period = Info.horz_v_period; 951fef5d1ffSmrg ret[i].vert_y_period = Info.vert_y_period; 952fef5d1ffSmrg ret[i].vert_u_period = Info.vert_u_period; 953fef5d1ffSmrg ret[i].vert_v_period = Info.vert_v_period; 954fef5d1ffSmrg memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); 955fef5d1ffSmrg ret[i].scanline_order = Info.scanline_order; 956fef5d1ffSmrg (*num)++; 957fef5d1ffSmrg } 958fef5d1ffSmrg } 959fef5d1ffSmrg else 960fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 961fef5d1ffSmrg } 962fef5d1ffSmrg 963fef5d1ffSmrg out: 964fef5d1ffSmrg UnlockDisplay(dpy); 965fef5d1ffSmrg SyncHandle(); 966fef5d1ffSmrg 967fef5d1ffSmrg return ret; 9689f606849Smrg} 9699f606849Smrg 970fef5d1ffSmrgXvImage * 971fef5d1ffSmrgXvCreateImage( 972fef5d1ffSmrg Display *dpy, 973fef5d1ffSmrg XvPortID port, 974fef5d1ffSmrg int id, 975fef5d1ffSmrg char *data, 976fef5d1ffSmrg int width, 977fef5d1ffSmrg int height) 978fef5d1ffSmrg{ 979fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 980fef5d1ffSmrg xvQueryImageAttributesReq *req; 981fef5d1ffSmrg xvQueryImageAttributesReply rep; 982fef5d1ffSmrg XvImage *ret = NULL; 983fef5d1ffSmrg 984fef5d1ffSmrg XvCheckExtension(dpy, info, NULL); 985fef5d1ffSmrg 986fef5d1ffSmrg LockDisplay(dpy); 987fef5d1ffSmrg 988fef5d1ffSmrg XvGetReq(QueryImageAttributes, req); 989949d0342Smrg req->id = (CARD32) id; 990949d0342Smrg req->port = (CARD32) port; 991949d0342Smrg req->width = (CARD16) width; 992949d0342Smrg req->height = (CARD16) height; 993fef5d1ffSmrg 994fef5d1ffSmrg /* READ THE REPLY */ 995fef5d1ffSmrg 996fef5d1ffSmrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 997fef5d1ffSmrg goto out; 998fef5d1ffSmrg } 999fef5d1ffSmrg 1000fef5d1ffSmrg if (rep.num_planes < ((INT_MAX >> 3) - sizeof(XvImage))) 1001fef5d1ffSmrg ret = Xmalloc(sizeof(XvImage) + (rep.num_planes << 3)); 1002fef5d1ffSmrg 1003fef5d1ffSmrg if (ret != NULL) { 1004fef5d1ffSmrg ret->id = id; 1005fef5d1ffSmrg ret->width = rep.width; 1006fef5d1ffSmrg ret->height = rep.height; 1007949d0342Smrg ret->data_size = (int) rep.data_size; 1008949d0342Smrg ret->num_planes = (int) rep.num_planes; 1009fef5d1ffSmrg ret->pitches = (int *) (&ret[1]); 1010fef5d1ffSmrg ret->offsets = ret->pitches + rep.num_planes; 1011fef5d1ffSmrg ret->data = data; 1012fef5d1ffSmrg ret->obdata = NULL; 1013fef5d1ffSmrg _XRead(dpy, (char *) (ret->pitches), rep.num_planes << 2); 1014fef5d1ffSmrg _XRead(dpy, (char *) (ret->offsets), rep.num_planes << 2); 1015fef5d1ffSmrg } 1016fef5d1ffSmrg else 1017fef5d1ffSmrg _XEatDataWords(dpy, rep.length); 1018fef5d1ffSmrg 1019fef5d1ffSmrg out: 1020fef5d1ffSmrg UnlockDisplay(dpy); 1021fef5d1ffSmrg SyncHandle(); 1022fef5d1ffSmrg 1023fef5d1ffSmrg return ret; 10249f606849Smrg} 10259f606849Smrg 1026fef5d1ffSmrgXvImage * 1027fef5d1ffSmrgXvShmCreateImage( 1028fef5d1ffSmrg Display *dpy, 1029fef5d1ffSmrg XvPortID port, 1030fef5d1ffSmrg int id, 1031fef5d1ffSmrg char *data, 1032fef5d1ffSmrg int width, 1033fef5d1ffSmrg int height, 1034fef5d1ffSmrg XShmSegmentInfo *shminfo) 1035fef5d1ffSmrg{ 1036fef5d1ffSmrg XvImage *ret; 10379f606849Smrg 1038fef5d1ffSmrg ret = XvCreateImage(dpy, port, id, data, width, height); 10399f606849Smrg 1040fef5d1ffSmrg if (ret) 1041fef5d1ffSmrg ret->obdata = (XPointer) shminfo; 10429f606849Smrg 1043fef5d1ffSmrg return ret; 10449f606849Smrg} 10459f606849Smrg 1046fef5d1ffSmrgint 1047fef5d1ffSmrgXvPutImage( 1048fef5d1ffSmrg Display *dpy, 1049fef5d1ffSmrg XvPortID port, 1050fef5d1ffSmrg Drawable d, 1051fef5d1ffSmrg GC gc, 1052fef5d1ffSmrg XvImage *image, 1053fef5d1ffSmrg int src_x, int src_y, 1054fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1055fef5d1ffSmrg int dest_x, int dest_y, 1056fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h) 1057fef5d1ffSmrg{ 1058fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1059fef5d1ffSmrg xvPutImageReq *req; 1060fef5d1ffSmrg unsigned int len; 1061fef5d1ffSmrg 1062fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1063fef5d1ffSmrg 1064fef5d1ffSmrg LockDisplay(dpy); 1065fef5d1ffSmrg 1066fef5d1ffSmrg FlushGC(dpy, gc); 1067fef5d1ffSmrg 1068fef5d1ffSmrg XvGetReq(PutImage, req); 1069fef5d1ffSmrg 1070949d0342Smrg req->port = (CARD32) port; 1071949d0342Smrg req->drawable = (CARD32) d; 1072949d0342Smrg req->gc = (CARD32) gc->gid; 1073949d0342Smrg req->id = (CARD32) image->id; 1074949d0342Smrg req->src_x = (INT16) src_x; 1075949d0342Smrg req->src_y = (INT16) src_y; 1076949d0342Smrg req->src_w = (CARD16) src_w; 1077949d0342Smrg req->src_h = (CARD16) src_h; 1078949d0342Smrg req->drw_x = (INT16) dest_x; 1079949d0342Smrg req->drw_y = (INT16) dest_y; 1080949d0342Smrg req->drw_w = (CARD16) dest_w; 1081949d0342Smrg req->drw_h = (CARD16) dest_h; 1082949d0342Smrg req->width = (CARD16) image->width; 1083949d0342Smrg req->height = (CARD16) image->height; 1084fef5d1ffSmrg 1085fef5d1ffSmrg len = ((unsigned int) image->data_size + 3) >> 2; 1086fef5d1ffSmrg SetReqLen(req, len, len); 1087fef5d1ffSmrg 1088fef5d1ffSmrg /* Yes it's kindof lame that we are sending the whole thing, 1089fef5d1ffSmrg but for video all of it may be needed even if displaying 1090fef5d1ffSmrg only a subsection, and I don't want to go through the 1091fef5d1ffSmrg trouble of creating subregions to send */ 1092fef5d1ffSmrg Data(dpy, (char *) image->data, image->data_size); 1093fef5d1ffSmrg 1094fef5d1ffSmrg UnlockDisplay(dpy); 1095fef5d1ffSmrg SyncHandle(); 1096fef5d1ffSmrg 1097fef5d1ffSmrg return Success; 10989f606849Smrg} 10999f606849Smrg 1100fef5d1ffSmrgint 1101fef5d1ffSmrgXvShmPutImage( 1102fef5d1ffSmrg Display *dpy, 1103fef5d1ffSmrg XvPortID port, 1104fef5d1ffSmrg Drawable d, 1105fef5d1ffSmrg GC gc, 1106fef5d1ffSmrg XvImage *image, 1107fef5d1ffSmrg int src_x, int src_y, 1108fef5d1ffSmrg unsigned int src_w, unsigned int src_h, 1109fef5d1ffSmrg int dest_x, int dest_y, 1110fef5d1ffSmrg unsigned int dest_w, unsigned int dest_h, 1111fef5d1ffSmrg Bool send_event) 1112fef5d1ffSmrg{ 1113fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1114fef5d1ffSmrg XShmSegmentInfo *shminfo = (XShmSegmentInfo *) image->obdata; 1115fef5d1ffSmrg xvShmPutImageReq *req; 1116fef5d1ffSmrg 1117fef5d1ffSmrg XvCheckExtension(dpy, info, XvBadExtension); 1118fef5d1ffSmrg 1119fef5d1ffSmrg LockDisplay(dpy); 1120fef5d1ffSmrg 1121fef5d1ffSmrg FlushGC(dpy, gc); 1122fef5d1ffSmrg 1123fef5d1ffSmrg XvGetReq(ShmPutImage, req); 1124fef5d1ffSmrg 1125949d0342Smrg req->port = (CARD32) port; 1126949d0342Smrg req->drawable = (CARD32) d; 1127949d0342Smrg req->gc = (CARD32) gc->gid; 1128949d0342Smrg req->shmseg = (CARD32) shminfo->shmseg; 1129949d0342Smrg req->id = (CARD32) image->id; 1130949d0342Smrg req->src_x = (INT16) src_x; 1131949d0342Smrg req->src_y = (INT16) src_y; 1132949d0342Smrg req->src_w = (CARD16) src_w; 1133949d0342Smrg req->src_h = (CARD16) src_h; 1134949d0342Smrg req->drw_x = (INT16) dest_x; 1135949d0342Smrg req->drw_y = (INT16) dest_y; 1136949d0342Smrg req->drw_w = (CARD16) dest_w; 1137949d0342Smrg req->drw_h = (CARD16) dest_h; 1138949d0342Smrg req->offset = (CARD32) (image->data - shminfo->shmaddr); 1139949d0342Smrg req->width = (CARD16) image->width; 1140949d0342Smrg req->height = (CARD16) image->height; 1141949d0342Smrg req->send_event = (CARD8) send_event; 1142fef5d1ffSmrg 1143fef5d1ffSmrg UnlockDisplay(dpy); 1144fef5d1ffSmrg SyncHandle(); 1145fef5d1ffSmrg 1146fef5d1ffSmrg return Success; 11479f606849Smrg} 11489f606849Smrg 11499f606849Smrg 11509f606849Smrgstatic Bool 11519f606849Smrgxv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) 11529f606849Smrg{ 1153fef5d1ffSmrg XExtDisplayInfo *info = xv_find_display(dpy); 1154fef5d1ffSmrg XvEvent *re = (XvEvent *) host; 1155fef5d1ffSmrg xvEvent *event = (xvEvent *) wire; 11569f606849Smrg 1157fef5d1ffSmrg XvCheckExtension(dpy, info, False); 11589f606849Smrg 1159fef5d1ffSmrg switch ((event->u.u.type & 0x7F) - info->codes->first_event) { 11609f606849Smrg case XvVideoNotify: 1161fef5d1ffSmrg re->xvvideo.type = event->u.u.type & 0x7f; 1162fef5d1ffSmrg re->xvvideo.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1163fef5d1ffSmrg re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); 1164fef5d1ffSmrg re->xvvideo.display = dpy; 1165fef5d1ffSmrg re->xvvideo.time = event->u.videoNotify.time; 1166fef5d1ffSmrg re->xvvideo.reason = event->u.videoNotify.reason; 1167fef5d1ffSmrg re->xvvideo.drawable = event->u.videoNotify.drawable; 1168fef5d1ffSmrg re->xvvideo.port_id = event->u.videoNotify.port; 1169fef5d1ffSmrg break; 11709f606849Smrg case XvPortNotify: 1171fef5d1ffSmrg re->xvport.type = event->u.u.type & 0x7f; 1172fef5d1ffSmrg re->xvport.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 1173fef5d1ffSmrg re->xvport.send_event = ((event->u.u.type & 0x80) != 0); 1174fef5d1ffSmrg re->xvport.display = dpy; 1175fef5d1ffSmrg re->xvport.time = event->u.portNotify.time; 1176fef5d1ffSmrg re->xvport.port_id = event->u.portNotify.port; 1177fef5d1ffSmrg re->xvport.attribute = event->u.portNotify.attribute; 1178fef5d1ffSmrg re->xvport.value = event->u.portNotify.value; 1179fef5d1ffSmrg break; 11809f606849Smrg default: 1181fef5d1ffSmrg return False; 1182fef5d1ffSmrg } 11839f606849Smrg 1184fef5d1ffSmrg return (True); 11859f606849Smrg} 1186