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