xvmc.c revision 05b261ec
1 2#define NEED_REPLIES 3#define NEED_EVENTS 4#ifdef HAVE_DIX_CONFIG_H 5#include <dix-config.h> 6#endif 7 8#include <string.h> 9 10#include <X11/X.h> 11#include <X11/Xproto.h> 12#include "misc.h" 13#include "os.h" 14#include "dixstruct.h" 15#include "resource.h" 16#include "scrnintstr.h" 17#include "extnsionst.h" 18#include "servermd.h" 19#include <X11/Xfuncproto.h> 20#include "xvdix.h" 21#include <X11/extensions/XvMC.h> 22#include <X11/extensions/Xvproto.h> 23#include <X11/extensions/XvMCproto.h> 24#include "xvmcext.h" 25 26#ifdef HAS_XVMCSHM 27#ifndef Lynx 28#include <sys/ipc.h> 29#include <sys/types.h> 30#include <sys/shm.h> 31#else 32#include <ipc.h> 33#include <shm.h> 34#endif /* Lynx */ 35#endif /* HAS_XVMCSHM */ 36 37 38 39#define DR_CLIENT_DRIVER_NAME_SIZE 48 40#define DR_BUSID_SIZE 48 41 42int XvMCScreenIndex = -1; 43 44unsigned long XvMCGeneration = 0; 45 46int XvMCReqCode; 47int XvMCEventBase; 48int XvMCErrorBase; 49 50unsigned long XvMCRTContext; 51unsigned long XvMCRTSurface; 52unsigned long XvMCRTSubpicture; 53 54typedef struct { 55 int num_adaptors; 56 XvMCAdaptorPtr adaptors; 57 CloseScreenProcPtr CloseScreen; 58 char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE]; 59 char busID[DR_BUSID_SIZE]; 60 int major; 61 int minor; 62 int patchLevel; 63} XvMCScreenRec, *XvMCScreenPtr; 64 65#define XVMC_GET_PRIVATE(pScreen) \ 66 (XvMCScreenPtr)((pScreen)->devPrivates[XvMCScreenIndex].ptr) 67 68 69static int 70XvMCDestroyContextRes(pointer data, XID id) 71{ 72 XvMCContextPtr pContext = (XvMCContextPtr)data; 73 74 pContext->refcnt--; 75 76 if(!pContext->refcnt) { 77 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); 78 (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext)(pContext); 79 xfree(pContext); 80 } 81 82 return Success; 83} 84 85static int 86XvMCDestroySurfaceRes(pointer data, XID id) 87{ 88 XvMCSurfacePtr pSurface = (XvMCSurfacePtr)data; 89 XvMCContextPtr pContext = pSurface->context; 90 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); 91 92 (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface)(pSurface); 93 xfree(pSurface); 94 95 XvMCDestroyContextRes((pointer)pContext, pContext->context_id); 96 97 return Success; 98} 99 100 101static int 102XvMCDestroySubpictureRes(pointer data, XID id) 103{ 104 XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr)data; 105 XvMCContextPtr pContext = pSubpict->context; 106 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); 107 108 (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture)(pSubpict); 109 xfree(pSubpict); 110 111 XvMCDestroyContextRes((pointer)pContext, pContext->context_id); 112 113 return Success; 114} 115 116static void 117XvMCResetProc (ExtensionEntry *extEntry) 118{ 119} 120 121 122static int 123ProcXvMCQueryVersion(ClientPtr client) 124{ 125 xvmcQueryVersionReply rep; 126 /* REQUEST(xvmcQueryVersionReq); */ 127 REQUEST_SIZE_MATCH(xvmcQueryVersionReq); 128 rep.type = X_Reply; 129 rep.sequenceNumber = client->sequence; 130 rep.length = 0; 131 rep.major = XvMCVersion; 132 rep.minor = XvMCRevision; 133 WriteToClient(client, sizeof(xvmcQueryVersionReply), (char*)&rep); 134 return Success; 135} 136 137 138static int 139ProcXvMCListSurfaceTypes(ClientPtr client) 140{ 141 XvPortPtr pPort; 142 int i; 143 XvMCScreenPtr pScreenPriv; 144 xvmcListSurfaceTypesReply rep; 145 xvmcSurfaceInfo info; 146 XvMCAdaptorPtr adaptor = NULL; 147 XvMCSurfaceInfoPtr surface; 148 REQUEST(xvmcListSurfaceTypesReq); 149 REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq); 150 151 if(!(pPort = LOOKUP_PORT(stuff->port, client))) { 152 client->errorValue = stuff->port; 153 return _XvBadPort; 154 } 155 156 if(XvMCScreenIndex >= 0) { /* any adaptors at all */ 157 ScreenPtr pScreen = pPort->pAdaptor->pScreen; 158 if((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */ 159 for(i = 0; i < pScreenPriv->num_adaptors; i++) { 160 if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { 161 adaptor = &(pScreenPriv->adaptors[i]); 162 break; 163 } 164 } 165 } 166 } 167 168 rep.type = X_Reply; 169 rep.sequenceNumber = client->sequence; 170 rep.num = (adaptor) ? adaptor->num_surfaces : 0; 171 rep.length = rep.num * sizeof(xvmcSurfaceInfo) >> 2; 172 173 WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), (char*)&rep); 174 175 for(i = 0; i < rep.num; i++) { 176 surface = adaptor->surfaces[i]; 177 info.surface_type_id = surface->surface_type_id; 178 info.chroma_format = surface->chroma_format; 179 info.max_width = surface->max_width; 180 info.max_height = surface->max_height; 181 info.subpicture_max_width = surface->subpicture_max_width; 182 info.subpicture_max_height = surface->subpicture_max_height; 183 info.mc_type = surface->mc_type; 184 info.flags = surface->flags; 185 WriteToClient(client, sizeof(xvmcSurfaceInfo), (char*)&info); 186 } 187 188 return Success; 189} 190 191static int 192ProcXvMCCreateContext(ClientPtr client) 193{ 194 XvPortPtr pPort; 195 CARD32 *data = NULL; 196 int dwords = 0; 197 int i, result, adapt_num = -1; 198 ScreenPtr pScreen; 199 XvMCContextPtr pContext; 200 XvMCScreenPtr pScreenPriv; 201 XvMCAdaptorPtr adaptor = NULL; 202 XvMCSurfaceInfoPtr surface = NULL; 203 xvmcCreateContextReply rep; 204 REQUEST(xvmcCreateContextReq); 205 REQUEST_SIZE_MATCH(xvmcCreateContextReq); 206 207 if(!(pPort = LOOKUP_PORT(stuff->port, client))) { 208 client->errorValue = stuff->port; 209 return _XvBadPort; 210 } 211 212 pScreen = pPort->pAdaptor->pScreen; 213 214 if(XvMCScreenIndex < 0) /* no XvMC adaptors */ 215 return BadMatch; 216 217 if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */ 218 return BadMatch; 219 220 for(i = 0; i < pScreenPriv->num_adaptors; i++) { 221 if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { 222 adaptor = &(pScreenPriv->adaptors[i]); 223 adapt_num = i; 224 break; 225 } 226 } 227 228 if(adapt_num < 0) /* none this port */ 229 return BadMatch; 230 231 for(i = 0; i < adaptor->num_surfaces; i++) { 232 if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { 233 surface = adaptor->surfaces[i]; 234 break; 235 } 236 } 237 238 /* adaptor doesn't support this suface_type_id */ 239 if(!surface) return BadMatch; 240 241 242 if((stuff->width > surface->max_width) || 243 (stuff->height > surface->max_height)) 244 return BadValue; 245 246 if(!(pContext = xalloc(sizeof(XvMCContextRec)))) { 247 return BadAlloc; 248 } 249 250 251 pContext->pScreen = pScreen; 252 pContext->adapt_num = adapt_num; 253 pContext->context_id = stuff->context_id; 254 pContext->surface_type_id = stuff->surface_type_id; 255 pContext->width = stuff->width; 256 pContext->height = stuff->height; 257 pContext->flags = stuff->flags; 258 pContext->refcnt = 1; 259 260 result = (*adaptor->CreateContext)(pPort, pContext, &dwords, &data); 261 262 if(result != Success) { 263 xfree(pContext); 264 return result; 265 } 266 267 rep.type = X_Reply; 268 rep.sequenceNumber = client->sequence; 269 rep.width_actual = pContext->width; 270 rep.height_actual = pContext->height; 271 rep.flags_return = pContext->flags; 272 rep.length = dwords; 273 274 WriteToClient(client, sizeof(xvmcCreateContextReply), (char*)&rep); 275 if(dwords) 276 WriteToClient(client, dwords << 2, (char*)data); 277 AddResource(pContext->context_id, XvMCRTContext, pContext); 278 279 if(data) 280 xfree(data); 281 282 return Success; 283} 284 285static int 286ProcXvMCDestroyContext(ClientPtr client) 287{ 288 REQUEST(xvmcDestroyContextReq); 289 REQUEST_SIZE_MATCH(xvmcDestroyContextReq); 290 291 if(!LookupIDByType(stuff->context_id, XvMCRTContext)) 292 return (XvMCBadContext + XvMCErrorBase); 293 294 FreeResource(stuff->context_id, RT_NONE); 295 296 return Success; 297} 298 299static int 300ProcXvMCCreateSurface(ClientPtr client) 301{ 302 CARD32 *data = NULL; 303 int dwords = 0; 304 int result; 305 XvMCContextPtr pContext; 306 XvMCSurfacePtr pSurface; 307 XvMCScreenPtr pScreenPriv; 308 xvmcCreateSurfaceReply rep; 309 REQUEST(xvmcCreateSurfaceReq); 310 REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq); 311 312 if(!(pContext = LookupIDByType(stuff->context_id, XvMCRTContext))) 313 return (XvMCBadContext + XvMCErrorBase); 314 315 pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); 316 317 if(!(pSurface = xalloc(sizeof(XvMCSurfaceRec)))) 318 return BadAlloc; 319 320 pSurface->surface_id = stuff->surface_id; 321 pSurface->surface_type_id = pContext->surface_type_id; 322 pSurface->context = pContext; 323 324 result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface)( 325 pSurface, &dwords, &data); 326 327 if(result != Success) { 328 xfree(pSurface); 329 return result; 330 } 331 332 rep.type = X_Reply; 333 rep.sequenceNumber = client->sequence; 334 rep.length = dwords; 335 336 WriteToClient(client, sizeof(xvmcCreateSurfaceReply), (char*)&rep); 337 if(dwords) 338 WriteToClient(client, dwords << 2, (char*)data); 339 AddResource(pSurface->surface_id, XvMCRTSurface, pSurface); 340 341 if(data) 342 xfree(data); 343 344 pContext->refcnt++; 345 346 return Success; 347} 348 349static int 350ProcXvMCDestroySurface(ClientPtr client) 351{ 352 REQUEST(xvmcDestroySurfaceReq); 353 REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq); 354 355 if(!LookupIDByType(stuff->surface_id, XvMCRTSurface)) 356 return (XvMCBadSurface + XvMCErrorBase); 357 358 FreeResource(stuff->surface_id, RT_NONE); 359 360 return Success; 361} 362 363static int 364ProcXvMCCreateSubpicture(ClientPtr client) 365{ 366 Bool image_supported = FALSE; 367 CARD32 *data = NULL; 368 int i, result, dwords = 0; 369 XvMCContextPtr pContext; 370 XvMCSubpicturePtr pSubpicture; 371 XvMCScreenPtr pScreenPriv; 372 xvmcCreateSubpictureReply rep; 373 XvMCAdaptorPtr adaptor; 374 XvMCSurfaceInfoPtr surface = NULL; 375 REQUEST(xvmcCreateSubpictureReq); 376 REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq); 377 378 if(!(pContext = LookupIDByType(stuff->context_id, XvMCRTContext))) 379 return (XvMCBadContext + XvMCErrorBase); 380 381 pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); 382 383 adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]); 384 385 /* find which surface this context supports */ 386 for(i = 0; i < adaptor->num_surfaces; i++) { 387 if(adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id){ 388 surface = adaptor->surfaces[i]; 389 break; 390 } 391 } 392 393 if(!surface) return BadMatch; 394 395 /* make sure this surface supports that xvimage format */ 396 if(!surface->compatible_subpictures) return BadMatch; 397 398 for(i = 0; i < surface->compatible_subpictures->num_xvimages; i++) { 399 if(surface->compatible_subpictures->xvimage_ids[i] == stuff->xvimage_id) { 400 image_supported = TRUE; 401 break; 402 } 403 } 404 405 if(!image_supported) return BadMatch; 406 407 /* make sure the size is OK */ 408 if((stuff->width > surface->subpicture_max_width) || 409 (stuff->height > surface->subpicture_max_height)) 410 return BadValue; 411 412 if(!(pSubpicture = xalloc(sizeof(XvMCSubpictureRec)))) 413 return BadAlloc; 414 415 pSubpicture->subpicture_id = stuff->subpicture_id; 416 pSubpicture->xvimage_id = stuff->xvimage_id; 417 pSubpicture->width = stuff->width; 418 pSubpicture->height = stuff->height; 419 pSubpicture->num_palette_entries = 0; /* overwritten by DDX */ 420 pSubpicture->entry_bytes = 0; /* overwritten by DDX */ 421 pSubpicture->component_order[0] = 0; /* overwritten by DDX */ 422 pSubpicture->component_order[1] = 0; 423 pSubpicture->component_order[2] = 0; 424 pSubpicture->component_order[3] = 0; 425 pSubpicture->context = pContext; 426 427 result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSubpicture)( 428 pSubpicture, &dwords, &data); 429 430 if(result != Success) { 431 xfree(pSubpicture); 432 return result; 433 } 434 435 rep.type = X_Reply; 436 rep.sequenceNumber = client->sequence; 437 rep.width_actual = pSubpicture->width; 438 rep.height_actual = pSubpicture->height; 439 rep.num_palette_entries = pSubpicture->num_palette_entries; 440 rep.entry_bytes = pSubpicture->entry_bytes; 441 rep.component_order[0] = pSubpicture->component_order[0]; 442 rep.component_order[1] = pSubpicture->component_order[1]; 443 rep.component_order[2] = pSubpicture->component_order[2]; 444 rep.component_order[3] = pSubpicture->component_order[3]; 445 rep.length = dwords; 446 447 WriteToClient(client, sizeof(xvmcCreateSubpictureReply), (char*)&rep); 448 if(dwords) 449 WriteToClient(client, dwords << 2, (char*)data); 450 AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture); 451 452 if(data) 453 xfree(data); 454 455 pContext->refcnt++; 456 457 return Success; 458} 459 460static int 461ProcXvMCDestroySubpicture(ClientPtr client) 462{ 463 REQUEST(xvmcDestroySubpictureReq); 464 REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq); 465 466 if(!LookupIDByType(stuff->subpicture_id, XvMCRTSubpicture)) 467 return (XvMCBadSubpicture + XvMCErrorBase); 468 469 FreeResource(stuff->subpicture_id, RT_NONE); 470 471 return Success; 472} 473 474 475static int 476ProcXvMCListSubpictureTypes(ClientPtr client) 477{ 478 XvPortPtr pPort; 479 xvmcListSubpictureTypesReply rep; 480 XvMCScreenPtr pScreenPriv; 481 ScreenPtr pScreen; 482 XvMCAdaptorPtr adaptor = NULL; 483 XvMCSurfaceInfoPtr surface = NULL; 484 xvImageFormatInfo info; 485 XvImagePtr pImage; 486 int i, j; 487 REQUEST(xvmcListSubpictureTypesReq); 488 REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq); 489 490 if(!(pPort = LOOKUP_PORT(stuff->port, client))) { 491 client->errorValue = stuff->port; 492 return _XvBadPort; 493 } 494 495 pScreen = pPort->pAdaptor->pScreen; 496 497 if(XvMCScreenIndex < 0) /* No XvMC adaptors */ 498 return BadMatch; 499 500 if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) 501 return BadMatch; /* None this screen */ 502 503 for(i = 0; i < pScreenPriv->num_adaptors; i++) { 504 if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { 505 adaptor = &(pScreenPriv->adaptors[i]); 506 break; 507 } 508 } 509 510 if(!adaptor) return BadMatch; 511 512 for(i = 0; i < adaptor->num_surfaces; i++) { 513 if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { 514 surface = adaptor->surfaces[i]; 515 break; 516 } 517 } 518 519 if(!surface) return BadMatch; 520 521 rep.type = X_Reply; 522 rep.sequenceNumber = client->sequence; 523 rep.num = 0; 524 if(surface->compatible_subpictures) 525 rep.num = surface->compatible_subpictures->num_xvimages; 526 527 rep.length = rep.num * sizeof(xvImageFormatInfo) >> 2; 528 529 WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), (char*)&rep); 530 531 for(i = 0; i < rep.num; i++) { 532 pImage = NULL; 533 for(j = 0; j < adaptor->num_subpictures; j++) { 534 if(surface->compatible_subpictures->xvimage_ids[i] == 535 adaptor->subpictures[j]->id) 536 { 537 pImage = adaptor->subpictures[j]; 538 break; 539 } 540 } 541 if(!pImage) return BadImplementation; 542 543 info.id = pImage->id; 544 info.type = pImage->type; 545 info.byte_order = pImage->byte_order; 546 memcpy(&info.guid, pImage->guid, 16); 547 info.bpp = pImage->bits_per_pixel; 548 info.num_planes = pImage->num_planes; 549 info.depth = pImage->depth; 550 info.red_mask = pImage->red_mask; 551 info.green_mask = pImage->green_mask; 552 info.blue_mask = pImage->blue_mask; 553 info.format = pImage->format; 554 info.y_sample_bits = pImage->y_sample_bits; 555 info.u_sample_bits = pImage->u_sample_bits; 556 info.v_sample_bits = pImage->v_sample_bits; 557 info.horz_y_period = pImage->horz_y_period; 558 info.horz_u_period = pImage->horz_u_period; 559 info.horz_v_period = pImage->horz_v_period; 560 info.vert_y_period = pImage->vert_y_period; 561 info.vert_u_period = pImage->vert_u_period; 562 info.vert_v_period = pImage->vert_v_period; 563 memcpy(&info.comp_order, pImage->component_order, 32); 564 info.scanline_order = pImage->scanline_order; 565 WriteToClient(client, sizeof(xvImageFormatInfo), (char*)&info); 566 } 567 568 return Success; 569} 570 571static int 572ProcXvMCGetDRInfo(ClientPtr client) 573{ 574 xvmcGetDRInfoReply rep; 575 XvPortPtr pPort; 576 ScreenPtr pScreen; 577 XvMCScreenPtr pScreenPriv; 578 579#ifdef HAS_XVMCSHM 580 volatile CARD32 *patternP; 581#endif 582 583 REQUEST(xvmcGetDRInfoReq); 584 REQUEST_SIZE_MATCH(xvmcGetDRInfoReq); 585 586 587 if(!(pPort = LOOKUP_PORT(stuff->port, client))) { 588 client->errorValue = stuff->port; 589 return _XvBadPort; 590 } 591 592 pScreen = pPort->pAdaptor->pScreen; 593 pScreenPriv = XVMC_GET_PRIVATE(pScreen); 594 595 rep.type = X_Reply; 596 rep.sequenceNumber = client->sequence; 597 rep.major = pScreenPriv->major; 598 rep.minor = pScreenPriv->minor; 599 rep.patchLevel = pScreenPriv->patchLevel; 600 rep.nameLen = (strlen(pScreenPriv->clientDriverName) + 4) >> 2; 601 rep.busIDLen = (strlen(pScreenPriv->busID) + 4) >> 2; 602 603 rep.length = rep.nameLen + rep.busIDLen; 604 rep.nameLen <<=2; 605 rep.busIDLen <<=2; 606 607 /* 608 * Read back to the client what she has put in the shared memory 609 * segment she prepared for us. 610 */ 611 612 rep.isLocal = 1; 613#ifdef HAS_XVMCSHM 614 patternP = (CARD32 *)shmat( stuff->shmKey, NULL, SHM_RDONLY ); 615 if ( -1 != (long) patternP) { 616 register volatile CARD32 *patternC = patternP; 617 register int i; 618 CARD32 magic = stuff->magic; 619 620 rep.isLocal = 1; 621 i = 1024 / sizeof(CARD32); 622 623 while ( i-- ) { 624 if (*patternC++ != magic) { 625 rep.isLocal = 0; 626 break; 627 } 628 magic = ~magic; 629 } 630 shmdt( (char *)patternP ); 631 } 632#endif /* HAS_XVMCSHM */ 633 634 WriteToClient(client, sizeof(xvmcGetDRInfoReply), 635 (char*)&rep); 636 if (rep.length) { 637 WriteToClient(client, rep.nameLen, 638 pScreenPriv->clientDriverName); 639 WriteToClient(client, rep.busIDLen, 640 pScreenPriv->busID); 641 } 642 return Success; 643} 644 645 646int (*ProcXvMCVector[xvmcNumRequest])(ClientPtr) = { 647 ProcXvMCQueryVersion, 648 ProcXvMCListSurfaceTypes, 649 ProcXvMCCreateContext, 650 ProcXvMCDestroyContext, 651 ProcXvMCCreateSurface, 652 ProcXvMCDestroySurface, 653 ProcXvMCCreateSubpicture, 654 ProcXvMCDestroySubpicture, 655 ProcXvMCListSubpictureTypes, 656 ProcXvMCGetDRInfo 657}; 658 659static int 660ProcXvMCDispatch (ClientPtr client) 661{ 662 REQUEST(xReq); 663 664 if(stuff->data < xvmcNumRequest) 665 return (*ProcXvMCVector[stuff->data])(client); 666 else 667 return BadRequest; 668} 669 670static int 671SProcXvMCDispatch (ClientPtr client) 672{ 673 /* We only support local */ 674 return BadImplementation; 675} 676 677void 678XvMCExtensionInit(void) 679{ 680 ExtensionEntry *extEntry; 681 682 if(XvMCScreenIndex < 0) /* nobody supports it */ 683 return; 684 685 if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes))) 686 return; 687 688 if(!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes))) 689 return; 690 691 if(!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes))) 692 return; 693 694 extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors, 695 ProcXvMCDispatch, SProcXvMCDispatch, 696 XvMCResetProc, StandardMinorOpcode); 697 698 if(!extEntry) return; 699 700 XvMCReqCode = extEntry->base; 701 XvMCEventBase = extEntry->eventBase; 702 XvMCErrorBase = extEntry->errorBase; 703} 704 705static Bool 706XvMCCloseScreen (int i, ScreenPtr pScreen) 707{ 708 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); 709 710 pScreen->CloseScreen = pScreenPriv->CloseScreen; 711 712 xfree(pScreenPriv); 713 714 return (*pScreen->CloseScreen)(i, pScreen); 715} 716 717 718int 719XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt) 720{ 721 XvMCScreenPtr pScreenPriv; 722 723 if(XvMCGeneration != serverGeneration) { 724 if((XvMCScreenIndex = AllocateScreenPrivateIndex()) < 0) 725 return BadAlloc; 726 727 XvMCGeneration = serverGeneration; 728 } 729 730 if(!(pScreenPriv = (XvMCScreenPtr)xalloc(sizeof(XvMCScreenRec)))) 731 return BadAlloc; 732 733 pScreen->devPrivates[XvMCScreenIndex].ptr = (pointer)pScreenPriv; 734 735 pScreenPriv->CloseScreen = pScreen->CloseScreen; 736 pScreen->CloseScreen = XvMCCloseScreen; 737 738 pScreenPriv->num_adaptors = num; 739 pScreenPriv->adaptors = pAdapt; 740 pScreenPriv->clientDriverName[0] = 0; 741 pScreenPriv->busID[0] = 0; 742 pScreenPriv->major = 0; 743 pScreenPriv->minor = 0; 744 pScreenPriv->patchLevel = 0; 745 746 return Success; 747} 748 749XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id) 750{ 751 XvImagePtr pImage = NULL; 752 ScreenPtr pScreen = pPort->pAdaptor->pScreen; 753 XvMCScreenPtr pScreenPriv; 754 XvMCAdaptorPtr adaptor = NULL; 755 int i; 756 757 if(XvMCScreenIndex < 0) return NULL; 758 759 if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) 760 return NULL; 761 762 for(i = 0; i < pScreenPriv->num_adaptors; i++) { 763 if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { 764 adaptor = &(pScreenPriv->adaptors[i]); 765 break; 766 } 767 } 768 769 if(!adaptor) return NULL; 770 771 for(i = 0; i < adaptor->num_subpictures; i++) { 772 if(adaptor->subpictures[i]->id == id) { 773 pImage = adaptor->subpictures[i]; 774 break; 775 } 776 } 777 778 return pImage; 779} 780 781int 782xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name, 783 char *busID, int major, int minor, 784 int patchLevel) 785{ 786 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); 787 strncpy(pScreenPriv->clientDriverName, name, 788 DR_CLIENT_DRIVER_NAME_SIZE); 789 strncpy(pScreenPriv->busID, busID, DR_BUSID_SIZE); 790 pScreenPriv->major = major; 791 pScreenPriv->minor = minor; 792 pScreenPriv->patchLevel = patchLevel; 793 pScreenPriv->clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE-1] = 0; 794 pScreenPriv->busID[DR_BUSID_SIZE-1] = 0; 795 return Success; 796} 797 798