No longer leak FDs on VT switch.
[xserver.git] / Xext / xvmc.c
blob282c304d5dc83f83c97ef960dcc202eabda349fc
2 #include <dix-config.h>
4 #include <string.h>
5 #include <X11/X.h>
6 #include <X11/Xproto.h>
8 #include "Xext/xvdix_priv.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_priv.h"
17 #include "servermd.h"
18 #include <X11/Xfuncproto.h>
19 #include <X11/extensions/XvMC.h>
20 #include <X11/extensions/Xvproto.h>
21 #include <X11/extensions/XvMCproto.h>
22 #include "xvmcext.h"
24 #ifdef HAS_XVMCSHM
25 #include <sys/ipc.h>
26 #include <sys/types.h>
27 #include <sys/shm.h>
28 #endif /* HAS_XVMCSHM */
30 #define SERVER_XVMC_MAJOR_VERSION 1
31 #define SERVER_XVMC_MINOR_VERSION 1
33 #define DR_CLIENT_DRIVER_NAME_SIZE 48
34 #define DR_BUSID_SIZE 48
36 static DevPrivateKeyRec XvMCScreenKeyRec;
38 #define XvMCScreenKey (&XvMCScreenKeyRec)
39 static Bool XvMCInUse;
41 int XvMCReqCode;
42 int XvMCEventBase;
44 static RESTYPE XvMCRTContext;
45 static RESTYPE XvMCRTSurface;
46 static RESTYPE XvMCRTSubpicture;
48 typedef struct {
49 int num_adaptors;
50 XvMCAdaptorPtr adaptors;
51 CloseScreenProcPtr CloseScreen;
52 char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE];
53 char busID[DR_BUSID_SIZE];
54 int major;
55 int minor;
56 int patchLevel;
57 } XvMCScreenRec, *XvMCScreenPtr;
59 #define XVMC_GET_PRIVATE(pScreen) \
60 (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey))
62 static int
63 XvMCDestroyContextRes(void *data, XID id)
65 XvMCContextPtr pContext = (XvMCContextPtr) data;
67 pContext->refcnt--;
69 if (!pContext->refcnt) {
70 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
72 (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext) (pContext);
73 free(pContext);
76 return Success;
79 static int
80 XvMCDestroySurfaceRes(void *data, XID id)
82 XvMCSurfacePtr pSurface = (XvMCSurfacePtr) data;
83 XvMCContextPtr pContext = pSurface->context;
84 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
86 (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface) (pSurface);
87 free(pSurface);
89 XvMCDestroyContextRes((void *) pContext, pContext->context_id);
91 return Success;
94 static int
95 XvMCDestroySubpictureRes(void *data, XID id)
97 XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr) data;
98 XvMCContextPtr pContext = pSubpict->context;
99 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
101 (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture) (pSubpict);
102 free(pSubpict);
104 XvMCDestroyContextRes((void *) pContext, pContext->context_id);
106 return Success;
109 static int
110 ProcXvMCQueryVersion(ClientPtr client)
112 xvmcQueryVersionReply rep = {
113 .type = X_Reply,
114 .sequenceNumber = client->sequence,
115 .length = 0,
116 .major = SERVER_XVMC_MAJOR_VERSION,
117 .minor = SERVER_XVMC_MINOR_VERSION
120 /* REQUEST(xvmcQueryVersionReq); */
121 REQUEST_SIZE_MATCH(xvmcQueryVersionReq);
123 WriteToClient(client, sizeof(xvmcQueryVersionReply), &rep);
124 return Success;
127 static int
128 ProcXvMCListSurfaceTypes(ClientPtr client)
130 XvPortPtr pPort;
131 int i;
132 XvMCScreenPtr pScreenPriv;
133 xvmcListSurfaceTypesReply rep;
134 xvmcSurfaceInfo info;
135 XvMCAdaptorPtr adaptor = NULL;
136 XvMCSurfaceInfoPtr surface;
137 int num_surfaces;
139 REQUEST(xvmcListSurfaceTypesReq);
140 REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq);
142 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
144 if (XvMCInUse) { /* any adaptors at all */
145 ScreenPtr pScreen = pPort->pAdaptor->pScreen;
147 if ((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */
148 for (i = 0; i < pScreenPriv->num_adaptors; i++) {
149 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
150 adaptor = &(pScreenPriv->adaptors[i]);
151 break;
157 num_surfaces = (adaptor) ? adaptor->num_surfaces : 0;
158 rep = (xvmcListSurfaceTypesReply) {
159 .type = X_Reply,
160 .sequenceNumber = client->sequence,
161 .num = num_surfaces,
162 .length = bytes_to_int32(num_surfaces * sizeof(xvmcSurfaceInfo)),
165 WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), &rep);
167 for (i = 0; i < num_surfaces; i++) {
168 surface = adaptor->surfaces[i];
169 info.surface_type_id = surface->surface_type_id;
170 info.chroma_format = surface->chroma_format;
171 info.max_width = surface->max_width;
172 info.max_height = surface->max_height;
173 info.subpicture_max_width = surface->subpicture_max_width;
174 info.subpicture_max_height = surface->subpicture_max_height;
175 info.mc_type = surface->mc_type;
176 info.flags = surface->flags;
177 WriteToClient(client, sizeof(xvmcSurfaceInfo), &info);
180 return Success;
183 static int
184 ProcXvMCCreateContext(ClientPtr client)
186 XvPortPtr pPort;
187 CARD32 *data = NULL;
188 int dwords = 0;
189 int i, result, adapt_num = -1;
190 ScreenPtr pScreen;
191 XvMCContextPtr pContext;
192 XvMCScreenPtr pScreenPriv;
193 XvMCAdaptorPtr adaptor = NULL;
194 XvMCSurfaceInfoPtr surface = NULL;
195 xvmcCreateContextReply rep;
197 REQUEST(xvmcCreateContextReq);
198 REQUEST_SIZE_MATCH(xvmcCreateContextReq);
200 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
202 pScreen = pPort->pAdaptor->pScreen;
204 if (!XvMCInUse) /* no XvMC adaptors */
205 return BadMatch;
207 if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */
208 return BadMatch;
210 for (i = 0; i < pScreenPriv->num_adaptors; i++) {
211 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
212 adaptor = &(pScreenPriv->adaptors[i]);
213 adapt_num = i;
214 break;
218 if (adapt_num < 0) /* none this port */
219 return BadMatch;
221 for (i = 0; i < adaptor->num_surfaces; i++) {
222 if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
223 surface = adaptor->surfaces[i];
224 break;
228 /* adaptor doesn't support this suface_type_id */
229 if (!surface)
230 return BadMatch;
232 if ((stuff->width > surface->max_width) ||
233 (stuff->height > surface->max_height))
234 return BadValue;
236 if (!(pContext = malloc(sizeof(XvMCContextRec)))) {
237 return BadAlloc;
240 pContext->pScreen = pScreen;
241 pContext->adapt_num = adapt_num;
242 pContext->context_id = stuff->context_id;
243 pContext->surface_type_id = stuff->surface_type_id;
244 pContext->width = stuff->width;
245 pContext->height = stuff->height;
246 pContext->flags = stuff->flags;
247 pContext->refcnt = 1;
249 result = (*adaptor->CreateContext) (pPort, pContext, &dwords, &data);
251 if (result != Success) {
252 free(pContext);
253 return result;
255 if (!AddResource(pContext->context_id, XvMCRTContext, pContext)) {
256 free(data);
257 return BadAlloc;
260 rep = (xvmcCreateContextReply) {
261 .type = X_Reply,
262 .sequenceNumber = client->sequence,
263 .length = dwords,
264 .width_actual = pContext->width,
265 .height_actual = pContext->height,
266 .flags_return = pContext->flags
269 WriteToClient(client, sizeof(xvmcCreateContextReply), &rep);
270 if (dwords)
271 WriteToClient(client, dwords << 2, data);
273 free(data);
275 return Success;
278 static int
279 ProcXvMCDestroyContext(ClientPtr client)
281 void *val;
282 int rc;
284 REQUEST(xvmcDestroyContextReq);
285 REQUEST_SIZE_MATCH(xvmcDestroyContextReq);
287 rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext,
288 client, DixDestroyAccess);
289 if (rc != Success)
290 return rc;
292 FreeResource(stuff->context_id, X11_RESTYPE_NONE);
294 return Success;
297 static int
298 ProcXvMCCreateSurface(ClientPtr client)
300 CARD32 *data = NULL;
301 int dwords = 0;
302 int result;
303 XvMCContextPtr pContext;
304 XvMCSurfacePtr pSurface;
305 XvMCScreenPtr pScreenPriv;
306 xvmcCreateSurfaceReply rep;
308 REQUEST(xvmcCreateSurfaceReq);
309 REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
311 result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
312 XvMCRTContext, client, DixUseAccess);
313 if (result != Success)
314 return result;
316 pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
318 if (!(pSurface = malloc(sizeof(XvMCSurfaceRec))))
319 return BadAlloc;
321 pSurface->surface_id = stuff->surface_id;
322 pSurface->surface_type_id = pContext->surface_type_id;
323 pSurface->context = pContext;
325 result =
326 (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface) (pSurface,
327 &dwords,
328 &data);
330 if (result != Success) {
331 free(pSurface);
332 return result;
334 if (!AddResource(pSurface->surface_id, XvMCRTSurface, pSurface)) {
335 free(data);
336 return BadAlloc;
339 rep = (xvmcCreateSurfaceReply) {
340 .type = X_Reply,
341 .sequenceNumber = client->sequence,
342 .length = dwords
345 WriteToClient(client, sizeof(xvmcCreateSurfaceReply), &rep);
346 if (dwords)
347 WriteToClient(client, dwords << 2, data);
349 free(data);
351 pContext->refcnt++;
353 return Success;
356 static int
357 ProcXvMCDestroySurface(ClientPtr client)
359 void *val;
360 int rc;
362 REQUEST(xvmcDestroySurfaceReq);
363 REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq);
365 rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface,
366 client, DixDestroyAccess);
367 if (rc != Success)
368 return rc;
370 FreeResource(stuff->surface_id, X11_RESTYPE_NONE);
372 return Success;
375 static int
376 ProcXvMCCreateSubpicture(ClientPtr client)
378 Bool image_supported = FALSE;
379 CARD32 *data = NULL;
380 int i, result, dwords = 0;
381 XvMCContextPtr pContext;
382 XvMCSubpicturePtr pSubpicture;
383 XvMCScreenPtr pScreenPriv;
384 xvmcCreateSubpictureReply rep;
385 XvMCAdaptorPtr adaptor;
386 XvMCSurfaceInfoPtr surface = NULL;
388 REQUEST(xvmcCreateSubpictureReq);
389 REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
391 result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
392 XvMCRTContext, client, DixUseAccess);
393 if (result != Success)
394 return result;
396 pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
398 adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]);
400 /* find which surface this context supports */
401 for (i = 0; i < adaptor->num_surfaces; i++) {
402 if (adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id) {
403 surface = adaptor->surfaces[i];
404 break;
408 if (!surface)
409 return BadMatch;
411 /* make sure this surface supports that xvimage format */
412 if (!surface->compatible_subpictures)
413 return BadMatch;
415 for (i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
416 if (surface->compatible_subpictures->xvimage_ids[i] ==
417 stuff->xvimage_id) {
418 image_supported = TRUE;
419 break;
423 if (!image_supported)
424 return BadMatch;
426 /* make sure the size is OK */
427 if ((stuff->width > surface->subpicture_max_width) ||
428 (stuff->height > surface->subpicture_max_height))
429 return BadValue;
431 if (!(pSubpicture = malloc(sizeof(XvMCSubpictureRec))))
432 return BadAlloc;
434 pSubpicture->subpicture_id = stuff->subpicture_id;
435 pSubpicture->xvimage_id = stuff->xvimage_id;
436 pSubpicture->width = stuff->width;
437 pSubpicture->height = stuff->height;
438 pSubpicture->num_palette_entries = 0; /* overwritten by DDX */
439 pSubpicture->entry_bytes = 0; /* overwritten by DDX */
440 pSubpicture->component_order[0] = 0; /* overwritten by DDX */
441 pSubpicture->component_order[1] = 0;
442 pSubpicture->component_order[2] = 0;
443 pSubpicture->component_order[3] = 0;
444 pSubpicture->context = pContext;
446 result =
447 (*pScreenPriv->adaptors[pContext->adapt_num].
448 CreateSubpicture) (pSubpicture, &dwords, &data);
450 if (result != Success) {
451 free(pSubpicture);
452 return result;
454 if (!AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture)) {
455 free(data);
456 return BadAlloc;
459 rep = (xvmcCreateSubpictureReply) {
460 .type = X_Reply,
461 .sequenceNumber = client->sequence,
462 .length = dwords,
463 .width_actual = pSubpicture->width,
464 .height_actual = pSubpicture->height,
465 .num_palette_entries = pSubpicture->num_palette_entries,
466 .entry_bytes = pSubpicture->entry_bytes,
467 .component_order[0] = pSubpicture->component_order[0],
468 .component_order[1] = pSubpicture->component_order[1],
469 .component_order[2] = pSubpicture->component_order[2],
470 .component_order[3] = pSubpicture->component_order[3]
473 WriteToClient(client, sizeof(xvmcCreateSubpictureReply), &rep);
474 if (dwords)
475 WriteToClient(client, dwords << 2, data);
477 free(data);
479 pContext->refcnt++;
481 return Success;
484 static int
485 ProcXvMCDestroySubpicture(ClientPtr client)
487 void *val;
488 int rc;
490 REQUEST(xvmcDestroySubpictureReq);
491 REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq);
493 rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture,
494 client, DixDestroyAccess);
495 if (rc != Success)
496 return rc;
498 FreeResource(stuff->subpicture_id, X11_RESTYPE_NONE);
500 return Success;
503 static int
504 ProcXvMCListSubpictureTypes(ClientPtr client)
506 XvPortPtr pPort;
507 xvmcListSubpictureTypesReply rep;
508 XvMCScreenPtr pScreenPriv;
509 ScreenPtr pScreen;
510 XvMCAdaptorPtr adaptor = NULL;
511 XvMCSurfaceInfoPtr surface = NULL;
512 xvImageFormatInfo info;
513 XvImagePtr pImage;
514 int i, j;
516 REQUEST(xvmcListSubpictureTypesReq);
517 REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq);
519 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
521 pScreen = pPort->pAdaptor->pScreen;
523 if (!dixPrivateKeyRegistered(XvMCScreenKey))
524 return BadMatch; /* No XvMC adaptors */
526 if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
527 return BadMatch; /* None this screen */
529 for (i = 0; i < pScreenPriv->num_adaptors; i++) {
530 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
531 adaptor = &(pScreenPriv->adaptors[i]);
532 break;
536 if (!adaptor)
537 return BadMatch;
539 for (i = 0; i < adaptor->num_surfaces; i++) {
540 if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
541 surface = adaptor->surfaces[i];
542 break;
546 if (!surface)
547 return BadMatch;
549 rep = (xvmcListSubpictureTypesReply) {
550 .type = X_Reply,
551 .sequenceNumber = client->sequence,
552 .num = 0
554 if (surface->compatible_subpictures)
555 rep.num = surface->compatible_subpictures->num_xvimages;
557 rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo));
559 WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), &rep);
561 for (i = 0; i < rep.num; i++) {
562 pImage = NULL;
563 for (j = 0; j < adaptor->num_subpictures; j++) {
564 if (surface->compatible_subpictures->xvimage_ids[i] ==
565 adaptor->subpictures[j]->id) {
566 pImage = adaptor->subpictures[j];
567 break;
570 if (!pImage)
571 return BadImplementation;
573 info.id = pImage->id;
574 info.type = pImage->type;
575 info.byte_order = pImage->byte_order;
576 memcpy(&info.guid, pImage->guid, 16);
577 info.bpp = pImage->bits_per_pixel;
578 info.num_planes = pImage->num_planes;
579 info.depth = pImage->depth;
580 info.red_mask = pImage->red_mask;
581 info.green_mask = pImage->green_mask;
582 info.blue_mask = pImage->blue_mask;
583 info.format = pImage->format;
584 info.y_sample_bits = pImage->y_sample_bits;
585 info.u_sample_bits = pImage->u_sample_bits;
586 info.v_sample_bits = pImage->v_sample_bits;
587 info.horz_y_period = pImage->horz_y_period;
588 info.horz_u_period = pImage->horz_u_period;
589 info.horz_v_period = pImage->horz_v_period;
590 info.vert_y_period = pImage->vert_y_period;
591 info.vert_u_period = pImage->vert_u_period;
592 info.vert_v_period = pImage->vert_v_period;
593 memcpy(&info.comp_order, pImage->component_order, 32);
594 info.scanline_order = pImage->scanline_order;
595 WriteToClient(client, sizeof(xvImageFormatInfo), &info);
598 return Success;
601 static int
602 ProcXvMCGetDRInfo(ClientPtr client)
604 xvmcGetDRInfoReply rep;
605 XvPortPtr pPort;
606 ScreenPtr pScreen;
607 XvMCScreenPtr pScreenPriv;
609 #ifdef HAS_XVMCSHM
610 volatile CARD32 *patternP;
611 #endif
613 REQUEST(xvmcGetDRInfoReq);
614 REQUEST_SIZE_MATCH(xvmcGetDRInfoReq);
616 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
618 pScreen = pPort->pAdaptor->pScreen;
619 pScreenPriv = XVMC_GET_PRIVATE(pScreen);
621 rep = (xvmcGetDRInfoReply) {
622 .type = X_Reply,
623 .sequenceNumber = client->sequence,
624 .major = pScreenPriv->major,
625 .minor = pScreenPriv->minor,
626 .patchLevel = pScreenPriv->patchLevel,
627 .nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1),
628 .busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1),
629 .isLocal = 1
632 rep.length = rep.nameLen + rep.busIDLen;
633 rep.nameLen <<= 2;
634 rep.busIDLen <<= 2;
637 * Read back to the client what she has put in the shared memory
638 * segment she prepared for us.
641 #ifdef HAS_XVMCSHM
642 patternP = (CARD32 *) shmat(stuff->shmKey, NULL, SHM_RDONLY);
643 if (-1 != (long) patternP) {
644 volatile CARD32 *patternC = patternP;
645 int i;
646 CARD32 magic = stuff->magic;
648 rep.isLocal = 1;
649 i = 1024 / sizeof(CARD32);
651 while (i--) {
652 if (*patternC++ != magic) {
653 rep.isLocal = 0;
654 break;
656 magic = ~magic;
658 shmdt((char *) patternP);
660 #endif /* HAS_XVMCSHM */
662 WriteToClient(client, sizeof(xvmcGetDRInfoReply), &rep);
663 if (rep.length) {
664 WriteToClient(client, rep.nameLen, pScreenPriv->clientDriverName);
665 WriteToClient(client, rep.busIDLen, pScreenPriv->busID);
667 return Success;
670 int (*ProcXvMCVector[xvmcNumRequest]) (ClientPtr) = {
671 ProcXvMCQueryVersion,
672 ProcXvMCListSurfaceTypes,
673 ProcXvMCCreateContext,
674 ProcXvMCDestroyContext,
675 ProcXvMCCreateSurface,
676 ProcXvMCDestroySurface,
677 ProcXvMCCreateSubpicture,
678 ProcXvMCDestroySubpicture,
679 ProcXvMCListSubpictureTypes, ProcXvMCGetDRInfo};
681 static int
682 ProcXvMCDispatch(ClientPtr client)
684 REQUEST(xReq);
686 if (stuff->data < xvmcNumRequest)
687 return (*ProcXvMCVector[stuff->data]) (client);
688 else
689 return BadRequest;
692 static int _X_COLD
693 SProcXvMCDispatch(ClientPtr client)
695 /* We only support local */
696 return BadImplementation;
699 void
700 XvMCExtensionInit(void)
702 ExtensionEntry *extEntry;
704 if (!dixPrivateKeyRegistered(XvMCScreenKey))
705 return;
707 if (!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes,
708 "XvMCRTContext")))
709 return;
711 if (!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes,
712 "XvMCRTSurface")))
713 return;
715 if (!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes,
716 "XvMCRTSubpicture")))
717 return;
719 extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors,
720 ProcXvMCDispatch, SProcXvMCDispatch,
721 NULL, StandardMinorOpcode);
723 if (!extEntry)
724 return;
726 XvMCReqCode = extEntry->base;
727 XvMCEventBase = extEntry->eventBase;
728 SetResourceTypeErrorValue(XvMCRTContext,
729 extEntry->errorBase + XvMCBadContext);
730 SetResourceTypeErrorValue(XvMCRTSurface,
731 extEntry->errorBase + XvMCBadSurface);
732 SetResourceTypeErrorValue(XvMCRTSubpicture,
733 extEntry->errorBase + XvMCBadSubpicture);
736 static Bool
737 XvMCCloseScreen(ScreenPtr pScreen)
739 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
741 pScreen->CloseScreen = pScreenPriv->CloseScreen;
743 free(pScreenPriv);
745 return (*pScreen->CloseScreen) (pScreen);
749 XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt)
751 XvMCScreenPtr pScreenPriv;
753 if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0))
754 return BadAlloc;
756 if (!(pScreenPriv = malloc(sizeof(XvMCScreenRec))))
757 return BadAlloc;
759 dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv);
761 pScreenPriv->CloseScreen = pScreen->CloseScreen;
762 pScreen->CloseScreen = XvMCCloseScreen;
764 pScreenPriv->num_adaptors = num;
765 pScreenPriv->adaptors = pAdapt;
766 pScreenPriv->clientDriverName[0] = 0;
767 pScreenPriv->busID[0] = 0;
768 pScreenPriv->major = 0;
769 pScreenPriv->minor = 0;
770 pScreenPriv->patchLevel = 0;
772 XvMCInUse = TRUE;
774 return Success;
777 XvImagePtr
778 XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
780 XvImagePtr pImage = NULL;
781 ScreenPtr pScreen = pPort->pAdaptor->pScreen;
782 XvMCScreenPtr pScreenPriv;
783 XvMCAdaptorPtr adaptor = NULL;
784 int i;
786 if (!dixPrivateKeyRegistered(XvMCScreenKey))
787 return NULL;
789 if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
790 return NULL;
792 for (i = 0; i < pScreenPriv->num_adaptors; i++) {
793 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
794 adaptor = &(pScreenPriv->adaptors[i]);
795 break;
799 if (!adaptor)
800 return NULL;
802 for (i = 0; i < adaptor->num_subpictures; i++) {
803 if (adaptor->subpictures[i]->id == id) {
804 pImage = adaptor->subpictures[i];
805 break;
809 return pImage;
813 xf86XvMCRegisterDRInfo(ScreenPtr pScreen, const char *name,
814 const char *busID, int major, int minor, int patchLevel)
816 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
818 strlcpy(pScreenPriv->clientDriverName, name, DR_CLIENT_DRIVER_NAME_SIZE);
819 strlcpy(pScreenPriv->busID, busID, DR_BUSID_SIZE);
820 pScreenPriv->major = major;
821 pScreenPriv->minor = minor;
822 pScreenPriv->patchLevel = patchLevel;
823 return Success;