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