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