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