Add patch that contain Mali fixes.
[deb_xorg-server.git] / Xext / xvmc.c
CommitLineData
a09e091a
JB
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(pointer 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(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
95static int
96XvMCDestroySubpictureRes(pointer 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((pointer) 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
257 rep = (xvmcCreateContextReply) {
258 .type = X_Reply,
259 .sequenceNumber = client->sequence,
260 .length = dwords,
261 .width_actual = pContext->width,
262 .height_actual = pContext->height,
263 .flags_return = pContext->flags
264 };
265
266 WriteToClient(client, sizeof(xvmcCreateContextReply), &rep);
267 if (dwords)
268 WriteToClient(client, dwords << 2, data);
269 AddResource(pContext->context_id, XvMCRTContext, pContext);
270
271 free(data);
272
273 return Success;
274}
275
276static int
277ProcXvMCDestroyContext(ClientPtr client)
278{
279 pointer val;
280 int rc;
281
282 REQUEST(xvmcDestroyContextReq);
283 REQUEST_SIZE_MATCH(xvmcDestroyContextReq);
284
285 rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext,
286 client, DixDestroyAccess);
287 if (rc != Success)
288 return rc;
289
290 FreeResource(stuff->context_id, RT_NONE);
291
292 return Success;
293}
294
295static int
296ProcXvMCCreateSurface(ClientPtr client)
297{
298 CARD32 *data = NULL;
299 int dwords = 0;
300 int result;
301 XvMCContextPtr pContext;
302 XvMCSurfacePtr pSurface;
303 XvMCScreenPtr pScreenPriv;
304 xvmcCreateSurfaceReply rep;
305
306 REQUEST(xvmcCreateSurfaceReq);
307 REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
308
309 result = dixLookupResourceByType((pointer *) &pContext, stuff->context_id,
310 XvMCRTContext, client, DixUseAccess);
311 if (result != Success)
312 return result;
313
314 pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
315
316 if (!(pSurface = malloc(sizeof(XvMCSurfaceRec))))
317 return BadAlloc;
318
319 pSurface->surface_id = stuff->surface_id;
320 pSurface->surface_type_id = pContext->surface_type_id;
321 pSurface->context = pContext;
322
323 result =
324 (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface) (pSurface,
325 &dwords,
326 &data);
327
328 if (result != Success) {
329 free(pSurface);
330 return result;
331 }
332 rep = (xvmcCreateSurfaceReply) {
333 .type = X_Reply,
334 .sequenceNumber = client->sequence,
335 .length = dwords
336 };
337
338 WriteToClient(client, sizeof(xvmcCreateSurfaceReply), &rep);
339 if (dwords)
340 WriteToClient(client, dwords << 2, data);
341 AddResource(pSurface->surface_id, XvMCRTSurface, pSurface);
342
343 free(data);
344
345 pContext->refcnt++;
346
347 return Success;
348}
349
350static int
351ProcXvMCDestroySurface(ClientPtr client)
352{
353 pointer val;
354 int rc;
355
356 REQUEST(xvmcDestroySurfaceReq);
357 REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq);
358
359 rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface,
360 client, DixDestroyAccess);
361 if (rc != Success)
362 return rc;
363
364 FreeResource(stuff->surface_id, RT_NONE);
365
366 return Success;
367}
368
369static int
370ProcXvMCCreateSubpicture(ClientPtr client)
371{
372 Bool image_supported = FALSE;
373 CARD32 *data = NULL;
374 int i, result, dwords = 0;
375 XvMCContextPtr pContext;
376 XvMCSubpicturePtr pSubpicture;
377 XvMCScreenPtr pScreenPriv;
378 xvmcCreateSubpictureReply rep;
379 XvMCAdaptorPtr adaptor;
380 XvMCSurfaceInfoPtr surface = NULL;
381
382 REQUEST(xvmcCreateSubpictureReq);
383 REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
384
385 result = dixLookupResourceByType((pointer *) &pContext, stuff->context_id,
386 XvMCRTContext, client, DixUseAccess);
387 if (result != Success)
388 return result;
389
390 pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
391
392 adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]);
393
394 /* find which surface this context supports */
395 for (i = 0; i < adaptor->num_surfaces; i++) {
396 if (adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id) {
397 surface = adaptor->surfaces[i];
398 break;
399 }
400 }
401
402 if (!surface)
403 return BadMatch;
404
405 /* make sure this surface supports that xvimage format */
406 if (!surface->compatible_subpictures)
407 return BadMatch;
408
409 for (i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
410 if (surface->compatible_subpictures->xvimage_ids[i] ==
411 stuff->xvimage_id) {
412 image_supported = TRUE;
413 break;
414 }
415 }
416
417 if (!image_supported)
418 return BadMatch;
419
420 /* make sure the size is OK */
421 if ((stuff->width > surface->subpicture_max_width) ||
422 (stuff->height > surface->subpicture_max_height))
423 return BadValue;
424
425 if (!(pSubpicture = malloc(sizeof(XvMCSubpictureRec))))
426 return BadAlloc;
427
428 pSubpicture->subpicture_id = stuff->subpicture_id;
429 pSubpicture->xvimage_id = stuff->xvimage_id;
430 pSubpicture->width = stuff->width;
431 pSubpicture->height = stuff->height;
432 pSubpicture->num_palette_entries = 0; /* overwritten by DDX */
433 pSubpicture->entry_bytes = 0; /* overwritten by DDX */
434 pSubpicture->component_order[0] = 0; /* overwritten by DDX */
435 pSubpicture->component_order[1] = 0;
436 pSubpicture->component_order[2] = 0;
437 pSubpicture->component_order[3] = 0;
438 pSubpicture->context = pContext;
439
440 result =
441 (*pScreenPriv->adaptors[pContext->adapt_num].
442 CreateSubpicture) (pSubpicture, &dwords, &data);
443
444 if (result != Success) {
445 free(pSubpicture);
446 return result;
447 }
448 rep = (xvmcCreateSubpictureReply) {
449 .type = X_Reply,
450 .sequenceNumber = client->sequence,
451 .length = dwords,
452 .width_actual = pSubpicture->width,
453 .height_actual = pSubpicture->height,
454 .num_palette_entries = pSubpicture->num_palette_entries,
455 .entry_bytes = pSubpicture->entry_bytes,
456 .component_order[0] = pSubpicture->component_order[0],
457 .component_order[1] = pSubpicture->component_order[1],
458 .component_order[2] = pSubpicture->component_order[2],
459 .component_order[3] = pSubpicture->component_order[3]
460 };
461
462 WriteToClient(client, sizeof(xvmcCreateSubpictureReply), &rep);
463 if (dwords)
464 WriteToClient(client, dwords << 2, data);
465 AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture);
466
467 free(data);
468
469 pContext->refcnt++;
470
471 return Success;
472}
473
474static int
475ProcXvMCDestroySubpicture(ClientPtr client)
476{
477 pointer val;
478 int rc;
479
480 REQUEST(xvmcDestroySubpictureReq);
481 REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq);
482
483 rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture,
484 client, DixDestroyAccess);
485 if (rc != Success)
486 return rc;
487
488 FreeResource(stuff->subpicture_id, RT_NONE);
489
490 return Success;
491}
492
493static int
494ProcXvMCListSubpictureTypes(ClientPtr client)
495{
496 XvPortPtr pPort;
497 xvmcListSubpictureTypesReply rep;
498 XvMCScreenPtr pScreenPriv;
499 ScreenPtr pScreen;
500 XvMCAdaptorPtr adaptor = NULL;
501 XvMCSurfaceInfoPtr surface = NULL;
502 xvImageFormatInfo info;
503 XvImagePtr pImage;
504 int i, j;
505
506 REQUEST(xvmcListSubpictureTypesReq);
507 REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq);
508
509 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
510
511 pScreen = pPort->pAdaptor->pScreen;
512
513 if (!dixPrivateKeyRegistered(XvMCScreenKey))
514 return BadMatch; /* No XvMC adaptors */
515
516 if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
517 return BadMatch; /* None this screen */
518
519 for (i = 0; i < pScreenPriv->num_adaptors; i++) {
520 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
521 adaptor = &(pScreenPriv->adaptors[i]);
522 break;
523 }
524 }
525
526 if (!adaptor)
527 return BadMatch;
528
529 for (i = 0; i < adaptor->num_surfaces; i++) {
530 if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
531 surface = adaptor->surfaces[i];
532 break;
533 }
534 }
535
536 if (!surface)
537 return BadMatch;
538
539 rep = (xvmcListSubpictureTypesReply) {
540 .type = X_Reply,
541 .sequenceNumber = client->sequence,
542 .num = 0
543 };
544 if (surface->compatible_subpictures)
545 rep.num = surface->compatible_subpictures->num_xvimages;
546
547 rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo));
548
549 WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), &rep);
550
551 for (i = 0; i < rep.num; i++) {
552 pImage = NULL;
553 for (j = 0; j < adaptor->num_subpictures; j++) {
554 if (surface->compatible_subpictures->xvimage_ids[i] ==
555 adaptor->subpictures[j]->id) {
556 pImage = adaptor->subpictures[j];
557 break;
558 }
559 }
560 if (!pImage)
561 return BadImplementation;
562
563 info.id = pImage->id;
564 info.type = pImage->type;
565 info.byte_order = pImage->byte_order;
566 memcpy(&info.guid, pImage->guid, 16);
567 info.bpp = pImage->bits_per_pixel;
568 info.num_planes = pImage->num_planes;
569 info.depth = pImage->depth;
570 info.red_mask = pImage->red_mask;
571 info.green_mask = pImage->green_mask;
572 info.blue_mask = pImage->blue_mask;
573 info.format = pImage->format;
574 info.y_sample_bits = pImage->y_sample_bits;
575 info.u_sample_bits = pImage->u_sample_bits;
576 info.v_sample_bits = pImage->v_sample_bits;
577 info.horz_y_period = pImage->horz_y_period;
578 info.horz_u_period = pImage->horz_u_period;
579 info.horz_v_period = pImage->horz_v_period;
580 info.vert_y_period = pImage->vert_y_period;
581 info.vert_u_period = pImage->vert_u_period;
582 info.vert_v_period = pImage->vert_v_period;
583 memcpy(&info.comp_order, pImage->component_order, 32);
584 info.scanline_order = pImage->scanline_order;
585 WriteToClient(client, sizeof(xvImageFormatInfo), &info);
586 }
587
588 return Success;
589}
590
591static int
592ProcXvMCGetDRInfo(ClientPtr client)
593{
594 xvmcGetDRInfoReply rep;
595 XvPortPtr pPort;
596 ScreenPtr pScreen;
597 XvMCScreenPtr pScreenPriv;
598
599#ifdef HAS_XVMCSHM
600 volatile CARD32 *patternP;
601#endif
602
603 REQUEST(xvmcGetDRInfoReq);
604 REQUEST_SIZE_MATCH(xvmcGetDRInfoReq);
605
606 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
607
608 pScreen = pPort->pAdaptor->pScreen;
609 pScreenPriv = XVMC_GET_PRIVATE(pScreen);
610
611 rep = (xvmcGetDRInfoReply) {
612 .type = X_Reply,
613 .sequenceNumber = client->sequence,
614 .major = pScreenPriv->major,
615 .minor = pScreenPriv->minor,
616 .patchLevel = pScreenPriv->patchLevel,
617 .nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1),
618 .busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1),
619 .isLocal = 1
620 };
621
622 rep.length = rep.nameLen + rep.busIDLen;
623 rep.nameLen <<= 2;
624 rep.busIDLen <<= 2;
625
626 /*
627 * Read back to the client what she has put in the shared memory
628 * segment she prepared for us.
629 */
630
631#ifdef HAS_XVMCSHM
632 patternP = (CARD32 *) shmat(stuff->shmKey, NULL, SHM_RDONLY);
633 if (-1 != (long) patternP) {
634 volatile CARD32 *patternC = patternP;
635 int i;
636 CARD32 magic = stuff->magic;
637
638 rep.isLocal = 1;
639 i = 1024 / sizeof(CARD32);
640
641 while (i--) {
642 if (*patternC++ != magic) {
643 rep.isLocal = 0;
644 break;
645 }
646 magic = ~magic;
647 }
648 shmdt((char *) patternP);
649 }
650#endif /* HAS_XVMCSHM */
651
652 WriteToClient(client, sizeof(xvmcGetDRInfoReply), &rep);
653 if (rep.length) {
654 WriteToClient(client, rep.nameLen, pScreenPriv->clientDriverName);
655 WriteToClient(client, rep.busIDLen, pScreenPriv->busID);
656 }
657 return Success;
658}
659
660int (*ProcXvMCVector[xvmcNumRequest]) (ClientPtr) = {
661ProcXvMCQueryVersion,
662 ProcXvMCListSurfaceTypes,
663 ProcXvMCCreateContext,
664 ProcXvMCDestroyContext,
665 ProcXvMCCreateSurface,
666 ProcXvMCDestroySurface,
667 ProcXvMCCreateSubpicture,
668 ProcXvMCDestroySubpicture,
669 ProcXvMCListSubpictureTypes, ProcXvMCGetDRInfo};
670
671static int
672ProcXvMCDispatch(ClientPtr client)
673{
674 REQUEST(xReq);
675
676 if (stuff->data < xvmcNumRequest)
677 return (*ProcXvMCVector[stuff->data]) (client);
678 else
679 return BadRequest;
680}
681
682static int
683SProcXvMCDispatch(ClientPtr client)
684{
685 /* We only support local */
686 return BadImplementation;
687}
688
689void
690XvMCExtensionInit(void)
691{
692 ExtensionEntry *extEntry;
693
694 if (!dixPrivateKeyRegistered(XvMCScreenKey))
695 return;
696
697 if (!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes,
698 "XvMCRTContext")))
699 return;
700
701 if (!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes,
702 "XvMCRTSurface")))
703 return;
704
705 if (!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes,
706 "XvMCRTSubpicture")))
707 return;
708
709 extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors,
710 ProcXvMCDispatch, SProcXvMCDispatch,
711 NULL, StandardMinorOpcode);
712
713 if (!extEntry)
714 return;
715
716 XvMCReqCode = extEntry->base;
717 XvMCEventBase = extEntry->eventBase;
718 SetResourceTypeErrorValue(XvMCRTContext,
719 extEntry->errorBase + XvMCBadContext);
720 SetResourceTypeErrorValue(XvMCRTSurface,
721 extEntry->errorBase + XvMCBadSurface);
722 SetResourceTypeErrorValue(XvMCRTSubpicture,
723 extEntry->errorBase + XvMCBadSubpicture);
724}
725
726static Bool
727XvMCCloseScreen(ScreenPtr pScreen)
728{
729 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
730
731 pScreen->CloseScreen = pScreenPriv->CloseScreen;
732
733 free(pScreenPriv);
734
735 return (*pScreen->CloseScreen) (pScreen);
736}
737
738int
739XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt)
740{
741 XvMCScreenPtr pScreenPriv;
742
743 if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0))
744 return BadAlloc;
745
746 if (!(pScreenPriv = malloc(sizeof(XvMCScreenRec))))
747 return BadAlloc;
748
749 dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv);
750
751 pScreenPriv->CloseScreen = pScreen->CloseScreen;
752 pScreen->CloseScreen = XvMCCloseScreen;
753
754 pScreenPriv->num_adaptors = num;
755 pScreenPriv->adaptors = pAdapt;
756 pScreenPriv->clientDriverName[0] = 0;
757 pScreenPriv->busID[0] = 0;
758 pScreenPriv->major = 0;
759 pScreenPriv->minor = 0;
760 pScreenPriv->patchLevel = 0;
761
762 XvMCInUse = TRUE;
763
764 return Success;
765}
766
767XvImagePtr
768XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
769{
770 XvImagePtr pImage = NULL;
771 ScreenPtr pScreen = pPort->pAdaptor->pScreen;
772 XvMCScreenPtr pScreenPriv;
773 XvMCAdaptorPtr adaptor = NULL;
774 int i;
775
776 if (!dixPrivateKeyRegistered(XvMCScreenKey))
777 return NULL;
778
779 if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
780 return NULL;
781
782 for (i = 0; i < pScreenPriv->num_adaptors; i++) {
783 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
784 adaptor = &(pScreenPriv->adaptors[i]);
785 break;
786 }
787 }
788
789 if (!adaptor)
790 return NULL;
791
792 for (i = 0; i < adaptor->num_subpictures; i++) {
793 if (adaptor->subpictures[i]->id == id) {
794 pImage = adaptor->subpictures[i];
795 break;
796 }
797 }
798
799 return pImage;
800}
801
802int
803xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name,
804 char *busID, int major, int minor, int patchLevel)
805{
806 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
807
808 strlcpy(pScreenPriv->clientDriverName, name, DR_CLIENT_DRIVER_NAME_SIZE);
809 strlcpy(pScreenPriv->busID, busID, DR_BUSID_SIZE);
810 pScreenPriv->major = major;
811 pScreenPriv->minor = minor;
812 pScreenPriv->patchLevel = patchLevel;
813 return Success;
814}