xvdisp.c revision 45bb0b75
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 swaps(&stuff->length, n); 1284 return XvProcVector[xv_QueryExtension](client); 1285} 1286 1287static int 1288SProcXvQueryAdaptors(ClientPtr client) 1289{ 1290 char n; 1291 REQUEST(xvQueryAdaptorsReq); 1292 swaps(&stuff->length, n); 1293 swapl(&stuff->window, n); 1294 return XvProcVector[xv_QueryAdaptors](client); 1295} 1296 1297static int 1298SProcXvQueryEncodings(ClientPtr client) 1299{ 1300 char n; 1301 REQUEST(xvQueryEncodingsReq); 1302 swaps(&stuff->length, n); 1303 swapl(&stuff->port, n); 1304 return XvProcVector[xv_QueryEncodings](client); 1305} 1306 1307static int 1308SProcXvGrabPort(ClientPtr client) 1309{ 1310 char n; 1311 REQUEST(xvGrabPortReq); 1312 swaps(&stuff->length, n); 1313 swapl(&stuff->port, n); 1314 swapl(&stuff->time, n); 1315 return XvProcVector[xv_GrabPort](client); 1316} 1317 1318static int 1319SProcXvUngrabPort(ClientPtr client) 1320{ 1321 char n; 1322 REQUEST(xvUngrabPortReq); 1323 swaps(&stuff->length, n); 1324 swapl(&stuff->port, n); 1325 swapl(&stuff->time, n); 1326 return XvProcVector[xv_UngrabPort](client); 1327} 1328 1329static int 1330SProcXvPutVideo(ClientPtr client) 1331{ 1332 char n; 1333 REQUEST(xvPutVideoReq); 1334 swaps(&stuff->length, n); 1335 swapl(&stuff->port, n); 1336 swapl(&stuff->drawable, n); 1337 swapl(&stuff->gc, n); 1338 swaps(&stuff->vid_x, n); 1339 swaps(&stuff->vid_y, n); 1340 swaps(&stuff->vid_w, n); 1341 swaps(&stuff->vid_h, n); 1342 swaps(&stuff->drw_x, n); 1343 swaps(&stuff->drw_y, n); 1344 swaps(&stuff->drw_w, n); 1345 swaps(&stuff->drw_h, n); 1346 return XvProcVector[xv_PutVideo](client); 1347} 1348 1349static int 1350SProcXvPutStill(ClientPtr client) 1351{ 1352 char n; 1353 REQUEST(xvPutStillReq); 1354 swaps(&stuff->length, n); 1355 swapl(&stuff->port, n); 1356 swapl(&stuff->drawable, n); 1357 swapl(&stuff->gc, n); 1358 swaps(&stuff->vid_x, n); 1359 swaps(&stuff->vid_y, n); 1360 swaps(&stuff->vid_w, n); 1361 swaps(&stuff->vid_h, n); 1362 swaps(&stuff->drw_x, n); 1363 swaps(&stuff->drw_y, n); 1364 swaps(&stuff->drw_w, n); 1365 swaps(&stuff->drw_h, n); 1366 return XvProcVector[xv_PutStill](client); 1367} 1368 1369static int 1370SProcXvGetVideo(ClientPtr client) 1371{ 1372 char n; 1373 REQUEST(xvGetVideoReq); 1374 swaps(&stuff->length, n); 1375 swapl(&stuff->port, n); 1376 swapl(&stuff->drawable, n); 1377 swapl(&stuff->gc, n); 1378 swaps(&stuff->vid_x, n); 1379 swaps(&stuff->vid_y, n); 1380 swaps(&stuff->vid_w, n); 1381 swaps(&stuff->vid_h, n); 1382 swaps(&stuff->drw_x, n); 1383 swaps(&stuff->drw_y, n); 1384 swaps(&stuff->drw_w, n); 1385 swaps(&stuff->drw_h, n); 1386 return XvProcVector[xv_GetVideo](client); 1387} 1388 1389static int 1390SProcXvGetStill(ClientPtr client) 1391{ 1392 char n; 1393 REQUEST(xvGetStillReq); 1394 swaps(&stuff->length, n); 1395 swapl(&stuff->port, n); 1396 swapl(&stuff->drawable, n); 1397 swapl(&stuff->gc, n); 1398 swaps(&stuff->vid_x, n); 1399 swaps(&stuff->vid_y, n); 1400 swaps(&stuff->vid_w, n); 1401 swaps(&stuff->vid_h, n); 1402 swaps(&stuff->drw_x, n); 1403 swaps(&stuff->drw_y, n); 1404 swaps(&stuff->drw_w, n); 1405 swaps(&stuff->drw_h, n); 1406 return XvProcVector[xv_GetStill](client); 1407} 1408 1409static int 1410SProcXvPutImage(ClientPtr client) 1411{ 1412 char n; 1413 REQUEST(xvPutImageReq); 1414 swaps(&stuff->length, n); 1415 swapl(&stuff->port, n); 1416 swapl(&stuff->drawable, n); 1417 swapl(&stuff->gc, n); 1418 swapl(&stuff->id, n); 1419 swaps(&stuff->src_x, n); 1420 swaps(&stuff->src_y, n); 1421 swaps(&stuff->src_w, n); 1422 swaps(&stuff->src_h, n); 1423 swaps(&stuff->drw_x, n); 1424 swaps(&stuff->drw_y, n); 1425 swaps(&stuff->drw_w, n); 1426 swaps(&stuff->drw_h, n); 1427 swaps(&stuff->width, n); 1428 swaps(&stuff->height, n); 1429 return XvProcVector[xv_PutImage](client); 1430} 1431 1432#ifdef MITSHM 1433static int 1434SProcXvShmPutImage(ClientPtr client) 1435{ 1436 char n; 1437 REQUEST(xvShmPutImageReq); 1438 swaps(&stuff->length, n); 1439 swapl(&stuff->port, n); 1440 swapl(&stuff->drawable, n); 1441 swapl(&stuff->gc, n); 1442 swapl(&stuff->shmseg, n); 1443 swapl(&stuff->id, n); 1444 swapl(&stuff->offset, n); 1445 swaps(&stuff->src_x, n); 1446 swaps(&stuff->src_y, n); 1447 swaps(&stuff->src_w, n); 1448 swaps(&stuff->src_h, n); 1449 swaps(&stuff->drw_x, n); 1450 swaps(&stuff->drw_y, n); 1451 swaps(&stuff->drw_w, n); 1452 swaps(&stuff->drw_h, n); 1453 swaps(&stuff->width, n); 1454 swaps(&stuff->height, n); 1455 return XvProcVector[xv_ShmPutImage](client); 1456} 1457#else /* MITSHM */ 1458#define SProcXvShmPutImage ProcXvShmPutImage 1459#endif 1460 1461static int 1462SProcXvSelectVideoNotify(ClientPtr client) 1463{ 1464 char n; 1465 REQUEST(xvSelectVideoNotifyReq); 1466 swaps(&stuff->length, n); 1467 swapl(&stuff->drawable, n); 1468 return XvProcVector[xv_SelectVideoNotify](client); 1469} 1470 1471static int 1472SProcXvSelectPortNotify(ClientPtr client) 1473{ 1474 char n; 1475 REQUEST(xvSelectPortNotifyReq); 1476 swaps(&stuff->length, n); 1477 swapl(&stuff->port, n); 1478 return XvProcVector[xv_SelectPortNotify](client); 1479} 1480 1481static int 1482SProcXvStopVideo(ClientPtr client) 1483{ 1484 char n; 1485 REQUEST(xvStopVideoReq); 1486 swaps(&stuff->length, n); 1487 swapl(&stuff->port, n); 1488 swapl(&stuff->drawable, n); 1489 return XvProcVector[xv_StopVideo](client); 1490} 1491 1492static int 1493SProcXvSetPortAttribute(ClientPtr client) 1494{ 1495 char n; 1496 REQUEST(xvSetPortAttributeReq); 1497 swaps(&stuff->length, n); 1498 swapl(&stuff->port, n); 1499 swapl(&stuff->attribute, n); 1500 swapl(&stuff->value, n); 1501 return XvProcVector[xv_SetPortAttribute](client); 1502} 1503 1504static int 1505SProcXvGetPortAttribute(ClientPtr client) 1506{ 1507 char n; 1508 REQUEST(xvGetPortAttributeReq); 1509 swaps(&stuff->length, n); 1510 swapl(&stuff->port, n); 1511 swapl(&stuff->attribute, n); 1512 return XvProcVector[xv_GetPortAttribute](client); 1513} 1514 1515static int 1516SProcXvQueryBestSize(ClientPtr client) 1517{ 1518 char n; 1519 REQUEST(xvQueryBestSizeReq); 1520 swaps(&stuff->length, n); 1521 swapl(&stuff->port, n); 1522 swaps(&stuff->vid_w, n); 1523 swaps(&stuff->vid_h, n); 1524 swaps(&stuff->drw_w, n); 1525 swaps(&stuff->drw_h, n); 1526 return XvProcVector[xv_QueryBestSize](client); 1527} 1528 1529static int 1530SProcXvQueryPortAttributes(ClientPtr client) 1531{ 1532 char n; 1533 REQUEST(xvQueryPortAttributesReq); 1534 swaps(&stuff->length, n); 1535 swapl(&stuff->port, n); 1536 return XvProcVector[xv_QueryPortAttributes](client); 1537} 1538 1539static int 1540SProcXvQueryImageAttributes(ClientPtr client) 1541{ 1542 char n; 1543 REQUEST(xvQueryImageAttributesReq); 1544 swaps(&stuff->length, n); 1545 swapl(&stuff->port, n); 1546 swapl(&stuff->id, n); 1547 swaps(&stuff->width, n); 1548 swaps(&stuff->height, n); 1549 return XvProcVector[xv_QueryImageAttributes](client); 1550} 1551 1552static int 1553SProcXvListImageFormats(ClientPtr client) 1554{ 1555 char n; 1556 REQUEST(xvListImageFormatsReq); 1557 swaps(&stuff->length, n); 1558 swapl(&stuff->port, n); 1559 return XvProcVector[xv_ListImageFormats](client); 1560} 1561 1562static int (*SXvProcVector[xvNumRequests])(ClientPtr) = { 1563 SProcXvQueryExtension, 1564 SProcXvQueryAdaptors, 1565 SProcXvQueryEncodings, 1566 SProcXvGrabPort, 1567 SProcXvUngrabPort, 1568 SProcXvPutVideo, 1569 SProcXvPutStill, 1570 SProcXvGetVideo, 1571 SProcXvGetStill, 1572 SProcXvStopVideo, 1573 SProcXvSelectVideoNotify, 1574 SProcXvSelectPortNotify, 1575 SProcXvQueryBestSize, 1576 SProcXvSetPortAttribute, 1577 SProcXvGetPortAttribute, 1578 SProcXvQueryPortAttributes, 1579 SProcXvListImageFormats, 1580 SProcXvQueryImageAttributes, 1581 SProcXvPutImage, 1582 SProcXvShmPutImage, 1583}; 1584 1585int 1586SProcXvDispatch(ClientPtr client) 1587{ 1588 REQUEST(xReq); 1589 1590 UpdateCurrentTime(); 1591 1592 if (stuff->data >= xvNumRequests) { 1593 SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); 1594 return BadRequest; 1595 } 1596 1597 return SXvProcVector[stuff->data](client); 1598} 1599 1600#ifdef PANORAMIX 1601static int 1602XineramaXvStopVideo(ClientPtr client) 1603{ 1604 int result, i; 1605 PanoramiXRes *draw, *port; 1606 REQUEST(xvStopVideoReq); 1607 REQUEST_SIZE_MATCH(xvStopVideoReq); 1608 1609 result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1610 XRC_DRAWABLE, client, DixWriteAccess); 1611 if (result != Success) 1612 return (result == BadValue) ? BadDrawable : result; 1613 1614 result = dixLookupResourceByType((pointer *)&port, stuff->port, 1615 XvXRTPort, client, DixReadAccess); 1616 if (result != Success) 1617 return result; 1618 1619 FOR_NSCREENS_BACKWARD(i) { 1620 if(port->info[i].id) { 1621 stuff->drawable = draw->info[i].id; 1622 stuff->port = port->info[i].id; 1623 result = ProcXvStopVideo(client); 1624 } 1625 } 1626 1627 return result; 1628} 1629 1630static int 1631XineramaXvSetPortAttribute(ClientPtr client) 1632{ 1633 REQUEST(xvSetPortAttributeReq); 1634 PanoramiXRes *port; 1635 int result, i; 1636 1637 REQUEST_SIZE_MATCH(xvSetPortAttributeReq); 1638 1639 result = dixLookupResourceByType((pointer *)&port, stuff->port, 1640 XvXRTPort, client, DixReadAccess); 1641 if (result != Success) 1642 return result; 1643 1644 FOR_NSCREENS_BACKWARD(i) { 1645 if(port->info[i].id) { 1646 stuff->port = port->info[i].id; 1647 result = ProcXvSetPortAttribute(client); 1648 } 1649 } 1650 return result; 1651} 1652 1653#ifdef MITSHM 1654static int 1655XineramaXvShmPutImage(ClientPtr client) 1656{ 1657 REQUEST(xvShmPutImageReq); 1658 PanoramiXRes *draw, *gc, *port; 1659 Bool send_event = stuff->send_event; 1660 Bool isRoot; 1661 int result, i, x, y; 1662 1663 REQUEST_SIZE_MATCH(xvShmPutImageReq); 1664 1665 result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1666 XRC_DRAWABLE, client, DixWriteAccess); 1667 if (result != Success) 1668 return (result == BadValue) ? BadDrawable : result; 1669 1670 result = dixLookupResourceByType((pointer *)&gc, stuff->gc, 1671 XRT_GC, client, DixReadAccess); 1672 if (result != Success) 1673 return result; 1674 1675 result = dixLookupResourceByType((pointer *)&port, stuff->port, 1676 XvXRTPort, client, DixReadAccess); 1677 if (result != Success) 1678 return result; 1679 1680 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1681 1682 x = stuff->drw_x; 1683 y = stuff->drw_y; 1684 1685 FOR_NSCREENS_BACKWARD(i) { 1686 if(port->info[i].id) { 1687 stuff->drawable = draw->info[i].id; 1688 stuff->port = port->info[i].id; 1689 stuff->gc = gc->info[i].id; 1690 stuff->drw_x = x; 1691 stuff->drw_y = y; 1692 if(isRoot) { 1693 stuff->drw_x -= screenInfo.screens[i]->x; 1694 stuff->drw_y -= screenInfo.screens[i]->y; 1695 } 1696 stuff->send_event = (send_event && !i) ? 1 : 0; 1697 1698 result = ProcXvShmPutImage(client); 1699 } 1700 } 1701 return result; 1702} 1703#else 1704#define XineramaXvShmPutImage ProcXvShmPutImage 1705#endif 1706 1707static int 1708XineramaXvPutImage(ClientPtr client) 1709{ 1710 REQUEST(xvPutImageReq); 1711 PanoramiXRes *draw, *gc, *port; 1712 Bool isRoot; 1713 int result, i, x, y; 1714 1715 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1716 1717 result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1718 XRC_DRAWABLE, client, DixWriteAccess); 1719 if (result != Success) 1720 return (result == BadValue) ? BadDrawable : result; 1721 1722 result = dixLookupResourceByType((pointer *)&gc, stuff->gc, 1723 XRT_GC, client, DixReadAccess); 1724 if (result != Success) 1725 return result; 1726 1727 result = dixLookupResourceByType((pointer *)&port, stuff->port, 1728 XvXRTPort, client, DixReadAccess); 1729 if (result != Success) 1730 return result; 1731 1732 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1733 1734 x = stuff->drw_x; 1735 y = stuff->drw_y; 1736 1737 FOR_NSCREENS_BACKWARD(i) { 1738 if(port->info[i].id) { 1739 stuff->drawable = draw->info[i].id; 1740 stuff->port = port->info[i].id; 1741 stuff->gc = gc->info[i].id; 1742 stuff->drw_x = x; 1743 stuff->drw_y = y; 1744 if(isRoot) { 1745 stuff->drw_x -= screenInfo.screens[i]->x; 1746 stuff->drw_y -= screenInfo.screens[i]->y; 1747 } 1748 1749 result = ProcXvPutImage(client); 1750 } 1751 } 1752 return result; 1753} 1754 1755static int 1756XineramaXvPutVideo(ClientPtr client) 1757{ 1758 REQUEST(xvPutImageReq); 1759 PanoramiXRes *draw, *gc, *port; 1760 Bool isRoot; 1761 int result, i, x, y; 1762 1763 REQUEST_AT_LEAST_SIZE(xvPutVideoReq); 1764 1765 result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1766 XRC_DRAWABLE, client, DixWriteAccess); 1767 if (result != Success) 1768 return (result == BadValue) ? BadDrawable : result; 1769 1770 result = dixLookupResourceByType((pointer *)&gc, stuff->gc, 1771 XRT_GC, client, DixReadAccess); 1772 if (result != Success) 1773 return result; 1774 1775 result = dixLookupResourceByType((pointer *)&port, stuff->port, 1776 XvXRTPort, client, DixReadAccess); 1777 if (result != Success) 1778 return result; 1779 1780 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1781 1782 x = stuff->drw_x; 1783 y = stuff->drw_y; 1784 1785 FOR_NSCREENS_BACKWARD(i) { 1786 if(port->info[i].id) { 1787 stuff->drawable = draw->info[i].id; 1788 stuff->port = port->info[i].id; 1789 stuff->gc = gc->info[i].id; 1790 stuff->drw_x = x; 1791 stuff->drw_y = y; 1792 if(isRoot) { 1793 stuff->drw_x -= screenInfo.screens[i]->x; 1794 stuff->drw_y -= screenInfo.screens[i]->y; 1795 } 1796 1797 result = ProcXvPutVideo(client); 1798 } 1799 } 1800 return result; 1801} 1802 1803static int 1804XineramaXvPutStill(ClientPtr client) 1805{ 1806 REQUEST(xvPutImageReq); 1807 PanoramiXRes *draw, *gc, *port; 1808 Bool isRoot; 1809 int result, i, x, y; 1810 1811 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1812 1813 result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1814 XRC_DRAWABLE, client, DixWriteAccess); 1815 if (result != Success) 1816 return (result == BadValue) ? BadDrawable : result; 1817 1818 result = dixLookupResourceByType((pointer *)&gc, stuff->gc, 1819 XRT_GC, client, DixReadAccess); 1820 if (result != Success) 1821 return result; 1822 1823 result = dixLookupResourceByType((pointer *)&port, stuff->port, 1824 XvXRTPort, client, DixReadAccess); 1825 if (result != Success) 1826 return result; 1827 1828 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1829 1830 x = stuff->drw_x; 1831 y = stuff->drw_y; 1832 1833 FOR_NSCREENS_BACKWARD(i) { 1834 if(port->info[i].id) { 1835 stuff->drawable = draw->info[i].id; 1836 stuff->port = port->info[i].id; 1837 stuff->gc = gc->info[i].id; 1838 stuff->drw_x = x; 1839 stuff->drw_y = y; 1840 if(isRoot) { 1841 stuff->drw_x -= screenInfo.screens[i]->x; 1842 stuff->drw_y -= screenInfo.screens[i]->y; 1843 } 1844 1845 result = ProcXvPutStill(client); 1846 } 1847 } 1848 return result; 1849} 1850 1851static Bool 1852isImageAdaptor(XvAdaptorPtr pAdapt) 1853{ 1854 return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0); 1855} 1856 1857static Bool 1858hasOverlay(XvAdaptorPtr pAdapt) 1859{ 1860 int i; 1861 for(i = 0; i < pAdapt->nAttributes; i++) 1862 if(!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY")) 1863 return TRUE; 1864 return FALSE; 1865} 1866 1867static XvAdaptorPtr 1868matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay) 1869{ 1870 int i; 1871 XvScreenPtr xvsp = dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey()); 1872 /* Do not try to go on if xv is not supported on this screen */ 1873 if(xvsp == NULL) 1874 return NULL; 1875 1876 /* if the adaptor has the same name it's a perfect match */ 1877 for(i = 0; i < xvsp->nAdaptors; i++) { 1878 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; 1879 if(!strcmp(refAdapt->name, pAdapt->name)) 1880 return pAdapt; 1881 } 1882 1883 /* otherwise we only look for XvImage adaptors */ 1884 if(!isImageAdaptor(refAdapt)) 1885 return NULL; 1886 1887 /* prefer overlay/overlay non-overlay/non-overlay pairing */ 1888 for(i = 0; i < xvsp->nAdaptors; i++) { 1889 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; 1890 if(isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt)) 1891 return pAdapt; 1892 } 1893 1894 /* but we'll take any XvImage pairing if we can get it */ 1895 for(i = 0; i < xvsp->nAdaptors; i++) { 1896 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; 1897 if(isImageAdaptor(pAdapt)) 1898 return pAdapt; 1899 } 1900 return NULL; 1901} 1902 1903void XineramifyXv(void) 1904{ 1905 XvScreenPtr xvsp0 = dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey()); 1906 XvAdaptorPtr MatchingAdaptors[MAXSCREENS]; 1907 int i, j, k; 1908 1909 XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort"); 1910 1911 if (!xvsp0 || !XvXRTPort) return; 1912 SetResourceTypeErrorValue(XvXRTPort, _XvBadPort); 1913 1914 for(i = 0; i < xvsp0->nAdaptors; i++) { 1915 Bool isOverlay; 1916 XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i; 1917 if(!(refAdapt->type & XvInputMask)) continue; 1918 1919 MatchingAdaptors[0] = refAdapt; 1920 isOverlay = hasOverlay(refAdapt); 1921 for(j = 1; j < PanoramiXNumScreens; j++) 1922 MatchingAdaptors[j] = matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay); 1923 1924 /* now create a resource for each port */ 1925 for(j = 0; j < refAdapt->nPorts; j++) { 1926 PanoramiXRes *port = malloc(sizeof(PanoramiXRes)); 1927 if(!port) 1928 break; 1929 1930 for(k = 0; k < PanoramiXNumScreens; k++) { 1931 if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 1932 port->info[k].id = MatchingAdaptors[k]->base_id + j; 1933 else 1934 port->info[k].id = 0; 1935 } 1936 AddResource(port->info[0].id, XvXRTPort, port); 1937 } 1938 } 1939 1940 /* munge the dispatch vector */ 1941 XvProcVector[xv_PutVideo] = XineramaXvPutVideo; 1942 XvProcVector[xv_PutStill] = XineramaXvPutStill; 1943 XvProcVector[xv_StopVideo] = XineramaXvStopVideo; 1944 XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute; 1945 XvProcVector[xv_PutImage] = XineramaXvPutImage; 1946 XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage; 1947} 1948#endif /* PANORAMIX */ 1949 1950void 1951XvResetProcVector(void) 1952{ 1953#ifdef PANORAMIX 1954 XvProcVector[xv_PutVideo] = ProcXvPutVideo; 1955 XvProcVector[xv_PutStill] = ProcXvPutStill; 1956 XvProcVector[xv_StopVideo] = ProcXvStopVideo; 1957 XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute; 1958 XvProcVector[xv_PutImage] = ProcXvPutImage; 1959 XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage; 1960#endif 1961} 1962