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