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