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