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