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