File: | Xext/xvmc.c |
Location: | line 565, column 17 |
Description: | Access to field 'xvimage_ids' results in a dereference of a null pointer (loaded from field 'compatible_subpictures') |
1 | ||||
2 | #ifdef HAVE_DIX_CONFIG_H1 | |||
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_SIZE48 48 | |||
33 | #define DR_BUSID_SIZE48 48 | |||
34 | ||||
35 | static DevPrivateKeyRec XvMCScreenKeyRec; | |||
36 | ||||
37 | #define XvMCScreenKey(&XvMCScreenKeyRec) (&XvMCScreenKeyRec) | |||
38 | static Bool XvMCInUse; | |||
39 | ||||
40 | int XvMCReqCode; | |||
41 | int XvMCEventBase; | |||
42 | ||||
43 | static RESTYPE XvMCRTContext; | |||
44 | static RESTYPE XvMCRTSurface; | |||
45 | static RESTYPE XvMCRTSubpicture; | |||
46 | ||||
47 | int (*XvMCScreenInitProc)(ScreenPtr, int, XvMCAdaptorPtr) = NULL((void*)0); | |||
48 | ||||
49 | typedef struct { | |||
50 | int num_adaptors; | |||
51 | XvMCAdaptorPtr adaptors; | |||
52 | CloseScreenProcPtr CloseScreen; | |||
53 | char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE48]; | |||
54 | char busID[DR_BUSID_SIZE48]; | |||
55 | int major; | |||
56 | int minor; | |||
57 | int patchLevel; | |||
58 | } XvMCScreenRec, *XvMCScreenPtr; | |||
59 | ||||
60 | #define XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))) \ | |||
61 | (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey(&XvMCScreenKeyRec))) | |||
62 | ||||
63 | static int | |||
64 | XvMCDestroyContextRes(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)(XvMCScreenPtr)(dixLookupPrivate(&(pContext->pScreen)-> devPrivates, (&XvMCScreenKeyRec))); | |||
72 | ||||
73 | (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext) (pContext); | |||
74 | free(pContext); | |||
75 | } | |||
76 | ||||
77 | return Success0; | |||
78 | } | |||
79 | ||||
80 | static int | |||
81 | XvMCDestroySurfaceRes(void *data, XID id) | |||
82 | { | |||
83 | XvMCSurfacePtr pSurface = (XvMCSurfacePtr) data; | |||
84 | XvMCContextPtr pContext = pSurface->context; | |||
85 | XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pContext->pScreen)-> devPrivates, (&XvMCScreenKeyRec))); | |||
86 | ||||
87 | (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface) (pSurface); | |||
88 | free(pSurface); | |||
89 | ||||
90 | XvMCDestroyContextRes((void *) pContext, pContext->context_id); | |||
91 | ||||
92 | return Success0; | |||
93 | } | |||
94 | ||||
95 | static int | |||
96 | XvMCDestroySubpictureRes(void *data, XID id) | |||
97 | { | |||
98 | XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr) data; | |||
99 | XvMCContextPtr pContext = pSubpict->context; | |||
100 | XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pContext->pScreen)-> devPrivates, (&XvMCScreenKeyRec))); | |||
101 | ||||
102 | (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture) (pSubpict); | |||
103 | free(pSubpict); | |||
104 | ||||
105 | XvMCDestroyContextRes((void *) pContext, pContext->context_id); | |||
106 | ||||
107 | return Success0; | |||
108 | } | |||
109 | ||||
110 | static int | |||
111 | ProcXvMCQueryVersion(ClientPtr client) | |||
112 | { | |||
113 | xvmcQueryVersionReply rep = { | |||
114 | .type = X_Reply1, | |||
115 | .sequenceNumber = client->sequence, | |||
116 | .length = 0, | |||
117 | .major = SERVER_XVMC_MAJOR_VERSION1, | |||
118 | .minor = SERVER_XVMC_MINOR_VERSION1 | |||
119 | }; | |||
120 | ||||
121 | /* REQUEST(xvmcQueryVersionReq); */ | |||
122 | REQUEST_SIZE_MATCH(xvmcQueryVersionReq)if ((sizeof(xvmcQueryVersionReq) >> 2) != client->req_len ) return(16); | |||
123 | ||||
124 | WriteToClient(client, sizeof(xvmcQueryVersionReply), &rep); | |||
125 | return Success0; | |||
126 | } | |||
127 | ||||
128 | static int | |||
129 | ProcXvMCListSurfaceTypes(ClientPtr client) | |||
130 | { | |||
131 | XvPortPtr pPort; | |||
132 | int i; | |||
133 | XvMCScreenPtr pScreenPriv; | |||
134 | xvmcListSurfaceTypesReply rep; | |||
135 | xvmcSurfaceInfo info; | |||
136 | XvMCAdaptorPtr adaptor = NULL((void*)0); | |||
137 | XvMCSurfaceInfoPtr surface; | |||
138 | int num_surfaces; | |||
139 | ||||
140 | REQUEST(xvmcListSurfaceTypesReq)xvmcListSurfaceTypesReq *stuff = (xvmcListSurfaceTypesReq *)client ->requestBuffer; | |||
141 | REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq)if ((sizeof(xvmcListSurfaceTypesReq) >> 2) != client-> req_len) return(16); | |||
142 | ||||
143 | VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(pPort), stuff ->port, XvRTPort, client, (1<<0)); if (rc != 0) return rc; }; | |||
144 | ||||
145 | if (XvMCInUse) { /* any adaptors at all */ | |||
146 | ScreenPtr pScreen = pPort->pAdaptor->pScreen; | |||
147 | ||||
148 | if ((pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))))) { /* 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_Reply1, | |||
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 Success0; | |||
182 | } | |||
183 | ||||
184 | static int | |||
185 | ProcXvMCCreateContext(ClientPtr client) | |||
186 | { | |||
187 | XvPortPtr pPort; | |||
188 | CARD32 *data = NULL((void*)0); | |||
189 | int dwords = 0; | |||
190 | int i, result, adapt_num = -1; | |||
191 | ScreenPtr pScreen; | |||
192 | XvMCContextPtr pContext; | |||
193 | XvMCScreenPtr pScreenPriv; | |||
194 | XvMCAdaptorPtr adaptor = NULL((void*)0); | |||
195 | XvMCSurfaceInfoPtr surface = NULL((void*)0); | |||
196 | xvmcCreateContextReply rep; | |||
197 | ||||
198 | REQUEST(xvmcCreateContextReq)xvmcCreateContextReq *stuff = (xvmcCreateContextReq *)client-> requestBuffer; | |||
199 | REQUEST_SIZE_MATCH(xvmcCreateContextReq)if ((sizeof(xvmcCreateContextReq) >> 2) != client->req_len ) return(16); | |||
200 | ||||
201 | VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(pPort), stuff ->port, XvRTPort, client, (1<<0)); if (rc != 0) return rc; }; | |||
202 | ||||
203 | pScreen = pPort->pAdaptor->pScreen; | |||
204 | ||||
205 | if (!XvMCInUse) /* no XvMC adaptors */ | |||
206 | return BadMatch8; | |||
207 | ||||
208 | if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))))) /* none this screen */ | |||
209 | return BadMatch8; | |||
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 BadMatch8; | |||
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 BadMatch8; | |||
232 | ||||
233 | if ((stuff->width > surface->max_width) || | |||
234 | (stuff->height > surface->max_height)) | |||
235 | return BadValue2; | |||
236 | ||||
237 | if (!(pContext = malloc(sizeof(XvMCContextRec)))) { | |||
238 | return BadAlloc11; | |||
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 != Success0) { | |||
253 | free(pContext); | |||
254 | return result; | |||
255 | } | |||
256 | if (!AddResourceDarwin_X_AddResource(pContext->context_id, XvMCRTContext, pContext)) { | |||
257 | free(data); | |||
258 | return BadAlloc11; | |||
259 | } | |||
260 | ||||
261 | rep = (xvmcCreateContextReply) { | |||
262 | .type = X_Reply1, | |||
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 Success0; | |||
277 | } | |||
278 | ||||
279 | static int | |||
280 | ProcXvMCDestroyContext(ClientPtr client) | |||
281 | { | |||
282 | void *val; | |||
283 | int rc; | |||
284 | ||||
285 | REQUEST(xvmcDestroyContextReq)xvmcDestroyContextReq *stuff = (xvmcDestroyContextReq *)client ->requestBuffer; | |||
286 | REQUEST_SIZE_MATCH(xvmcDestroyContextReq)if ((sizeof(xvmcDestroyContextReq) >> 2) != client-> req_len) return(16); | |||
287 | ||||
288 | rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext, | |||
289 | client, DixDestroyAccess(1<<2)); | |||
290 | if (rc != Success0) | |||
291 | return rc; | |||
292 | ||||
293 | FreeResource(stuff->context_id, RT_NONE((RESTYPE)0)); | |||
294 | ||||
295 | return Success0; | |||
296 | } | |||
297 | ||||
298 | static int | |||
299 | ProcXvMCCreateSurface(ClientPtr client) | |||
300 | { | |||
301 | CARD32 *data = NULL((void*)0); | |||
302 | int dwords = 0; | |||
303 | int result; | |||
304 | XvMCContextPtr pContext; | |||
305 | XvMCSurfacePtr pSurface; | |||
306 | XvMCScreenPtr pScreenPriv; | |||
307 | xvmcCreateSurfaceReply rep; | |||
308 | ||||
309 | REQUEST(xvmcCreateSurfaceReq)xvmcCreateSurfaceReq *stuff = (xvmcCreateSurfaceReq *)client-> requestBuffer; | |||
310 | REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq)if ((sizeof(xvmcCreateSurfaceReq) >> 2) != client->req_len ) return(16); | |||
311 | ||||
312 | result = dixLookupResourceByType((void **) &pContext, stuff->context_id, | |||
313 | XvMCRTContext, client, DixUseAccess(1<<24)); | |||
314 | if (result != Success0) | |||
315 | return result; | |||
316 | ||||
317 | pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pContext->pScreen)-> devPrivates, (&XvMCScreenKeyRec))); | |||
318 | ||||
319 | if (!(pSurface = malloc(sizeof(XvMCSurfaceRec)))) | |||
320 | return BadAlloc11; | |||
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 != Success0) { | |||
332 | free(pSurface); | |||
333 | return result; | |||
334 | } | |||
335 | if (!AddResourceDarwin_X_AddResource(pSurface->surface_id, XvMCRTSurface, pSurface)) { | |||
336 | free(data); | |||
337 | return BadAlloc11; | |||
338 | } | |||
339 | ||||
340 | rep = (xvmcCreateSurfaceReply) { | |||
341 | .type = X_Reply1, | |||
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 Success0; | |||
355 | } | |||
356 | ||||
357 | static int | |||
358 | ProcXvMCDestroySurface(ClientPtr client) | |||
359 | { | |||
360 | void *val; | |||
361 | int rc; | |||
362 | ||||
363 | REQUEST(xvmcDestroySurfaceReq)xvmcDestroySurfaceReq *stuff = (xvmcDestroySurfaceReq *)client ->requestBuffer; | |||
364 | REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq)if ((sizeof(xvmcDestroySurfaceReq) >> 2) != client-> req_len) return(16); | |||
365 | ||||
366 | rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface, | |||
367 | client, DixDestroyAccess(1<<2)); | |||
368 | if (rc != Success0) | |||
369 | return rc; | |||
370 | ||||
371 | FreeResource(stuff->surface_id, RT_NONE((RESTYPE)0)); | |||
372 | ||||
373 | return Success0; | |||
374 | } | |||
375 | ||||
376 | static int | |||
377 | ProcXvMCCreateSubpicture(ClientPtr client) | |||
378 | { | |||
379 | Bool image_supported = FALSE0; | |||
380 | CARD32 *data = NULL((void*)0); | |||
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((void*)0); | |||
388 | ||||
389 | REQUEST(xvmcCreateSubpictureReq)xvmcCreateSubpictureReq *stuff = (xvmcCreateSubpictureReq *)client ->requestBuffer; | |||
390 | REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq)if ((sizeof(xvmcCreateSubpictureReq) >> 2) != client-> req_len) return(16); | |||
391 | ||||
392 | result = dixLookupResourceByType((void **) &pContext, stuff->context_id, | |||
393 | XvMCRTContext, client, DixUseAccess(1<<24)); | |||
394 | if (result != Success0) | |||
395 | return result; | |||
396 | ||||
397 | pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pContext->pScreen)-> devPrivates, (&XvMCScreenKeyRec))); | |||
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 BadMatch8; | |||
411 | ||||
412 | /* make sure this surface supports that xvimage format */ | |||
413 | if (!surface->compatible_subpictures) | |||
414 | return BadMatch8; | |||
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 = TRUE1; | |||
420 | break; | |||
421 | } | |||
422 | } | |||
423 | ||||
424 | if (!image_supported) | |||
425 | return BadMatch8; | |||
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 BadValue2; | |||
431 | ||||
432 | if (!(pSubpicture = malloc(sizeof(XvMCSubpictureRec)))) | |||
433 | return BadAlloc11; | |||
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 != Success0) { | |||
452 | free(pSubpicture); | |||
453 | return result; | |||
454 | } | |||
455 | if (!AddResourceDarwin_X_AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture)) { | |||
456 | free(data); | |||
457 | return BadAlloc11; | |||
458 | } | |||
459 | ||||
460 | rep = (xvmcCreateSubpictureReply) { | |||
461 | .type = X_Reply1, | |||
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 Success0; | |||
483 | } | |||
484 | ||||
485 | static int | |||
486 | ProcXvMCDestroySubpicture(ClientPtr client) | |||
487 | { | |||
488 | void *val; | |||
489 | int rc; | |||
490 | ||||
491 | REQUEST(xvmcDestroySubpictureReq)xvmcDestroySubpictureReq *stuff = (xvmcDestroySubpictureReq * )client->requestBuffer; | |||
492 | REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq)if ((sizeof(xvmcDestroySubpictureReq) >> 2) != client-> req_len) return(16); | |||
493 | ||||
494 | rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture, | |||
495 | client, DixDestroyAccess(1<<2)); | |||
496 | if (rc != Success0) | |||
497 | return rc; | |||
498 | ||||
499 | FreeResource(stuff->subpicture_id, RT_NONE((RESTYPE)0)); | |||
500 | ||||
501 | return Success0; | |||
502 | } | |||
503 | ||||
504 | static int | |||
505 | ProcXvMCListSubpictureTypes(ClientPtr client) | |||
506 | { | |||
507 | XvPortPtr pPort; | |||
508 | xvmcListSubpictureTypesReply rep; | |||
509 | XvMCScreenPtr pScreenPriv; | |||
510 | ScreenPtr pScreen; | |||
511 | XvMCAdaptorPtr adaptor = NULL((void*)0); | |||
512 | XvMCSurfaceInfoPtr surface = NULL((void*)0); | |||
513 | xvImageFormatInfo info; | |||
514 | XvImagePtr pImage; | |||
515 | int i, j; | |||
516 | ||||
517 | REQUEST(xvmcListSubpictureTypesReq)xvmcListSubpictureTypesReq *stuff = (xvmcListSubpictureTypesReq *)client->requestBuffer; | |||
518 | REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq)if ((sizeof(xvmcListSubpictureTypesReq) >> 2) != client ->req_len) return(16); | |||
519 | ||||
520 | VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(pPort), stuff ->port, XvRTPort, client, (1<<0)); if (rc != 0) return rc; }; | |||
521 | ||||
522 | pScreen = pPort->pAdaptor->pScreen; | |||
523 | ||||
524 | if (!dixPrivateKeyRegistered(XvMCScreenKey(&XvMCScreenKeyRec))) | |||
| ||||
525 | return BadMatch8; /* No XvMC adaptors */ | |||
526 | ||||
527 | if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))))) | |||
528 | return BadMatch8; /* 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 BadMatch8; | |||
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 BadMatch8; | |||
549 | ||||
550 | rep = (xvmcListSubpictureTypesReply) { | |||
551 | .type = X_Reply1, | |||
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((void*)0); | |||
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 BadImplementation17; | |||
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)__builtin___memcpy_chk (&info.guid, pImage->guid, 16, __builtin_object_size (&info.guid, 0)); | |||
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)__builtin___memcpy_chk (&info.comp_order, pImage->component_order , 32, __builtin_object_size (&info.comp_order, 0)); | |||
595 | info.scanline_order = pImage->scanline_order; | |||
596 | WriteToClient(client, sizeof(xvImageFormatInfo), &info); | |||
597 | } | |||
598 | ||||
599 | return Success0; | |||
600 | } | |||
601 | ||||
602 | static int | |||
603 | ProcXvMCGetDRInfo(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)xvmcGetDRInfoReq *stuff = (xvmcGetDRInfoReq *)client->requestBuffer; | |||
615 | REQUEST_SIZE_MATCH(xvmcGetDRInfoReq)if ((sizeof(xvmcGetDRInfoReq) >> 2) != client->req_len ) return(16); | |||
616 | ||||
617 | VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(pPort), stuff ->port, XvRTPort, client, (1<<0)); if (rc != 0) return rc; }; | |||
618 | ||||
619 | pScreen = pPort->pAdaptor->pScreen; | |||
620 | pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))); | |||
621 | ||||
622 | rep = (xvmcGetDRInfoReply) { | |||
623 | .type = X_Reply1, | |||
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((void*)0), 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 Success0; | |||
669 | } | |||
670 | ||||
671 | int (*ProcXvMCVector[xvmcNumRequest(9 + 1)]) (ClientPtr) = { | |||
672 | ProcXvMCQueryVersion, | |||
673 | ProcXvMCListSurfaceTypes, | |||
674 | ProcXvMCCreateContext, | |||
675 | ProcXvMCDestroyContext, | |||
676 | ProcXvMCCreateSurface, | |||
677 | ProcXvMCDestroySurface, | |||
678 | ProcXvMCCreateSubpicture, | |||
679 | ProcXvMCDestroySubpicture, | |||
680 | ProcXvMCListSubpictureTypes, ProcXvMCGetDRInfo}; | |||
681 | ||||
682 | static int | |||
683 | ProcXvMCDispatch(ClientPtr client) | |||
684 | { | |||
685 | REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer; | |||
686 | ||||
687 | if (stuff->data < xvmcNumRequest(9 + 1)) | |||
688 | return (*ProcXvMCVector[stuff->data]) (client); | |||
689 | else | |||
690 | return BadRequest1; | |||
691 | } | |||
692 | ||||
693 | static int | |||
694 | SProcXvMCDispatch(ClientPtr client) | |||
695 | { | |||
696 | /* We only support local */ | |||
697 | return BadImplementation17; | |||
698 | } | |||
699 | ||||
700 | void | |||
701 | XvMCExtensionInit(void) | |||
702 | { | |||
703 | ExtensionEntry *extEntry; | |||
704 | ||||
705 | if (!dixPrivateKeyRegistered(XvMCScreenKey(&XvMCScreenKeyRec))) | |||
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"XVideo-MotionCompensation", XvMCNumEvents0, XvMCNumErrors3, | |||
721 | ProcXvMCDispatch, SProcXvMCDispatch, | |||
722 | NULL((void*)0), StandardMinorOpcode); | |||
723 | ||||
724 | if (!extEntry) | |||
725 | return; | |||
726 | ||||
727 | XvMCReqCode = extEntry->base; | |||
728 | XvMCEventBase = extEntry->eventBase; | |||
729 | SetResourceTypeErrorValue(XvMCRTContext, | |||
730 | extEntry->errorBase + XvMCBadContext0); | |||
731 | SetResourceTypeErrorValue(XvMCRTSurface, | |||
732 | extEntry->errorBase + XvMCBadSurface1); | |||
733 | SetResourceTypeErrorValue(XvMCRTSubpicture, | |||
734 | extEntry->errorBase + XvMCBadSubpicture2); | |||
735 | } | |||
736 | ||||
737 | static Bool | |||
738 | XvMCCloseScreen(ScreenPtr pScreen) | |||
739 | { | |||
740 | XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))); | |||
741 | ||||
742 | pScreen->CloseScreen = pScreenPriv->CloseScreen; | |||
743 | ||||
744 | free(pScreenPriv); | |||
745 | ||||
746 | return (*pScreen->CloseScreen) (pScreen); | |||
747 | } | |||
748 | ||||
749 | int | |||
750 | XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt) | |||
751 | { | |||
752 | XvMCScreenPtr pScreenPriv; | |||
753 | ||||
754 | if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) | |||
755 | return BadAlloc11; | |||
756 | ||||
757 | if (!(pScreenPriv = malloc(sizeof(XvMCScreenRec)))) | |||
758 | return BadAlloc11; | |||
759 | ||||
760 | dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey(&XvMCScreenKeyRec), 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 = TRUE1; | |||
774 | ||||
775 | return Success0; | |||
776 | } | |||
777 | ||||
778 | XvImagePtr | |||
779 | XvMCFindXvImage(XvPortPtr pPort, CARD32 id) | |||
780 | { | |||
781 | XvImagePtr pImage = NULL((void*)0); | |||
782 | ScreenPtr pScreen = pPort->pAdaptor->pScreen; | |||
783 | XvMCScreenPtr pScreenPriv; | |||
784 | XvMCAdaptorPtr adaptor = NULL((void*)0); | |||
785 | int i; | |||
786 | ||||
787 | if (!dixPrivateKeyRegistered(XvMCScreenKey(&XvMCScreenKeyRec))) | |||
788 | return NULL((void*)0); | |||
789 | ||||
790 | if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))))) | |||
791 | return NULL((void*)0); | |||
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((void*)0); | |||
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 | ||||
813 | int | |||
814 | xf86XvMCRegisterDRInfo(ScreenPtr pScreen, const char *name, | |||
815 | const char *busID, int major, int minor, int patchLevel) | |||
816 | { | |||
817 | XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates , (&XvMCScreenKeyRec))); | |||
818 | ||||
819 | strlcpy(pScreenPriv->clientDriverName, name, DR_CLIENT_DRIVER_NAME_SIZE)__builtin___strlcpy_chk (pScreenPriv->clientDriverName, name , 48, __builtin_object_size (pScreenPriv->clientDriverName , 2 > 1 ? 1 : 0)); | |||
820 | strlcpy(pScreenPriv->busID, busID, DR_BUSID_SIZE)__builtin___strlcpy_chk (pScreenPriv->busID, busID, 48, __builtin_object_size (pScreenPriv->busID, 2 > 1 ? 1 : 0)); | |||
821 | pScreenPriv->major = major; | |||
822 | pScreenPriv->minor = minor; | |||
823 | pScreenPriv->patchLevel = patchLevel; | |||
824 | return Success0; | |||
825 | } |