xvdisp.c revision 4642e01f
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#ifdef HAVE_DIX_CONFIG_H 25#include <dix-config.h> 26#endif 27 28#include <string.h> 29 30#include <X11/X.h> 31#include <X11/Xproto.h> 32#include "misc.h" 33#include "scrnintstr.h" 34#include "windowstr.h" 35#include "pixmapstr.h" 36#include "gcstruct.h" 37#include "dixstruct.h" 38#include "resource.h" 39#include "opaque.h" 40 41#include <X11/extensions/Xv.h> 42#include <X11/extensions/Xvproto.h> 43#include "xvdix.h" 44#ifdef MITSHM 45#define _XSHM_SERVER_ 46#include <X11/extensions/shmstr.h> 47#endif 48 49#include "xvdisp.h" 50 51#ifdef PANORAMIX 52#include "panoramiX.h" 53#include "panoramiXsrv.h" 54 55unsigned long XvXRTPort; 56#endif 57 58static int 59SWriteQueryExtensionReply( 60 ClientPtr client, 61 xvQueryExtensionReply *rep 62){ 63 char n; 64 65 swaps(&rep->sequenceNumber, n); 66 swapl(&rep->length, n); 67 swaps(&rep->version, n); 68 swaps(&rep->revision, n); 69 70 (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)rep); 71 72 return Success; 73} 74 75static int 76SWriteQueryAdaptorsReply( 77 ClientPtr client, 78 xvQueryAdaptorsReply *rep 79){ 80 char n; 81 82 swaps(&rep->sequenceNumber, n); 83 swapl(&rep->length, n); 84 swaps(&rep->num_adaptors, n); 85 86 (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)rep); 87 88 return Success; 89} 90 91static int 92SWriteQueryEncodingsReply( 93 ClientPtr client, 94 xvQueryEncodingsReply *rep 95){ 96 char n; 97 98 swaps(&rep->sequenceNumber, n); 99 swapl(&rep->length, n); 100 swaps(&rep->num_encodings, n); 101 102 (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)rep); 103 104 return Success; 105} 106 107static int 108SWriteAdaptorInfo( 109 ClientPtr client, 110 xvAdaptorInfo *pAdaptor 111){ 112 char n; 113 114 swapl(&pAdaptor->base_id, n); 115 swaps(&pAdaptor->name_size, n); 116 swaps(&pAdaptor->num_ports, n); 117 swaps(&pAdaptor->num_formats, n); 118 119 (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor); 120 121 return Success; 122} 123 124static int 125SWriteEncodingInfo( 126 ClientPtr client, 127 xvEncodingInfo *pEncoding 128){ 129 char n; 130 131 swapl(&pEncoding->encoding, n); 132 swaps(&pEncoding->name_size, n); 133 swaps(&pEncoding->width, n); 134 swaps(&pEncoding->height, n); 135 swapl(&pEncoding->rate.numerator, n); 136 swapl(&pEncoding->rate.denominator, n); 137 (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding); 138 139 return Success; 140} 141 142static int 143SWriteFormat( 144 ClientPtr client, 145 xvFormat *pFormat 146){ 147 char n; 148 149 swapl(&pFormat->visual, n); 150 (void)WriteToClient(client, sz_xvFormat, (char *)pFormat); 151 152 return Success; 153} 154 155static int 156SWriteAttributeInfo( 157 ClientPtr client, 158 xvAttributeInfo *pAtt 159){ 160 char n; 161 162 swapl(&pAtt->flags, n); 163 swapl(&pAtt->size, n); 164 swapl(&pAtt->min, n); 165 swapl(&pAtt->max, n); 166 (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt); 167 168 return Success; 169} 170 171static int 172SWriteImageFormatInfo( 173 ClientPtr client, 174 xvImageFormatInfo *pImage 175){ 176 char n; 177 178 swapl(&pImage->id, n); 179 swapl(&pImage->red_mask, n); 180 swapl(&pImage->green_mask, n); 181 swapl(&pImage->blue_mask, n); 182 swapl(&pImage->y_sample_bits, n); 183 swapl(&pImage->u_sample_bits, n); 184 swapl(&pImage->v_sample_bits, n); 185 swapl(&pImage->horz_y_period, n); 186 swapl(&pImage->horz_u_period, n); 187 swapl(&pImage->horz_v_period, n); 188 swapl(&pImage->vert_y_period, n); 189 swapl(&pImage->vert_u_period, n); 190 swapl(&pImage->vert_v_period, n); 191 192 (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage); 193 194 return Success; 195} 196 197static int 198SWriteGrabPortReply( 199 ClientPtr client, 200 xvGrabPortReply *rep 201){ 202 char n; 203 204 swaps(&rep->sequenceNumber, n); 205 swapl(&rep->length, n); 206 207 (void)WriteToClient(client, sz_xvGrabPortReply, (char *)rep); 208 209 return Success; 210} 211 212static int 213SWriteGetPortAttributeReply( 214 ClientPtr client, 215 xvGetPortAttributeReply *rep 216){ 217 char n; 218 219 swaps(&rep->sequenceNumber, n); 220 swapl(&rep->length, n); 221 swapl(&rep->value, n); 222 223 (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)rep); 224 225 return Success; 226} 227 228static int 229SWriteQueryBestSizeReply( 230 ClientPtr client, 231 xvQueryBestSizeReply *rep 232){ 233 char n; 234 235 swaps(&rep->sequenceNumber, n); 236 swapl(&rep->length, n); 237 swaps(&rep->actual_width, n); 238 swaps(&rep->actual_height, n); 239 240 (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)rep); 241 242 return Success; 243} 244 245static int 246SWriteQueryPortAttributesReply( 247 ClientPtr client, 248 xvQueryPortAttributesReply *rep 249){ 250 char n; 251 252 swaps(&rep->sequenceNumber, n); 253 swapl(&rep->length, n); 254 swapl(&rep->num_attributes, n); 255 swapl(&rep->text_size, n); 256 257 (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)rep); 258 259 return Success; 260} 261 262static int 263SWriteQueryImageAttributesReply( 264 ClientPtr client, 265 xvQueryImageAttributesReply *rep 266){ 267 char n; 268 269 swaps(&rep->sequenceNumber, n); 270 swapl(&rep->length, n); 271 swapl(&rep->num_planes, n); 272 swapl(&rep->data_size, n); 273 swaps(&rep->width, n); 274 swaps(&rep->height, n); 275 276 (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)rep); 277 278 return Success; 279} 280 281static int 282SWriteListImageFormatsReply( 283 ClientPtr client, 284 xvListImageFormatsReply *rep 285){ 286 char n; 287 288 swaps(&rep->sequenceNumber, n); 289 swapl(&rep->length, n); 290 swapl(&rep->num_formats, n); 291 292 (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)rep); 293 294 return Success; 295} 296 297#define _WriteQueryAdaptorsReply(_c,_d) \ 298 if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \ 299 else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d) 300 301#define _WriteQueryExtensionReply(_c,_d) \ 302 if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \ 303 else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d) 304 305#define _WriteQueryEncodingsReply(_c,_d) \ 306 if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \ 307 else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d) 308 309#define _WriteAdaptorInfo(_c,_d) \ 310 if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \ 311 else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d) 312 313#define _WriteAttributeInfo(_c,_d) \ 314 if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \ 315 else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d) 316 317#define _WriteEncodingInfo(_c,_d) \ 318 if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \ 319 else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d) 320 321#define _WriteFormat(_c,_d) \ 322 if ((_c)->swapped) SWriteFormat(_c, _d); \ 323 else WriteToClient(_c, sz_xvFormat, (char*)_d) 324 325#define _WriteGrabPortReply(_c,_d) \ 326 if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \ 327 else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d) 328 329#define _WriteGetPortAttributeReply(_c,_d) \ 330 if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \ 331 else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d) 332 333#define _WriteQueryBestSizeReply(_c,_d) \ 334 if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \ 335 else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d) 336 337#define _WriteQueryPortAttributesReply(_c,_d) \ 338 if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \ 339 else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d) 340 341#define _WriteQueryImageAttributesReply(_c,_d) \ 342 if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \ 343 else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d) 344 345#define _WriteListImageFormatsReply(_c,_d) \ 346 if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \ 347 else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d) 348 349#define _WriteImageFormatInfo(_c,_d) \ 350 if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \ 351 else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d) 352 353#define _AllocatePort(_i,_p) \ 354 ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success 355 356static int 357ProcXvQueryExtension(ClientPtr client) 358{ 359 xvQueryExtensionReply rep; 360 /* REQUEST(xvQueryExtensionReq); */ 361 REQUEST_SIZE_MATCH(xvQueryExtensionReq); 362 363 rep.type = X_Reply; 364 rep.sequenceNumber = client->sequence; 365 rep.length = 0; 366 rep.version = XvVersion; 367 rep.revision = XvRevision; 368 369 _WriteQueryExtensionReply(client, &rep); 370 371 return Success; 372} 373 374static int 375ProcXvQueryAdaptors(ClientPtr client) 376{ 377 xvFormat format; 378 xvAdaptorInfo ainfo; 379 xvQueryAdaptorsReply rep; 380 int totalSize, na, nf, rc; 381 int nameSize; 382 XvAdaptorPtr pa; 383 XvFormatPtr pf; 384 WindowPtr pWin; 385 ScreenPtr pScreen; 386 XvScreenPtr pxvs; 387 388 REQUEST(xvQueryAdaptorsReq); 389 REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); 390 391 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 392 if (rc != Success) 393 return rc; 394 395 pScreen = pWin->drawable.pScreen; 396 pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, 397 XvGetScreenKey()); 398 if (!pxvs) 399 { 400 rep.type = X_Reply; 401 rep.sequenceNumber = client->sequence; 402 rep.num_adaptors = 0; 403 rep.length = 0; 404 405 _WriteQueryAdaptorsReply(client, &rep); 406 407 return Success; 408 } 409 410 (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors); 411 412 rep.type = X_Reply; 413 rep.sequenceNumber = client->sequence; 414 rep.num_adaptors = pxvs->nAdaptors; 415 416 /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */ 417 418 totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo; 419 420 /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */ 421 422 na = pxvs->nAdaptors; 423 pa = pxvs->pAdaptors; 424 while (na--) 425 { 426 totalSize += (strlen(pa->name) + 3) & ~3; 427 totalSize += pa->nFormats * sz_xvFormat; 428 pa++; 429 } 430 431 rep.length = totalSize >> 2; 432 433 _WriteQueryAdaptorsReply(client, &rep); 434 435 na = pxvs->nAdaptors; 436 pa = pxvs->pAdaptors; 437 while (na--) 438 { 439 440 ainfo.base_id = pa->base_id; 441 ainfo.num_ports = pa->nPorts; 442 ainfo.type = pa->type; 443 ainfo.name_size = nameSize = strlen(pa->name); 444 ainfo.num_formats = pa->nFormats; 445 446 _WriteAdaptorInfo(client, &ainfo); 447 448 WriteToClient(client, nameSize, pa->name); 449 450 nf = pa->nFormats; 451 pf = pa->pFormats; 452 while (nf--) 453 { 454 format.depth = pf->depth; 455 format.visual = pf->visual; 456 _WriteFormat(client, &format); 457 pf++; 458 } 459 460 pa++; 461 462 } 463 464 return (client->noClientException); 465} 466 467static int 468ProcXvQueryEncodings(ClientPtr client) 469{ 470 xvEncodingInfo einfo; 471 xvQueryEncodingsReply rep; 472 int totalSize; 473 int nameSize; 474 XvPortPtr pPort; 475 int ne; 476 XvEncodingPtr pe; 477 int status; 478 479 REQUEST(xvQueryEncodingsReq); 480 REQUEST_SIZE_MATCH(xvQueryEncodingsReq); 481 482 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 483 { 484 client->errorValue = stuff->port; 485 return (_XvBadPort); 486 } 487 488 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 489 { 490 client->errorValue = stuff->port; 491 return (status); 492 } 493 494 rep.type = X_Reply; 495 rep.sequenceNumber = client->sequence; 496 rep.num_encodings = pPort->pAdaptor->nEncodings; 497 498 /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */ 499 500 ne = pPort->pAdaptor->nEncodings; 501 pe = pPort->pAdaptor->pEncodings; 502 totalSize = ne * sz_xvEncodingInfo; 503 while (ne--) 504 { 505 totalSize += (strlen(pe->name) + 3) & ~3; 506 pe++; 507 } 508 509 rep.length = totalSize >> 2; 510 511 _WriteQueryEncodingsReply(client, &rep); 512 513 ne = pPort->pAdaptor->nEncodings; 514 pe = pPort->pAdaptor->pEncodings; 515 while (ne--) 516 { 517 einfo.encoding = pe->id; 518 einfo.name_size = nameSize = strlen(pe->name); 519 einfo.width = pe->width; 520 einfo.height = pe->height; 521 einfo.rate.numerator = pe->rate.numerator; 522 einfo.rate.denominator = pe->rate.denominator; 523 _WriteEncodingInfo(client, &einfo); 524 WriteToClient(client, nameSize, pe->name); 525 pe++; 526 } 527 528 return (client->noClientException); 529} 530 531static int 532ProcXvPutVideo(ClientPtr client) 533{ 534 DrawablePtr pDraw; 535 XvPortPtr pPort; 536 GCPtr pGC; 537 int status; 538 539 REQUEST(xvPutVideoReq); 540 REQUEST_SIZE_MATCH(xvPutVideoReq); 541 542 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 543 544 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 545 { 546 client->errorValue = stuff->port; 547 return (_XvBadPort); 548 } 549 550 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 551 { 552 client->errorValue = stuff->port; 553 return (status); 554 } 555 556 if (!(pPort->pAdaptor->type & XvInputMask) || 557 !(pPort->pAdaptor->type & XvVideoMask)) 558 { 559 client->errorValue = stuff->port; 560 return (BadMatch); 561 } 562 563 status = XVCALL(diMatchPort)(pPort, pDraw); 564 if (status != Success) 565 { 566 return status; 567 } 568 569 return XVCALL(diPutVideo)(client, pDraw, pPort, pGC, 570 stuff->vid_x, stuff->vid_y, 571 stuff->vid_w, stuff->vid_h, 572 stuff->drw_x, stuff->drw_y, 573 stuff->drw_w, stuff->drw_h); 574} 575 576static int 577ProcXvPutStill(ClientPtr client) 578{ 579 DrawablePtr pDraw; 580 XvPortPtr pPort; 581 GCPtr pGC; 582 int status; 583 584 REQUEST(xvPutStillReq); 585 REQUEST_SIZE_MATCH(xvPutStillReq); 586 587 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 588 589 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 590 { 591 client->errorValue = stuff->port; 592 return (_XvBadPort); 593 } 594 595 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 596 { 597 client->errorValue = stuff->port; 598 return (status); 599 } 600 601 if (!(pPort->pAdaptor->type & XvInputMask) || 602 !(pPort->pAdaptor->type & XvStillMask)) 603 { 604 client->errorValue = stuff->port; 605 return (BadMatch); 606 } 607 608 status = XVCALL(diMatchPort)(pPort, pDraw); 609 if (status != Success) 610 { 611 return status; 612 } 613 614 return XVCALL(diPutStill)(client, pDraw, pPort, pGC, 615 stuff->vid_x, stuff->vid_y, 616 stuff->vid_w, stuff->vid_h, 617 stuff->drw_x, stuff->drw_y, 618 stuff->drw_w, stuff->drw_h); 619} 620 621static int 622ProcXvGetVideo(ClientPtr client) 623{ 624 DrawablePtr pDraw; 625 XvPortPtr pPort; 626 GCPtr pGC; 627 int status; 628 629 REQUEST(xvGetVideoReq); 630 REQUEST_SIZE_MATCH(xvGetVideoReq); 631 632 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess); 633 634 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 635 { 636 client->errorValue = stuff->port; 637 return (_XvBadPort); 638 } 639 640 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 641 { 642 client->errorValue = stuff->port; 643 return (status); 644 } 645 646 if (!(pPort->pAdaptor->type & XvOutputMask) || 647 !(pPort->pAdaptor->type & XvVideoMask)) 648 { 649 client->errorValue = stuff->port; 650 return (BadMatch); 651 } 652 653 status = XVCALL(diMatchPort)(pPort, pDraw); 654 if (status != Success) 655 { 656 return status; 657 } 658 659 return XVCALL(diGetVideo)(client, pDraw, pPort, pGC, 660 stuff->vid_x, stuff->vid_y, 661 stuff->vid_w, stuff->vid_h, 662 stuff->drw_x, stuff->drw_y, 663 stuff->drw_w, stuff->drw_h); 664} 665 666static int 667ProcXvGetStill(ClientPtr client) 668{ 669 DrawablePtr pDraw; 670 XvPortPtr pPort; 671 GCPtr pGC; 672 int status; 673 674 REQUEST(xvGetStillReq); 675 REQUEST_SIZE_MATCH(xvGetStillReq); 676 677 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess); 678 679 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 680 { 681 client->errorValue = stuff->port; 682 return (_XvBadPort); 683 } 684 685 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 686 { 687 client->errorValue = stuff->port; 688 return (status); 689 } 690 691 if (!(pPort->pAdaptor->type & XvOutputMask) || 692 !(pPort->pAdaptor->type & XvStillMask)) 693 { 694 client->errorValue = stuff->port; 695 return (BadMatch); 696 } 697 698 status = XVCALL(diMatchPort)(pPort, pDraw); 699 if (status != Success) 700 { 701 return status; 702 } 703 704 return XVCALL(diGetStill)(client, pDraw, pPort, pGC, 705 stuff->vid_x, stuff->vid_y, 706 stuff->vid_w, stuff->vid_h, 707 stuff->drw_x, stuff->drw_y, 708 stuff->drw_w, stuff->drw_h); 709} 710 711static int 712ProcXvSelectVideoNotify(ClientPtr client) 713{ 714 DrawablePtr pDraw; 715 int rc; 716 REQUEST(xvSelectVideoNotifyReq); 717 REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); 718 719 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReceiveAccess); 720 if (rc != Success) 721 return rc; 722 723 return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff); 724} 725 726static int 727ProcXvSelectPortNotify(ClientPtr client) 728{ 729 int status; 730 XvPortPtr pPort; 731 REQUEST(xvSelectPortNotifyReq); 732 REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); 733 734 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 735 { 736 client->errorValue = stuff->port; 737 return (_XvBadPort); 738 } 739 740 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 741 { 742 client->errorValue = stuff->port; 743 return (status); 744 } 745 746 return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff); 747} 748 749static int 750ProcXvGrabPort(ClientPtr client) 751{ 752 int result, status; 753 XvPortPtr pPort; 754 xvGrabPortReply rep; 755 REQUEST(xvGrabPortReq); 756 REQUEST_SIZE_MATCH(xvGrabPortReq); 757 758 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 759 { 760 client->errorValue = stuff->port; 761 return (_XvBadPort); 762 } 763 764 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 765 { 766 client->errorValue = stuff->port; 767 return (status); 768 } 769 770 status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result); 771 772 if (status != Success) 773 { 774 return status; 775 } 776 777 rep.type = X_Reply; 778 rep.sequenceNumber = client->sequence; 779 rep.length = 0; 780 rep.result = result; 781 782 _WriteGrabPortReply(client, &rep); 783 784 return Success; 785} 786 787static int 788ProcXvUngrabPort(ClientPtr client) 789{ 790 int status; 791 XvPortPtr pPort; 792 REQUEST(xvGrabPortReq); 793 REQUEST_SIZE_MATCH(xvGrabPortReq); 794 795 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 796 { 797 client->errorValue = stuff->port; 798 return (_XvBadPort); 799 } 800 801 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 802 { 803 client->errorValue = stuff->port; 804 return (status); 805 } 806 807 return XVCALL(diUngrabPort)(client, pPort, stuff->time); 808} 809 810static int 811ProcXvStopVideo(ClientPtr client) 812{ 813 int status, rc; 814 DrawablePtr pDraw; 815 XvPortPtr pPort; 816 REQUEST(xvStopVideoReq); 817 REQUEST_SIZE_MATCH(xvStopVideoReq); 818 819 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 820 { 821 client->errorValue = stuff->port; 822 return (_XvBadPort); 823 } 824 825 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 826 { 827 client->errorValue = stuff->port; 828 return (status); 829 } 830 831 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); 832 if (rc != Success) 833 return rc; 834 835 return XVCALL(diStopVideo)(client, pPort, pDraw); 836} 837 838static int 839ProcXvSetPortAttribute(ClientPtr client) 840{ 841 int status; 842 XvPortPtr pPort; 843 REQUEST(xvSetPortAttributeReq); 844 REQUEST_SIZE_MATCH(xvSetPortAttributeReq); 845 846 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 847 { 848 client->errorValue = stuff->port; 849 return (_XvBadPort); 850 } 851 852 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 853 { 854 client->errorValue = stuff->port; 855 return (status); 856 } 857 858 if (!ValidAtom(stuff->attribute)) 859 { 860 client->errorValue = stuff->attribute; 861 return(BadAtom); 862 } 863 864 status = XVCALL(diSetPortAttribute)(client, pPort, 865 stuff->attribute, stuff->value); 866 867 if (status == BadMatch) 868 client->errorValue = stuff->attribute; 869 else 870 client->errorValue = stuff->value; 871 872 return status; 873} 874 875static int 876ProcXvGetPortAttribute(ClientPtr client) 877{ 878 INT32 value; 879 int status; 880 XvPortPtr pPort; 881 xvGetPortAttributeReply rep; 882 REQUEST(xvGetPortAttributeReq); 883 REQUEST_SIZE_MATCH(xvGetPortAttributeReq); 884 885 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 886 { 887 client->errorValue = stuff->port; 888 return (_XvBadPort); 889 } 890 891 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 892 { 893 client->errorValue = stuff->port; 894 return (status); 895 } 896 897 if (!ValidAtom(stuff->attribute)) 898 { 899 client->errorValue = stuff->attribute; 900 return(BadAtom); 901 } 902 903 status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value); 904 if (status != Success) 905 { 906 client->errorValue = stuff->attribute; 907 return status; 908 } 909 910 rep.type = X_Reply; 911 rep.sequenceNumber = client->sequence; 912 rep.length = 0; 913 rep.value = value; 914 915 _WriteGetPortAttributeReply(client, &rep); 916 917 return Success; 918} 919 920static int 921ProcXvQueryBestSize(ClientPtr client) 922{ 923 int status; 924 unsigned int actual_width, actual_height; 925 XvPortPtr pPort; 926 xvQueryBestSizeReply rep; 927 REQUEST(xvQueryBestSizeReq); 928 REQUEST_SIZE_MATCH(xvQueryBestSizeReq); 929 930 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 931 { 932 client->errorValue = stuff->port; 933 return (_XvBadPort); 934 } 935 936 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 937 { 938 client->errorValue = stuff->port; 939 return (status); 940 } 941 942 rep.type = X_Reply; 943 rep.sequenceNumber = client->sequence; 944 rep.length = 0; 945 946 (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion, 947 stuff->vid_w, stuff->vid_h, 948 stuff->drw_w, stuff->drw_h, 949 &actual_width, &actual_height); 950 951 rep.actual_width = actual_width; 952 rep.actual_height = actual_height; 953 954 _WriteQueryBestSizeReply(client, &rep); 955 956 return Success; 957} 958 959 960static int 961ProcXvQueryPortAttributes(ClientPtr client) 962{ 963 int status, size, i; 964 XvPortPtr pPort; 965 XvAttributePtr pAtt; 966 xvQueryPortAttributesReply rep; 967 xvAttributeInfo Info; 968 REQUEST(xvQueryPortAttributesReq); 969 REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); 970 971 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 972 { 973 client->errorValue = stuff->port; 974 return (_XvBadPort); 975 } 976 977 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 978 { 979 client->errorValue = stuff->port; 980 return (status); 981 } 982 983 rep.type = X_Reply; 984 rep.sequenceNumber = client->sequence; 985 rep.num_attributes = pPort->pAdaptor->nAttributes; 986 rep.text_size = 0; 987 988 for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 989 i < pPort->pAdaptor->nAttributes; i++, pAtt++) 990 { 991 rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L; 992 } 993 994 rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo) 995 + rep.text_size; 996 rep.length >>= 2; 997 998 _WriteQueryPortAttributesReply(client, &rep); 999 1000 for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 1001 i < pPort->pAdaptor->nAttributes; i++, pAtt++) 1002 { 1003 size = strlen(pAtt->name) + 1; /* pass the NULL */ 1004 Info.flags = pAtt->flags; 1005 Info.min = pAtt->min_value; 1006 Info.max = pAtt->max_value; 1007 Info.size = (size + 3) & ~3L; 1008 1009 _WriteAttributeInfo(client, &Info); 1010 1011 WriteToClient(client, size, pAtt->name); 1012 } 1013 1014 return Success; 1015} 1016 1017static int 1018ProcXvPutImage(ClientPtr client) 1019{ 1020 DrawablePtr pDraw; 1021 XvPortPtr pPort; 1022 XvImagePtr pImage = NULL; 1023 GCPtr pGC; 1024 int status, i, size; 1025 CARD16 width, height; 1026 1027 REQUEST(xvPutImageReq); 1028 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1029 1030 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1031 1032 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 1033 { 1034 client->errorValue = stuff->port; 1035 return (_XvBadPort); 1036 } 1037 1038 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 1039 { 1040 client->errorValue = stuff->port; 1041 return (status); 1042 } 1043 1044 if (!(pPort->pAdaptor->type & XvImageMask) || 1045 !(pPort->pAdaptor->type & XvInputMask)) 1046 { 1047 client->errorValue = stuff->port; 1048 return (BadMatch); 1049 } 1050 1051 status = XVCALL(diMatchPort)(pPort, pDraw); 1052 if (status != Success) 1053 { 1054 return status; 1055 } 1056 1057 for(i = 0; i < pPort->pAdaptor->nImages; i++) { 1058 if(pPort->pAdaptor->pImages[i].id == stuff->id) { 1059 pImage = &(pPort->pAdaptor->pImages[i]); 1060 break; 1061 } 1062 } 1063 1064 if(!pImage) 1065 return BadMatch; 1066 1067 width = stuff->width; 1068 height = stuff->height; 1069 size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 1070 pPort, pImage, &width, &height, NULL, NULL); 1071 size += sizeof(xvPutImageReq); 1072 size = (size + 3) >> 2; 1073 1074 if((width < stuff->width) || (height < stuff->height)) 1075 return BadValue; 1076 1077 if(client->req_len < size) 1078 return BadLength; 1079 1080 return XVCALL(diPutImage)(client, pDraw, pPort, pGC, 1081 stuff->src_x, stuff->src_y, 1082 stuff->src_w, stuff->src_h, 1083 stuff->drw_x, stuff->drw_y, 1084 stuff->drw_w, stuff->drw_h, 1085 pImage, (unsigned char*)(&stuff[1]), FALSE, 1086 stuff->width, stuff->height); 1087} 1088 1089#ifdef MITSHM 1090/* redefined here since it's not in any header file */ 1091typedef struct _ShmDesc { 1092 struct _ShmDesc *next; 1093 int shmid; 1094 int refcnt; 1095 char *addr; 1096 Bool writable; 1097 unsigned long size; 1098} ShmDescRec, *ShmDescPtr; 1099 1100extern RESTYPE ShmSegType; 1101extern int BadShmSegCode; 1102extern int ShmCompletionCode; 1103 1104static int 1105ProcXvShmPutImage(ClientPtr client) 1106{ 1107 ShmDescPtr shmdesc; 1108 DrawablePtr pDraw; 1109 XvPortPtr pPort; 1110 XvImagePtr pImage = NULL; 1111 GCPtr pGC; 1112 int status, size_needed, i; 1113 CARD16 width, height; 1114 1115 REQUEST(xvShmPutImageReq); 1116 REQUEST_SIZE_MATCH(xvShmPutImageReq); 1117 1118 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1119 1120 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 1121 { 1122 client->errorValue = stuff->port; 1123 return (_XvBadPort); 1124 } 1125 1126 if ((status = _AllocatePort(stuff->port, pPort)) != Success) 1127 { 1128 client->errorValue = stuff->port; 1129 return (status); 1130 } 1131 1132 if (!(pPort->pAdaptor->type & XvImageMask) || 1133 !(pPort->pAdaptor->type & XvInputMask)) 1134 { 1135 client->errorValue = stuff->port; 1136 return (BadMatch); 1137 } 1138 1139 status = XVCALL(diMatchPort)(pPort, pDraw); 1140 if (status != Success) 1141 { 1142 return status; 1143 } 1144 1145 for(i = 0; i < pPort->pAdaptor->nImages; i++) { 1146 if(pPort->pAdaptor->pImages[i].id == stuff->id) { 1147 pImage = &(pPort->pAdaptor->pImages[i]); 1148 break; 1149 } 1150 } 1151 1152 if(!pImage) 1153 return BadMatch; 1154 1155 if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) 1156 { 1157 client->errorValue = stuff->shmseg; 1158 return BadShmSegCode; 1159 } 1160 1161 width = stuff->width; 1162 height = stuff->height; 1163 size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 1164 pPort, pImage, &width, &height, NULL, NULL); 1165 if((size_needed + stuff->offset) > shmdesc->size) 1166 return BadAccess; 1167 1168 if((width < stuff->width) || (height < stuff->height)) 1169 return BadValue; 1170 1171 status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, 1172 stuff->src_x, stuff->src_y, 1173 stuff->src_w, stuff->src_h, 1174 stuff->drw_x, stuff->drw_y, 1175 stuff->drw_w, stuff->drw_h, pImage, 1176 (unsigned char *)shmdesc->addr + stuff->offset, 1177 stuff->send_event, stuff->width, stuff->height); 1178 1179 if((status == Success) && stuff->send_event) { 1180 xShmCompletionEvent ev; 1181 1182 ev.type = ShmCompletionCode; 1183 ev.drawable = stuff->drawable; 1184 ev.sequenceNumber = client->sequence; 1185 ev.minorEvent = xv_ShmPutImage; 1186 ev.majorEvent = XvReqCode; 1187 ev.shmseg = stuff->shmseg; 1188 ev.offset = stuff->offset; 1189 WriteEventsToClient(client, 1, (xEvent *) &ev); 1190 } 1191 1192 return status; 1193} 1194#else /* !MITSHM */ 1195static int 1196ProcXvShmPutImage(ClientPtr client) 1197{ 1198 SendErrorToClient(client, XvReqCode, xv_ShmPutImage, 0, BadImplementation); 1199 return(BadImplementation); 1200} 1201#endif 1202 1203#ifdef XvMCExtension 1204#include "xvmcext.h" 1205#endif 1206 1207static int 1208ProcXvQueryImageAttributes(ClientPtr client) 1209{ 1210 xvQueryImageAttributesReply rep; 1211 int size, num_planes, i; 1212 CARD16 width, height; 1213 XvImagePtr pImage = NULL; 1214 XvPortPtr pPort; 1215 int *offsets; 1216 int *pitches; 1217 int planeLength; 1218 REQUEST(xvQueryImageAttributesReq); 1219 1220 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); 1221 1222 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 1223 { 1224 client->errorValue = stuff->port; 1225 return (_XvBadPort); 1226 } 1227 1228 for(i = 0; i < pPort->pAdaptor->nImages; i++) { 1229 if(pPort->pAdaptor->pImages[i].id == stuff->id) { 1230 pImage = &(pPort->pAdaptor->pImages[i]); 1231 break; 1232 } 1233 } 1234 1235#ifdef XvMCExtension 1236 if(!pImage) 1237 pImage = XvMCFindXvImage(pPort, stuff->id); 1238#endif 1239 1240 if(!pImage) 1241 return BadMatch; 1242 1243 num_planes = pImage->num_planes; 1244 1245 if(!(offsets = xalloc(num_planes << 3))) 1246 return BadAlloc; 1247 pitches = offsets + num_planes; 1248 1249 width = stuff->width; 1250 height = stuff->height; 1251 1252 size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage, 1253 &width, &height, offsets, pitches); 1254 1255 rep.type = X_Reply; 1256 rep.sequenceNumber = client->sequence; 1257 rep.length = planeLength = num_planes << 1; 1258 rep.num_planes = num_planes; 1259 rep.width = width; 1260 rep.height = height; 1261 rep.data_size = size; 1262 1263 _WriteQueryImageAttributesReply(client, &rep); 1264 if(client->swapped) 1265 SwapLongs((CARD32*)offsets, planeLength); 1266 WriteToClient(client, planeLength << 2, (char*)offsets); 1267 1268 xfree(offsets); 1269 1270 return Success; 1271} 1272 1273static int 1274ProcXvListImageFormats(ClientPtr client) 1275{ 1276 XvPortPtr pPort; 1277 XvImagePtr pImage; 1278 int i; 1279 xvListImageFormatsReply rep; 1280 xvImageFormatInfo info; 1281 REQUEST(xvListImageFormatsReq); 1282 1283 REQUEST_SIZE_MATCH(xvListImageFormatsReq); 1284 1285 if(!(pPort = LOOKUP_PORT(stuff->port, client) )) 1286 { 1287 client->errorValue = stuff->port; 1288 return (_XvBadPort); 1289 } 1290 1291 rep.type = X_Reply; 1292 rep.sequenceNumber = client->sequence; 1293 rep.num_formats = pPort->pAdaptor->nImages; 1294 rep.length = pPort->pAdaptor->nImages * sz_xvImageFormatInfo >> 2; 1295 1296 _WriteListImageFormatsReply(client, &rep); 1297 1298 pImage = pPort->pAdaptor->pImages; 1299 1300 for(i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) { 1301 info.id = pImage->id; 1302 info.type = pImage->type; 1303 info.byte_order = pImage->byte_order; 1304 memcpy(&info.guid, pImage->guid, 16); 1305 info.bpp = pImage->bits_per_pixel; 1306 info.num_planes = pImage->num_planes; 1307 info.depth = pImage->depth; 1308 info.red_mask = pImage->red_mask; 1309 info.green_mask = pImage->green_mask; 1310 info.blue_mask = pImage->blue_mask; 1311 info.format = pImage->format; 1312 info.y_sample_bits = pImage->y_sample_bits; 1313 info.u_sample_bits = pImage->u_sample_bits; 1314 info.v_sample_bits = pImage->v_sample_bits; 1315 info.horz_y_period = pImage->horz_y_period; 1316 info.horz_u_period = pImage->horz_u_period; 1317 info.horz_v_period = pImage->horz_v_period; 1318 info.vert_y_period = pImage->vert_y_period; 1319 info.vert_u_period = pImage->vert_u_period; 1320 info.vert_v_period = pImage->vert_v_period; 1321 memcpy(&info.comp_order, pImage->component_order, 32); 1322 info.scanline_order = pImage->scanline_order; 1323 _WriteImageFormatInfo(client, &info); 1324 } 1325 1326 return Success; 1327} 1328 1329static int (*XvProcVector[xvNumRequests])(ClientPtr) = { 1330 ProcXvQueryExtension, 1331 ProcXvQueryAdaptors, 1332 ProcXvQueryEncodings, 1333 ProcXvGrabPort, 1334 ProcXvUngrabPort, 1335 ProcXvPutVideo, 1336 ProcXvPutStill, 1337 ProcXvGetVideo, 1338 ProcXvGetStill, 1339 ProcXvStopVideo, 1340 ProcXvSelectVideoNotify, 1341 ProcXvSelectPortNotify, 1342 ProcXvQueryBestSize, 1343 ProcXvSetPortAttribute, 1344 ProcXvGetPortAttribute, 1345 ProcXvQueryPortAttributes, 1346 ProcXvListImageFormats, 1347 ProcXvQueryImageAttributes, 1348 ProcXvPutImage, 1349 ProcXvShmPutImage, 1350}; 1351 1352int 1353ProcXvDispatch(ClientPtr client) 1354{ 1355 REQUEST(xReq); 1356 1357 UpdateCurrentTime(); 1358 1359 if (stuff->data > xvNumRequests) { 1360 SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); 1361 return(BadRequest); 1362 } 1363 1364 return XvProcVector[stuff->data](client); 1365} 1366 1367/* Swapped Procs */ 1368 1369static int 1370SProcXvQueryExtension(ClientPtr client) 1371{ 1372 char n; 1373 REQUEST(xvQueryExtensionReq); 1374 swaps(&stuff->length, n); 1375 return XvProcVector[xv_QueryExtension](client); 1376} 1377 1378static int 1379SProcXvQueryAdaptors(ClientPtr client) 1380{ 1381 char n; 1382 REQUEST(xvQueryAdaptorsReq); 1383 swaps(&stuff->length, n); 1384 swapl(&stuff->window, n); 1385 return XvProcVector[xv_QueryAdaptors](client); 1386} 1387 1388static int 1389SProcXvQueryEncodings(ClientPtr client) 1390{ 1391 char n; 1392 REQUEST(xvQueryEncodingsReq); 1393 swaps(&stuff->length, n); 1394 swapl(&stuff->port, n); 1395 return XvProcVector[xv_QueryEncodings](client); 1396} 1397 1398static int 1399SProcXvGrabPort(ClientPtr client) 1400{ 1401 char n; 1402 REQUEST(xvGrabPortReq); 1403 swaps(&stuff->length, n); 1404 swapl(&stuff->port, n); 1405 swapl(&stuff->time, n); 1406 return XvProcVector[xv_GrabPort](client); 1407} 1408 1409static int 1410SProcXvUngrabPort(ClientPtr client) 1411{ 1412 char n; 1413 REQUEST(xvUngrabPortReq); 1414 swaps(&stuff->length, n); 1415 swapl(&stuff->port, n); 1416 swapl(&stuff->time, n); 1417 return XvProcVector[xv_UngrabPort](client); 1418} 1419 1420static int 1421SProcXvPutVideo(ClientPtr client) 1422{ 1423 char n; 1424 REQUEST(xvPutVideoReq); 1425 swaps(&stuff->length, n); 1426 swapl(&stuff->port, n); 1427 swapl(&stuff->drawable, n); 1428 swapl(&stuff->gc, n); 1429 swaps(&stuff->vid_x, n); 1430 swaps(&stuff->vid_y, n); 1431 swaps(&stuff->vid_w, n); 1432 swaps(&stuff->vid_h, n); 1433 swaps(&stuff->drw_x, n); 1434 swaps(&stuff->drw_y, n); 1435 swaps(&stuff->drw_w, n); 1436 swaps(&stuff->drw_h, n); 1437 return XvProcVector[xv_PutVideo](client); 1438} 1439 1440static int 1441SProcXvPutStill(ClientPtr client) 1442{ 1443 char n; 1444 REQUEST(xvPutStillReq); 1445 swaps(&stuff->length, n); 1446 swapl(&stuff->port, n); 1447 swapl(&stuff->drawable, n); 1448 swapl(&stuff->gc, n); 1449 swaps(&stuff->vid_x, n); 1450 swaps(&stuff->vid_y, n); 1451 swaps(&stuff->vid_w, n); 1452 swaps(&stuff->vid_h, n); 1453 swaps(&stuff->drw_x, n); 1454 swaps(&stuff->drw_y, n); 1455 swaps(&stuff->drw_w, n); 1456 swaps(&stuff->drw_h, n); 1457 return XvProcVector[xv_PutStill](client); 1458} 1459 1460static int 1461SProcXvGetVideo(ClientPtr client) 1462{ 1463 char n; 1464 REQUEST(xvGetVideoReq); 1465 swaps(&stuff->length, n); 1466 swapl(&stuff->port, n); 1467 swapl(&stuff->drawable, n); 1468 swapl(&stuff->gc, n); 1469 swaps(&stuff->vid_x, n); 1470 swaps(&stuff->vid_y, n); 1471 swaps(&stuff->vid_w, n); 1472 swaps(&stuff->vid_h, n); 1473 swaps(&stuff->drw_x, n); 1474 swaps(&stuff->drw_y, n); 1475 swaps(&stuff->drw_w, n); 1476 swaps(&stuff->drw_h, n); 1477 return XvProcVector[xv_GetVideo](client); 1478} 1479 1480static int 1481SProcXvGetStill(ClientPtr client) 1482{ 1483 char n; 1484 REQUEST(xvGetStillReq); 1485 swaps(&stuff->length, n); 1486 swapl(&stuff->port, n); 1487 swapl(&stuff->drawable, n); 1488 swapl(&stuff->gc, n); 1489 swaps(&stuff->vid_x, n); 1490 swaps(&stuff->vid_y, n); 1491 swaps(&stuff->vid_w, n); 1492 swaps(&stuff->vid_h, n); 1493 swaps(&stuff->drw_x, n); 1494 swaps(&stuff->drw_y, n); 1495 swaps(&stuff->drw_w, n); 1496 swaps(&stuff->drw_h, n); 1497 return XvProcVector[xv_GetStill](client); 1498} 1499 1500static int 1501SProcXvPutImage(ClientPtr client) 1502{ 1503 char n; 1504 REQUEST(xvPutImageReq); 1505 swaps(&stuff->length, n); 1506 swapl(&stuff->port, n); 1507 swapl(&stuff->drawable, n); 1508 swapl(&stuff->gc, n); 1509 swapl(&stuff->id, n); 1510 swaps(&stuff->src_x, n); 1511 swaps(&stuff->src_y, n); 1512 swaps(&stuff->src_w, n); 1513 swaps(&stuff->src_h, n); 1514 swaps(&stuff->drw_x, n); 1515 swaps(&stuff->drw_y, n); 1516 swaps(&stuff->drw_w, n); 1517 swaps(&stuff->drw_h, n); 1518 swaps(&stuff->width, n); 1519 swaps(&stuff->height, n); 1520 return XvProcVector[xv_PutImage](client); 1521} 1522 1523#ifdef MITSHM 1524static int 1525SProcXvShmPutImage(ClientPtr client) 1526{ 1527 char n; 1528 REQUEST(xvShmPutImageReq); 1529 swaps(&stuff->length, n); 1530 swapl(&stuff->port, n); 1531 swapl(&stuff->drawable, n); 1532 swapl(&stuff->gc, n); 1533 swapl(&stuff->shmseg, n); 1534 swapl(&stuff->id, n); 1535 swapl(&stuff->offset, n); 1536 swaps(&stuff->src_x, n); 1537 swaps(&stuff->src_y, n); 1538 swaps(&stuff->src_w, n); 1539 swaps(&stuff->src_h, n); 1540 swaps(&stuff->drw_x, n); 1541 swaps(&stuff->drw_y, n); 1542 swaps(&stuff->drw_w, n); 1543 swaps(&stuff->drw_h, n); 1544 swaps(&stuff->width, n); 1545 swaps(&stuff->height, n); 1546 return XvProcVector[xv_ShmPutImage](client); 1547} 1548#else /* MITSHM */ 1549#define SProcXvShmPutImage ProcXvShmPutImage 1550#endif 1551 1552static int 1553SProcXvSelectVideoNotify(ClientPtr client) 1554{ 1555 char n; 1556 REQUEST(xvSelectVideoNotifyReq); 1557 swaps(&stuff->length, n); 1558 swapl(&stuff->drawable, n); 1559 return XvProcVector[xv_SelectVideoNotify](client); 1560} 1561 1562static int 1563SProcXvSelectPortNotify(ClientPtr client) 1564{ 1565 char n; 1566 REQUEST(xvSelectPortNotifyReq); 1567 swaps(&stuff->length, n); 1568 swapl(&stuff->port, n); 1569 return XvProcVector[xv_SelectPortNotify](client); 1570} 1571 1572static int 1573SProcXvStopVideo(ClientPtr client) 1574{ 1575 char n; 1576 REQUEST(xvStopVideoReq); 1577 swaps(&stuff->length, n); 1578 swapl(&stuff->port, n); 1579 swapl(&stuff->drawable, n); 1580 return XvProcVector[xv_StopVideo](client); 1581} 1582 1583static int 1584SProcXvSetPortAttribute(ClientPtr client) 1585{ 1586 char n; 1587 REQUEST(xvSetPortAttributeReq); 1588 swaps(&stuff->length, n); 1589 swapl(&stuff->port, n); 1590 swapl(&stuff->attribute, n); 1591 swapl(&stuff->value, n); 1592 return XvProcVector[xv_SetPortAttribute](client); 1593} 1594 1595static int 1596SProcXvGetPortAttribute(ClientPtr client) 1597{ 1598 char n; 1599 REQUEST(xvGetPortAttributeReq); 1600 swaps(&stuff->length, n); 1601 swapl(&stuff->port, n); 1602 swapl(&stuff->attribute, n); 1603 return XvProcVector[xv_GetPortAttribute](client); 1604} 1605 1606static int 1607SProcXvQueryBestSize(ClientPtr client) 1608{ 1609 char n; 1610 REQUEST(xvQueryBestSizeReq); 1611 swaps(&stuff->length, n); 1612 swapl(&stuff->port, n); 1613 swaps(&stuff->vid_w, n); 1614 swaps(&stuff->vid_h, n); 1615 swaps(&stuff->drw_w, n); 1616 swaps(&stuff->drw_h, n); 1617 return XvProcVector[xv_QueryBestSize](client); 1618} 1619 1620static int 1621SProcXvQueryPortAttributes(ClientPtr client) 1622{ 1623 char n; 1624 REQUEST(xvQueryPortAttributesReq); 1625 swaps(&stuff->length, n); 1626 swapl(&stuff->port, n); 1627 return XvProcVector[xv_QueryPortAttributes](client); 1628} 1629 1630static int 1631SProcXvQueryImageAttributes(ClientPtr client) 1632{ 1633 char n; 1634 REQUEST(xvQueryImageAttributesReq); 1635 swaps(&stuff->length, n); 1636 swapl(&stuff->port, n); 1637 swapl(&stuff->id, n); 1638 swaps(&stuff->width, n); 1639 swaps(&stuff->height, n); 1640 return XvProcVector[xv_QueryImageAttributes](client); 1641} 1642 1643static int 1644SProcXvListImageFormats(ClientPtr client) 1645{ 1646 char n; 1647 REQUEST(xvListImageFormatsReq); 1648 swaps(&stuff->length, n); 1649 swapl(&stuff->port, n); 1650 return XvProcVector[xv_ListImageFormats](client); 1651} 1652 1653static int (*SXvProcVector[xvNumRequests])(ClientPtr) = { 1654 SProcXvQueryExtension, 1655 SProcXvQueryAdaptors, 1656 SProcXvQueryEncodings, 1657 SProcXvGrabPort, 1658 SProcXvUngrabPort, 1659 SProcXvPutVideo, 1660 SProcXvPutStill, 1661 SProcXvGetVideo, 1662 SProcXvGetStill, 1663 SProcXvStopVideo, 1664 SProcXvSelectVideoNotify, 1665 SProcXvSelectPortNotify, 1666 SProcXvQueryBestSize, 1667 SProcXvSetPortAttribute, 1668 SProcXvGetPortAttribute, 1669 SProcXvQueryPortAttributes, 1670 SProcXvListImageFormats, 1671 SProcXvQueryImageAttributes, 1672 SProcXvPutImage, 1673 SProcXvShmPutImage, 1674}; 1675 1676int 1677SProcXvDispatch(ClientPtr client) 1678{ 1679 REQUEST(xReq); 1680 1681 UpdateCurrentTime(); 1682 1683 if (stuff->data > xvNumRequests) { 1684 SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); 1685 return(BadRequest); 1686 } 1687 1688 return SXvProcVector[stuff->data](client); 1689} 1690 1691#ifdef PANORAMIX 1692static int 1693XineramaXvStopVideo(ClientPtr client) 1694{ 1695 int result = Success, i; 1696 PanoramiXRes *draw, *port; 1697 REQUEST(xvStopVideoReq); 1698 REQUEST_SIZE_MATCH(xvStopVideoReq); 1699 1700 if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( 1701 client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) 1702 return BadDrawable; 1703 1704 if(!(port = (PanoramiXRes *)SecurityLookupIDByType( 1705 client, stuff->port, XvXRTPort, DixReadAccess))) 1706 return _XvBadPort; 1707 1708 FOR_NSCREENS_BACKWARD(i) { 1709 if(port->info[i].id) { 1710 stuff->drawable = draw->info[i].id; 1711 stuff->port = port->info[i].id; 1712 result = ProcXvStopVideo(client); 1713 } 1714 } 1715 1716 return result; 1717} 1718 1719static int 1720XineramaXvSetPortAttribute(ClientPtr client) 1721{ 1722 REQUEST(xvSetPortAttributeReq); 1723 PanoramiXRes *port; 1724 int result = Success, i; 1725 1726 REQUEST_SIZE_MATCH(xvSetPortAttributeReq); 1727 1728 if(!(port = (PanoramiXRes *)SecurityLookupIDByType( 1729 client, stuff->port, XvXRTPort, DixReadAccess))) 1730 return _XvBadPort; 1731 1732 FOR_NSCREENS_BACKWARD(i) { 1733 if(port->info[i].id) { 1734 stuff->port = port->info[i].id; 1735 result = ProcXvSetPortAttribute(client); 1736 } 1737 } 1738 return result; 1739} 1740 1741#ifdef MITSHM 1742static int 1743XineramaXvShmPutImage(ClientPtr client) 1744{ 1745 REQUEST(xvShmPutImageReq); 1746 PanoramiXRes *draw, *gc, *port; 1747 Bool send_event = stuff->send_event; 1748 Bool isRoot; 1749 int result = Success, i, x, y; 1750 1751 REQUEST_SIZE_MATCH(xvShmPutImageReq); 1752 1753 if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( 1754 client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) 1755 return BadDrawable; 1756 1757 if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( 1758 client, stuff->gc, XRT_GC, DixReadAccess))) 1759 return BadGC; 1760 1761 if(!(port = (PanoramiXRes *)SecurityLookupIDByType( 1762 client, stuff->port, XvXRTPort, DixReadAccess))) 1763 return _XvBadPort; 1764 1765 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1766 1767 x = stuff->drw_x; 1768 y = stuff->drw_y; 1769 1770 FOR_NSCREENS_BACKWARD(i) { 1771 if(port->info[i].id) { 1772 stuff->drawable = draw->info[i].id; 1773 stuff->port = port->info[i].id; 1774 stuff->gc = gc->info[i].id; 1775 stuff->drw_x = x; 1776 stuff->drw_y = y; 1777 if(isRoot) { 1778 stuff->drw_x -= panoramiXdataPtr[i].x; 1779 stuff->drw_y -= panoramiXdataPtr[i].y; 1780 } 1781 stuff->send_event = (send_event && !i) ? 1 : 0; 1782 1783 result = ProcXvShmPutImage(client); 1784 } 1785 } 1786 return result; 1787} 1788#else 1789#define XineramaXvShmPutImage ProcXvShmPutImage 1790#endif 1791 1792static int 1793XineramaXvPutImage(ClientPtr client) 1794{ 1795 REQUEST(xvPutImageReq); 1796 PanoramiXRes *draw, *gc, *port; 1797 Bool isRoot; 1798 int result = Success, i, x, y; 1799 1800 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1801 1802 if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( 1803 client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) 1804 return BadDrawable; 1805 1806 if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( 1807 client, stuff->gc, XRT_GC, DixReadAccess))) 1808 return BadGC; 1809 1810 if(!(port = (PanoramiXRes *)SecurityLookupIDByType( 1811 client, stuff->port, XvXRTPort, DixReadAccess))) 1812 return _XvBadPort; 1813 1814 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1815 1816 x = stuff->drw_x; 1817 y = stuff->drw_y; 1818 1819 FOR_NSCREENS_BACKWARD(i) { 1820 if(port->info[i].id) { 1821 stuff->drawable = draw->info[i].id; 1822 stuff->port = port->info[i].id; 1823 stuff->gc = gc->info[i].id; 1824 stuff->drw_x = x; 1825 stuff->drw_y = y; 1826 if(isRoot) { 1827 stuff->drw_x -= panoramiXdataPtr[i].x; 1828 stuff->drw_y -= panoramiXdataPtr[i].y; 1829 } 1830 1831 result = ProcXvPutImage(client); 1832 } 1833 } 1834 return result; 1835} 1836 1837static int 1838XineramaXvPutVideo(ClientPtr client) 1839{ 1840 REQUEST(xvPutImageReq); 1841 PanoramiXRes *draw, *gc, *port; 1842 Bool isRoot; 1843 int result = Success, i, x, y; 1844 1845 REQUEST_AT_LEAST_SIZE(xvPutVideoReq); 1846 1847 if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( 1848 client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) 1849 return BadDrawable; 1850 1851 if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( 1852 client, stuff->gc, XRT_GC, DixReadAccess))) 1853 return BadGC; 1854 1855 if(!(port = (PanoramiXRes *)SecurityLookupIDByType( 1856 client, stuff->port, XvXRTPort, DixReadAccess))) 1857 return _XvBadPort; 1858 1859 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1860 1861 x = stuff->drw_x; 1862 y = stuff->drw_y; 1863 1864 FOR_NSCREENS_BACKWARD(i) { 1865 if(port->info[i].id) { 1866 stuff->drawable = draw->info[i].id; 1867 stuff->port = port->info[i].id; 1868 stuff->gc = gc->info[i].id; 1869 stuff->drw_x = x; 1870 stuff->drw_y = y; 1871 if(isRoot) { 1872 stuff->drw_x -= panoramiXdataPtr[i].x; 1873 stuff->drw_y -= panoramiXdataPtr[i].y; 1874 } 1875 1876 result = ProcXvPutVideo(client); 1877 } 1878 } 1879 return result; 1880} 1881 1882static int 1883XineramaXvPutStill(ClientPtr client) 1884{ 1885 REQUEST(xvPutImageReq); 1886 PanoramiXRes *draw, *gc, *port; 1887 Bool isRoot; 1888 int result = Success, i, x, y; 1889 1890 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1891 1892 if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( 1893 client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) 1894 return BadDrawable; 1895 1896 if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( 1897 client, stuff->gc, XRT_GC, DixReadAccess))) 1898 return BadGC; 1899 1900 if(!(port = (PanoramiXRes *)SecurityLookupIDByType( 1901 client, stuff->port, XvXRTPort, DixReadAccess))) 1902 return _XvBadPort; 1903 1904 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1905 1906 x = stuff->drw_x; 1907 y = stuff->drw_y; 1908 1909 FOR_NSCREENS_BACKWARD(i) { 1910 if(port->info[i].id) { 1911 stuff->drawable = draw->info[i].id; 1912 stuff->port = port->info[i].id; 1913 stuff->gc = gc->info[i].id; 1914 stuff->drw_x = x; 1915 stuff->drw_y = y; 1916 if(isRoot) { 1917 stuff->drw_x -= panoramiXdataPtr[i].x; 1918 stuff->drw_y -= panoramiXdataPtr[i].y; 1919 } 1920 1921 result = ProcXvPutStill(client); 1922 } 1923 } 1924 return result; 1925} 1926 1927void XineramifyXv(void) 1928{ 1929 ScreenPtr pScreen, screen0 = screenInfo.screens[0]; 1930 XvScreenPtr xvsp0 = (XvScreenPtr)dixLookupPrivate(&screen0->devPrivates, 1931 XvGetScreenKey()); 1932 XvAdaptorPtr refAdapt, pAdapt; 1933 XvAttributePtr pAttr; 1934 XvScreenPtr xvsp; 1935 Bool isOverlay, hasOverlay; 1936 PanoramiXRes *port; 1937 XvAdaptorPtr MatchingAdaptors[MAXSCREENS]; 1938 int i, j, k, l; 1939 1940 XvXRTPort = CreateNewResourceType(XineramaDeleteResource); 1941 1942 if(!xvsp0) return; 1943 1944 for(i = 0; i < xvsp0->nAdaptors; i++) { 1945 refAdapt = xvsp0->pAdaptors + i; 1946 1947 bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS); 1948 1949 MatchingAdaptors[0] = refAdapt; 1950 1951 if(!(refAdapt->type & XvInputMask)) continue; 1952 1953 isOverlay = FALSE; 1954 for(j = 0; j < refAdapt->nAttributes; j++) { 1955 pAttr = refAdapt->pAttributes + j; 1956 if(!strcmp(pAttr->name, "XV_COLORKEY")) { 1957 isOverlay = TRUE; 1958 break; 1959 } 1960 } 1961 1962 for(j = 1; j < PanoramiXNumScreens; j++) { 1963 pScreen = screenInfo.screens[j]; 1964 xvsp = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, 1965 XvGetScreenKey()); 1966 /* Do not try to go on if xv is not supported on this screen */ 1967 if (xvsp==NULL) continue ; 1968 1969 /* if the adaptor has the same name it's a perfect match */ 1970 for(k = 0; k < xvsp->nAdaptors; k++) { 1971 pAdapt = xvsp->pAdaptors + k; 1972 if(!strcmp(refAdapt->name, pAdapt->name)) { 1973 MatchingAdaptors[j] = pAdapt; 1974 break; 1975 } 1976 } 1977 if(MatchingAdaptors[j]) continue; /* found it */ 1978 1979 /* otherwise we only look for XvImage adaptors */ 1980 if(!(refAdapt->type & XvImageMask)) continue; 1981 if(refAdapt->nImages <= 0) continue; 1982 1983 /* prefer overlay/overlay non-overlay/non-overlay pairing */ 1984 for(k = 0; k < xvsp->nAdaptors; k++) { 1985 pAdapt = xvsp->pAdaptors + k; 1986 if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) { 1987 hasOverlay = FALSE; 1988 for(l = 0; l < pAdapt->nAttributes; l++) { 1989 if(!strcmp(pAdapt->name, "XV_COLORKEY")) { 1990 hasOverlay = TRUE; 1991 break; 1992 } 1993 } 1994 if(isOverlay && hasOverlay) { 1995 MatchingAdaptors[j] = pAdapt; 1996 break; 1997 } 1998 else if(!isOverlay && !hasOverlay) { 1999 MatchingAdaptors[j] = pAdapt; 2000 break; 2001 } 2002 } 2003 } 2004 2005 if(MatchingAdaptors[j]) continue; /* found it */ 2006 2007 /* but we'll take any XvImage pairing if we can get it */ 2008 2009 for(k = 0; k < xvsp->nAdaptors; k++) { 2010 pAdapt = xvsp->pAdaptors + k; 2011 if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) { 2012 MatchingAdaptors[j] = pAdapt; 2013 break; 2014 } 2015 } 2016 } 2017 2018 /* now create a resource for each port */ 2019 for(j = 0; j < refAdapt->nPorts; j++) { 2020 if(!(port = xalloc(sizeof(PanoramiXRes)))) 2021 break; 2022 port->info[0].id = MatchingAdaptors[0]->base_id + j; 2023 AddResource(port->info[0].id, XvXRTPort, port); 2024 2025 for(k = 1; k < PanoramiXNumScreens; k++) { 2026 if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 2027 port->info[k].id = MatchingAdaptors[k]->base_id + j; 2028 else 2029 port->info[k].id = 0; 2030 } 2031 } 2032 } 2033 2034 /* munge the dispatch vector */ 2035 XvProcVector[xv_PutVideo] = XineramaXvPutVideo; 2036 XvProcVector[xv_PutStill] = XineramaXvPutStill; 2037 XvProcVector[xv_StopVideo] = XineramaXvStopVideo; 2038 XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute; 2039 XvProcVector[xv_PutImage] = XineramaXvPutImage; 2040 XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage; 2041} 2042#endif /* PANORAMIX */ 2043 2044void 2045XvResetProcVector(void) 2046{ 2047#ifdef PANORAMIX 2048 XvProcVector[xv_PutVideo] = ProcXvPutVideo; 2049 XvProcVector[xv_PutStill] = ProcXvPutStill; 2050 XvProcVector[xv_StopVideo] = ProcXvStopVideo; 2051 XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute; 2052 XvProcVector[xv_PutImage] = ProcXvPutImage; 2053 XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage; 2054#endif 2055} 2056