xvdisp.c revision f7df2e56
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 SendErrorToClient(client, XvReqCode, xv_ShmPutImage, 0, BadImplementation); 953 return BadImplementation; 954} 955#endif 956 957#ifdef XvMCExtension 958#include "xvmcext.h" 959#endif 960 961static int 962ProcXvQueryImageAttributes(ClientPtr client) 963{ 964 xvQueryImageAttributesReply rep; 965 int size, num_planes, i; 966 CARD16 width, height; 967 XvImagePtr pImage = NULL; 968 XvPortPtr pPort; 969 int *offsets; 970 int *pitches; 971 int planeLength; 972 973 REQUEST(xvQueryImageAttributesReq); 974 975 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); 976 977 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); 978 979 for (i = 0; i < pPort->pAdaptor->nImages; i++) { 980 if (pPort->pAdaptor->pImages[i].id == stuff->id) { 981 pImage = &(pPort->pAdaptor->pImages[i]); 982 break; 983 } 984 } 985 986#ifdef XvMCExtension 987 if (!pImage) 988 pImage = XvMCFindXvImage(pPort, stuff->id); 989#endif 990 991 if (!pImage) 992 return BadMatch; 993 994 num_planes = pImage->num_planes; 995 996 if (!(offsets = malloc(num_planes << 3))) 997 return BadAlloc; 998 pitches = offsets + num_planes; 999 1000 width = stuff->width; 1001 height = stuff->height; 1002 1003 size = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage, 1004 &width, &height, offsets, 1005 pitches); 1006 1007 rep = (xvQueryImageAttributesReply) { 1008 .type = X_Reply, 1009 .sequenceNumber = client->sequence, 1010 .length = planeLength = num_planes << 1, 1011 .num_planes = num_planes, 1012 .width = width, 1013 .height = height, 1014 .data_size = size 1015 }; 1016 1017 _WriteQueryImageAttributesReply(client, &rep); 1018 if (client->swapped) 1019 SwapLongs((CARD32 *) offsets, planeLength); 1020 WriteToClient(client, planeLength << 2, offsets); 1021 1022 free(offsets); 1023 1024 return Success; 1025} 1026 1027static int 1028ProcXvListImageFormats(ClientPtr client) 1029{ 1030 XvPortPtr pPort; 1031 XvImagePtr pImage; 1032 int i; 1033 xvListImageFormatsReply rep; 1034 xvImageFormatInfo info; 1035 1036 REQUEST(xvListImageFormatsReq); 1037 1038 REQUEST_SIZE_MATCH(xvListImageFormatsReq); 1039 1040 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); 1041 1042 rep = (xvListImageFormatsReply) { 1043 .type = X_Reply, 1044 .sequenceNumber = client->sequence, 1045 .num_formats = pPort->pAdaptor->nImages, 1046 .length = 1047 bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo) 1048 }; 1049 1050 _WriteListImageFormatsReply(client, &rep); 1051 1052 pImage = pPort->pAdaptor->pImages; 1053 1054 for (i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) { 1055 info.id = pImage->id; 1056 info.type = pImage->type; 1057 info.byte_order = pImage->byte_order; 1058 memcpy(&info.guid, pImage->guid, 16); 1059 info.bpp = pImage->bits_per_pixel; 1060 info.num_planes = pImage->num_planes; 1061 info.depth = pImage->depth; 1062 info.red_mask = pImage->red_mask; 1063 info.green_mask = pImage->green_mask; 1064 info.blue_mask = pImage->blue_mask; 1065 info.format = pImage->format; 1066 info.y_sample_bits = pImage->y_sample_bits; 1067 info.u_sample_bits = pImage->u_sample_bits; 1068 info.v_sample_bits = pImage->v_sample_bits; 1069 info.horz_y_period = pImage->horz_y_period; 1070 info.horz_u_period = pImage->horz_u_period; 1071 info.horz_v_period = pImage->horz_v_period; 1072 info.vert_y_period = pImage->vert_y_period; 1073 info.vert_u_period = pImage->vert_u_period; 1074 info.vert_v_period = pImage->vert_v_period; 1075 memcpy(&info.comp_order, pImage->component_order, 32); 1076 info.scanline_order = pImage->scanline_order; 1077 _WriteImageFormatInfo(client, &info); 1078 } 1079 1080 return Success; 1081} 1082 1083static int (*XvProcVector[xvNumRequests]) (ClientPtr) = { 1084ProcXvQueryExtension, 1085 ProcXvQueryAdaptors, 1086 ProcXvQueryEncodings, 1087 ProcXvGrabPort, 1088 ProcXvUngrabPort, 1089 ProcXvPutVideo, 1090 ProcXvPutStill, 1091 ProcXvGetVideo, 1092 ProcXvGetStill, 1093 ProcXvStopVideo, 1094 ProcXvSelectVideoNotify, 1095 ProcXvSelectPortNotify, 1096 ProcXvQueryBestSize, 1097 ProcXvSetPortAttribute, 1098 ProcXvGetPortAttribute, 1099 ProcXvQueryPortAttributes, 1100 ProcXvListImageFormats, 1101 ProcXvQueryImageAttributes, ProcXvPutImage, ProcXvShmPutImage,}; 1102 1103int 1104ProcXvDispatch(ClientPtr client) 1105{ 1106 REQUEST(xReq); 1107 1108 UpdateCurrentTime(); 1109 1110 if (stuff->data >= xvNumRequests) { 1111 SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); 1112 return BadRequest; 1113 } 1114 1115 return XvProcVector[stuff->data] (client); 1116} 1117 1118/* Swapped Procs */ 1119 1120static int 1121SProcXvQueryExtension(ClientPtr client) 1122{ 1123 REQUEST(xvQueryExtensionReq); 1124 REQUEST_SIZE_MATCH(xvQueryExtensionReq); 1125 swaps(&stuff->length); 1126 return XvProcVector[xv_QueryExtension] (client); 1127} 1128 1129static int 1130SProcXvQueryAdaptors(ClientPtr client) 1131{ 1132 REQUEST(xvQueryAdaptorsReq); 1133 REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); 1134 swaps(&stuff->length); 1135 swapl(&stuff->window); 1136 return XvProcVector[xv_QueryAdaptors] (client); 1137} 1138 1139static int 1140SProcXvQueryEncodings(ClientPtr client) 1141{ 1142 REQUEST(xvQueryEncodingsReq); 1143 REQUEST_SIZE_MATCH(xvQueryEncodingsReq); 1144 swaps(&stuff->length); 1145 swapl(&stuff->port); 1146 return XvProcVector[xv_QueryEncodings] (client); 1147} 1148 1149static int 1150SProcXvGrabPort(ClientPtr client) 1151{ 1152 REQUEST(xvGrabPortReq); 1153 REQUEST_SIZE_MATCH(xvGrabPortReq); 1154 swaps(&stuff->length); 1155 swapl(&stuff->port); 1156 swapl(&stuff->time); 1157 return XvProcVector[xv_GrabPort] (client); 1158} 1159 1160static int 1161SProcXvUngrabPort(ClientPtr client) 1162{ 1163 REQUEST(xvUngrabPortReq); 1164 REQUEST_SIZE_MATCH(xvUngrabPortReq); 1165 swaps(&stuff->length); 1166 swapl(&stuff->port); 1167 swapl(&stuff->time); 1168 return XvProcVector[xv_UngrabPort] (client); 1169} 1170 1171static int 1172SProcXvPutVideo(ClientPtr client) 1173{ 1174 REQUEST(xvPutVideoReq); 1175 REQUEST_SIZE_MATCH(xvPutVideoReq); 1176 swaps(&stuff->length); 1177 swapl(&stuff->port); 1178 swapl(&stuff->drawable); 1179 swapl(&stuff->gc); 1180 swaps(&stuff->vid_x); 1181 swaps(&stuff->vid_y); 1182 swaps(&stuff->vid_w); 1183 swaps(&stuff->vid_h); 1184 swaps(&stuff->drw_x); 1185 swaps(&stuff->drw_y); 1186 swaps(&stuff->drw_w); 1187 swaps(&stuff->drw_h); 1188 return XvProcVector[xv_PutVideo] (client); 1189} 1190 1191static int 1192SProcXvPutStill(ClientPtr client) 1193{ 1194 REQUEST(xvPutStillReq); 1195 REQUEST_SIZE_MATCH(xvPutStillReq); 1196 swaps(&stuff->length); 1197 swapl(&stuff->port); 1198 swapl(&stuff->drawable); 1199 swapl(&stuff->gc); 1200 swaps(&stuff->vid_x); 1201 swaps(&stuff->vid_y); 1202 swaps(&stuff->vid_w); 1203 swaps(&stuff->vid_h); 1204 swaps(&stuff->drw_x); 1205 swaps(&stuff->drw_y); 1206 swaps(&stuff->drw_w); 1207 swaps(&stuff->drw_h); 1208 return XvProcVector[xv_PutStill] (client); 1209} 1210 1211static int 1212SProcXvGetVideo(ClientPtr client) 1213{ 1214 REQUEST(xvGetVideoReq); 1215 REQUEST_SIZE_MATCH(xvGetVideoReq); 1216 swaps(&stuff->length); 1217 swapl(&stuff->port); 1218 swapl(&stuff->drawable); 1219 swapl(&stuff->gc); 1220 swaps(&stuff->vid_x); 1221 swaps(&stuff->vid_y); 1222 swaps(&stuff->vid_w); 1223 swaps(&stuff->vid_h); 1224 swaps(&stuff->drw_x); 1225 swaps(&stuff->drw_y); 1226 swaps(&stuff->drw_w); 1227 swaps(&stuff->drw_h); 1228 return XvProcVector[xv_GetVideo] (client); 1229} 1230 1231static int 1232SProcXvGetStill(ClientPtr client) 1233{ 1234 REQUEST(xvGetStillReq); 1235 REQUEST_SIZE_MATCH(xvGetStillReq); 1236 swaps(&stuff->length); 1237 swapl(&stuff->port); 1238 swapl(&stuff->drawable); 1239 swapl(&stuff->gc); 1240 swaps(&stuff->vid_x); 1241 swaps(&stuff->vid_y); 1242 swaps(&stuff->vid_w); 1243 swaps(&stuff->vid_h); 1244 swaps(&stuff->drw_x); 1245 swaps(&stuff->drw_y); 1246 swaps(&stuff->drw_w); 1247 swaps(&stuff->drw_h); 1248 return XvProcVector[xv_GetStill] (client); 1249} 1250 1251static int 1252SProcXvPutImage(ClientPtr client) 1253{ 1254 REQUEST(xvPutImageReq); 1255 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1256 swaps(&stuff->length); 1257 swapl(&stuff->port); 1258 swapl(&stuff->drawable); 1259 swapl(&stuff->gc); 1260 swapl(&stuff->id); 1261 swaps(&stuff->src_x); 1262 swaps(&stuff->src_y); 1263 swaps(&stuff->src_w); 1264 swaps(&stuff->src_h); 1265 swaps(&stuff->drw_x); 1266 swaps(&stuff->drw_y); 1267 swaps(&stuff->drw_w); 1268 swaps(&stuff->drw_h); 1269 swaps(&stuff->width); 1270 swaps(&stuff->height); 1271 return XvProcVector[xv_PutImage] (client); 1272} 1273 1274#ifdef MITSHM 1275static int 1276SProcXvShmPutImage(ClientPtr client) 1277{ 1278 REQUEST(xvShmPutImageReq); 1279 REQUEST_SIZE_MATCH(xvShmPutImageReq); 1280 swaps(&stuff->length); 1281 swapl(&stuff->port); 1282 swapl(&stuff->drawable); 1283 swapl(&stuff->gc); 1284 swapl(&stuff->shmseg); 1285 swapl(&stuff->id); 1286 swapl(&stuff->offset); 1287 swaps(&stuff->src_x); 1288 swaps(&stuff->src_y); 1289 swaps(&stuff->src_w); 1290 swaps(&stuff->src_h); 1291 swaps(&stuff->drw_x); 1292 swaps(&stuff->drw_y); 1293 swaps(&stuff->drw_w); 1294 swaps(&stuff->drw_h); 1295 swaps(&stuff->width); 1296 swaps(&stuff->height); 1297 return XvProcVector[xv_ShmPutImage] (client); 1298} 1299#else /* MITSHM */ 1300#define SProcXvShmPutImage ProcXvShmPutImage 1301#endif 1302 1303static int 1304SProcXvSelectVideoNotify(ClientPtr client) 1305{ 1306 REQUEST(xvSelectVideoNotifyReq); 1307 REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); 1308 swaps(&stuff->length); 1309 swapl(&stuff->drawable); 1310 return XvProcVector[xv_SelectVideoNotify] (client); 1311} 1312 1313static int 1314SProcXvSelectPortNotify(ClientPtr client) 1315{ 1316 REQUEST(xvSelectPortNotifyReq); 1317 REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); 1318 swaps(&stuff->length); 1319 swapl(&stuff->port); 1320 return XvProcVector[xv_SelectPortNotify] (client); 1321} 1322 1323static int 1324SProcXvStopVideo(ClientPtr client) 1325{ 1326 REQUEST(xvStopVideoReq); 1327 REQUEST_SIZE_MATCH(xvStopVideoReq); 1328 swaps(&stuff->length); 1329 swapl(&stuff->port); 1330 swapl(&stuff->drawable); 1331 return XvProcVector[xv_StopVideo] (client); 1332} 1333 1334static int 1335SProcXvSetPortAttribute(ClientPtr client) 1336{ 1337 REQUEST(xvSetPortAttributeReq); 1338 REQUEST_SIZE_MATCH(xvSetPortAttributeReq); 1339 swaps(&stuff->length); 1340 swapl(&stuff->port); 1341 swapl(&stuff->attribute); 1342 swapl(&stuff->value); 1343 return XvProcVector[xv_SetPortAttribute] (client); 1344} 1345 1346static int 1347SProcXvGetPortAttribute(ClientPtr client) 1348{ 1349 REQUEST(xvGetPortAttributeReq); 1350 REQUEST_SIZE_MATCH(xvGetPortAttributeReq); 1351 swaps(&stuff->length); 1352 swapl(&stuff->port); 1353 swapl(&stuff->attribute); 1354 return XvProcVector[xv_GetPortAttribute] (client); 1355} 1356 1357static int 1358SProcXvQueryBestSize(ClientPtr client) 1359{ 1360 REQUEST(xvQueryBestSizeReq); 1361 REQUEST_SIZE_MATCH(xvQueryBestSizeReq); 1362 swaps(&stuff->length); 1363 swapl(&stuff->port); 1364 swaps(&stuff->vid_w); 1365 swaps(&stuff->vid_h); 1366 swaps(&stuff->drw_w); 1367 swaps(&stuff->drw_h); 1368 return XvProcVector[xv_QueryBestSize] (client); 1369} 1370 1371static int 1372SProcXvQueryPortAttributes(ClientPtr client) 1373{ 1374 REQUEST(xvQueryPortAttributesReq); 1375 REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); 1376 swaps(&stuff->length); 1377 swapl(&stuff->port); 1378 return XvProcVector[xv_QueryPortAttributes] (client); 1379} 1380 1381static int 1382SProcXvQueryImageAttributes(ClientPtr client) 1383{ 1384 REQUEST(xvQueryImageAttributesReq); 1385 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); 1386 swaps(&stuff->length); 1387 swapl(&stuff->port); 1388 swapl(&stuff->id); 1389 swaps(&stuff->width); 1390 swaps(&stuff->height); 1391 return XvProcVector[xv_QueryImageAttributes] (client); 1392} 1393 1394static int 1395SProcXvListImageFormats(ClientPtr client) 1396{ 1397 REQUEST(xvListImageFormatsReq); 1398 REQUEST_SIZE_MATCH(xvListImageFormatsReq); 1399 swaps(&stuff->length); 1400 swapl(&stuff->port); 1401 return XvProcVector[xv_ListImageFormats] (client); 1402} 1403 1404static int (*SXvProcVector[xvNumRequests]) (ClientPtr) = { 1405SProcXvQueryExtension, 1406 SProcXvQueryAdaptors, 1407 SProcXvQueryEncodings, 1408 SProcXvGrabPort, 1409 SProcXvUngrabPort, 1410 SProcXvPutVideo, 1411 SProcXvPutStill, 1412 SProcXvGetVideo, 1413 SProcXvGetStill, 1414 SProcXvStopVideo, 1415 SProcXvSelectVideoNotify, 1416 SProcXvSelectPortNotify, 1417 SProcXvQueryBestSize, 1418 SProcXvSetPortAttribute, 1419 SProcXvGetPortAttribute, 1420 SProcXvQueryPortAttributes, 1421 SProcXvListImageFormats, 1422 SProcXvQueryImageAttributes, SProcXvPutImage, SProcXvShmPutImage,}; 1423 1424int 1425SProcXvDispatch(ClientPtr client) 1426{ 1427 REQUEST(xReq); 1428 1429 UpdateCurrentTime(); 1430 1431 if (stuff->data >= xvNumRequests) { 1432 SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); 1433 return BadRequest; 1434 } 1435 1436 return SXvProcVector[stuff->data] (client); 1437} 1438 1439#ifdef PANORAMIX 1440static int 1441XineramaXvStopVideo(ClientPtr client) 1442{ 1443 int result, i; 1444 PanoramiXRes *draw, *port; 1445 1446 REQUEST(xvStopVideoReq); 1447 REQUEST_SIZE_MATCH(xvStopVideoReq); 1448 1449 result = dixLookupResourceByClass((void **) &draw, stuff->drawable, 1450 XRC_DRAWABLE, client, DixWriteAccess); 1451 if (result != Success) 1452 return (result == BadValue) ? BadDrawable : result; 1453 1454 result = dixLookupResourceByType((void **) &port, stuff->port, 1455 XvXRTPort, client, DixReadAccess); 1456 if (result != Success) 1457 return result; 1458 1459 FOR_NSCREENS_BACKWARD(i) { 1460 if (port->info[i].id) { 1461 stuff->drawable = draw->info[i].id; 1462 stuff->port = port->info[i].id; 1463 result = ProcXvStopVideo(client); 1464 } 1465 } 1466 1467 return result; 1468} 1469 1470static int 1471XineramaXvSetPortAttribute(ClientPtr client) 1472{ 1473 REQUEST(xvSetPortAttributeReq); 1474 PanoramiXRes *port; 1475 int result, i; 1476 1477 REQUEST_SIZE_MATCH(xvSetPortAttributeReq); 1478 1479 result = dixLookupResourceByType((void **) &port, stuff->port, 1480 XvXRTPort, client, DixReadAccess); 1481 if (result != Success) 1482 return result; 1483 1484 FOR_NSCREENS_BACKWARD(i) { 1485 if (port->info[i].id) { 1486 stuff->port = port->info[i].id; 1487 result = ProcXvSetPortAttribute(client); 1488 } 1489 } 1490 return result; 1491} 1492 1493#ifdef MITSHM 1494static int 1495XineramaXvShmPutImage(ClientPtr client) 1496{ 1497 REQUEST(xvShmPutImageReq); 1498 PanoramiXRes *draw, *gc, *port; 1499 Bool send_event = stuff->send_event; 1500 Bool isRoot; 1501 int result, i, x, y; 1502 1503 REQUEST_SIZE_MATCH(xvShmPutImageReq); 1504 1505 result = dixLookupResourceByClass((void **) &draw, stuff->drawable, 1506 XRC_DRAWABLE, client, DixWriteAccess); 1507 if (result != Success) 1508 return (result == BadValue) ? BadDrawable : result; 1509 1510 result = dixLookupResourceByType((void **) &gc, stuff->gc, 1511 XRT_GC, client, DixReadAccess); 1512 if (result != Success) 1513 return result; 1514 1515 result = dixLookupResourceByType((void **) &port, stuff->port, 1516 XvXRTPort, client, DixReadAccess); 1517 if (result != Success) 1518 return result; 1519 1520 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1521 1522 x = stuff->drw_x; 1523 y = stuff->drw_y; 1524 1525 FOR_NSCREENS_BACKWARD(i) { 1526 if (port->info[i].id) { 1527 stuff->drawable = draw->info[i].id; 1528 stuff->port = port->info[i].id; 1529 stuff->gc = gc->info[i].id; 1530 stuff->drw_x = x; 1531 stuff->drw_y = y; 1532 if (isRoot) { 1533 stuff->drw_x -= screenInfo.screens[i]->x; 1534 stuff->drw_y -= screenInfo.screens[i]->y; 1535 } 1536 stuff->send_event = (send_event && !i) ? 1 : 0; 1537 1538 result = ProcXvShmPutImage(client); 1539 } 1540 } 1541 return result; 1542} 1543#else 1544#define XineramaXvShmPutImage ProcXvShmPutImage 1545#endif 1546 1547static int 1548XineramaXvPutImage(ClientPtr client) 1549{ 1550 REQUEST(xvPutImageReq); 1551 PanoramiXRes *draw, *gc, *port; 1552 Bool isRoot; 1553 int result, i, x, y; 1554 1555 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1556 1557 result = dixLookupResourceByClass((void **) &draw, stuff->drawable, 1558 XRC_DRAWABLE, client, DixWriteAccess); 1559 if (result != Success) 1560 return (result == BadValue) ? BadDrawable : result; 1561 1562 result = dixLookupResourceByType((void **) &gc, stuff->gc, 1563 XRT_GC, client, DixReadAccess); 1564 if (result != Success) 1565 return result; 1566 1567 result = dixLookupResourceByType((void **) &port, stuff->port, 1568 XvXRTPort, client, DixReadAccess); 1569 if (result != Success) 1570 return result; 1571 1572 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1573 1574 x = stuff->drw_x; 1575 y = stuff->drw_y; 1576 1577 FOR_NSCREENS_BACKWARD(i) { 1578 if (port->info[i].id) { 1579 stuff->drawable = draw->info[i].id; 1580 stuff->port = port->info[i].id; 1581 stuff->gc = gc->info[i].id; 1582 stuff->drw_x = x; 1583 stuff->drw_y = y; 1584 if (isRoot) { 1585 stuff->drw_x -= screenInfo.screens[i]->x; 1586 stuff->drw_y -= screenInfo.screens[i]->y; 1587 } 1588 1589 result = ProcXvPutImage(client); 1590 } 1591 } 1592 return result; 1593} 1594 1595static int 1596XineramaXvPutVideo(ClientPtr client) 1597{ 1598 REQUEST(xvPutImageReq); 1599 PanoramiXRes *draw, *gc, *port; 1600 Bool isRoot; 1601 int result, i, x, y; 1602 1603 REQUEST_AT_LEAST_SIZE(xvPutVideoReq); 1604 1605 result = dixLookupResourceByClass((void **) &draw, stuff->drawable, 1606 XRC_DRAWABLE, client, DixWriteAccess); 1607 if (result != Success) 1608 return (result == BadValue) ? BadDrawable : result; 1609 1610 result = dixLookupResourceByType((void **) &gc, stuff->gc, 1611 XRT_GC, client, DixReadAccess); 1612 if (result != Success) 1613 return result; 1614 1615 result = dixLookupResourceByType((void **) &port, stuff->port, 1616 XvXRTPort, client, DixReadAccess); 1617 if (result != Success) 1618 return result; 1619 1620 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1621 1622 x = stuff->drw_x; 1623 y = stuff->drw_y; 1624 1625 FOR_NSCREENS_BACKWARD(i) { 1626 if (port->info[i].id) { 1627 stuff->drawable = draw->info[i].id; 1628 stuff->port = port->info[i].id; 1629 stuff->gc = gc->info[i].id; 1630 stuff->drw_x = x; 1631 stuff->drw_y = y; 1632 if (isRoot) { 1633 stuff->drw_x -= screenInfo.screens[i]->x; 1634 stuff->drw_y -= screenInfo.screens[i]->y; 1635 } 1636 1637 result = ProcXvPutVideo(client); 1638 } 1639 } 1640 return result; 1641} 1642 1643static int 1644XineramaXvPutStill(ClientPtr client) 1645{ 1646 REQUEST(xvPutImageReq); 1647 PanoramiXRes *draw, *gc, *port; 1648 Bool isRoot; 1649 int result, i, x, y; 1650 1651 REQUEST_AT_LEAST_SIZE(xvPutImageReq); 1652 1653 result = dixLookupResourceByClass((void **) &draw, stuff->drawable, 1654 XRC_DRAWABLE, client, DixWriteAccess); 1655 if (result != Success) 1656 return (result == BadValue) ? BadDrawable : result; 1657 1658 result = dixLookupResourceByType((void **) &gc, stuff->gc, 1659 XRT_GC, client, DixReadAccess); 1660 if (result != Success) 1661 return result; 1662 1663 result = dixLookupResourceByType((void **) &port, stuff->port, 1664 XvXRTPort, client, DixReadAccess); 1665 if (result != Success) 1666 return result; 1667 1668 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 1669 1670 x = stuff->drw_x; 1671 y = stuff->drw_y; 1672 1673 FOR_NSCREENS_BACKWARD(i) { 1674 if (port->info[i].id) { 1675 stuff->drawable = draw->info[i].id; 1676 stuff->port = port->info[i].id; 1677 stuff->gc = gc->info[i].id; 1678 stuff->drw_x = x; 1679 stuff->drw_y = y; 1680 if (isRoot) { 1681 stuff->drw_x -= screenInfo.screens[i]->x; 1682 stuff->drw_y -= screenInfo.screens[i]->y; 1683 } 1684 1685 result = ProcXvPutStill(client); 1686 } 1687 } 1688 return result; 1689} 1690 1691static Bool 1692isImageAdaptor(XvAdaptorPtr pAdapt) 1693{ 1694 return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0); 1695} 1696 1697static Bool 1698hasOverlay(XvAdaptorPtr pAdapt) 1699{ 1700 int i; 1701 1702 for (i = 0; i < pAdapt->nAttributes; i++) 1703 if (!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY")) 1704 return TRUE; 1705 return FALSE; 1706} 1707 1708static XvAdaptorPtr 1709matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay) 1710{ 1711 int i; 1712 XvScreenPtr xvsp = 1713 dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey()); 1714 /* Do not try to go on if xv is not supported on this screen */ 1715 if (xvsp == NULL) 1716 return NULL; 1717 1718 /* if the adaptor has the same name it's a perfect match */ 1719 for (i = 0; i < xvsp->nAdaptors; i++) { 1720 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; 1721 1722 if (!strcmp(refAdapt->name, pAdapt->name)) 1723 return pAdapt; 1724 } 1725 1726 /* otherwise we only look for XvImage adaptors */ 1727 if (!isImageAdaptor(refAdapt)) 1728 return NULL; 1729 1730 /* prefer overlay/overlay non-overlay/non-overlay pairing */ 1731 for (i = 0; i < xvsp->nAdaptors; i++) { 1732 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; 1733 1734 if (isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt)) 1735 return pAdapt; 1736 } 1737 1738 /* but we'll take any XvImage pairing if we can get it */ 1739 for (i = 0; i < xvsp->nAdaptors; i++) { 1740 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; 1741 1742 if (isImageAdaptor(pAdapt)) 1743 return pAdapt; 1744 } 1745 return NULL; 1746} 1747 1748void 1749XineramifyXv(void) 1750{ 1751 XvScreenPtr xvsp0 = 1752 dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey()); 1753 XvAdaptorPtr MatchingAdaptors[MAXSCREENS]; 1754 int i, j, k; 1755 1756 XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort"); 1757 1758 if (!xvsp0 || !XvXRTPort) 1759 return; 1760 SetResourceTypeErrorValue(XvXRTPort, _XvBadPort); 1761 1762 for (i = 0; i < xvsp0->nAdaptors; i++) { 1763 Bool isOverlay; 1764 XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i; 1765 1766 if (!(refAdapt->type & XvInputMask)) 1767 continue; 1768 1769 MatchingAdaptors[0] = refAdapt; 1770 isOverlay = hasOverlay(refAdapt); 1771 FOR_NSCREENS_FORWARD_SKIP(j) 1772 MatchingAdaptors[j] = 1773 matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay); 1774 1775 /* now create a resource for each port */ 1776 for (j = 0; j < refAdapt->nPorts; j++) { 1777 PanoramiXRes *port = malloc(sizeof(PanoramiXRes)); 1778 1779 if (!port) 1780 break; 1781 1782 FOR_NSCREENS(k) { 1783 if (MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 1784 port->info[k].id = MatchingAdaptors[k]->base_id + j; 1785 else 1786 port->info[k].id = 0; 1787 } 1788 AddResource(port->info[0].id, XvXRTPort, port); 1789 } 1790 } 1791 1792 /* munge the dispatch vector */ 1793 XvProcVector[xv_PutVideo] = XineramaXvPutVideo; 1794 XvProcVector[xv_PutStill] = XineramaXvPutStill; 1795 XvProcVector[xv_StopVideo] = XineramaXvStopVideo; 1796 XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute; 1797 XvProcVector[xv_PutImage] = XineramaXvPutImage; 1798 XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage; 1799} 1800#endif /* PANORAMIX */ 1801 1802void 1803XvResetProcVector(void) 1804{ 1805#ifdef PANORAMIX 1806 XvProcVector[xv_PutVideo] = ProcXvPutVideo; 1807 XvProcVector[xv_PutStill] = ProcXvPutStill; 1808 XvProcVector[xv_StopVideo] = ProcXvStopVideo; 1809 XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute; 1810 XvProcVector[xv_PutImage] = ProcXvPutImage; 1811 XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage; 1812#endif 1813} 1814