Bug Summary

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')

Annotated Source Code

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
35static DevPrivateKeyRec XvMCScreenKeyRec;
36
37#define XvMCScreenKey(&XvMCScreenKeyRec) (&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((void*)0);
48
49typedef 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
63static int
64XvMCDestroyContextRes(void *data, XID id)
65{
66 XvMCContextPtr pContext = (XvMCContextPtr) data;
67
68 pContext->refcnt--;
69
70 if (!pContext->refcnt) {
71 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen)(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
80static int
81XvMCDestroySurfaceRes(void *data, XID id)
82{
83 XvMCSurfacePtr pSurface = (XvMCSurfacePtr) data;
84 XvMCContextPtr pContext = pSurface->context;
85 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen)(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
95static int
96XvMCDestroySubpictureRes(void *data, XID id)
97{
98 XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr) data;
99 XvMCContextPtr pContext = pSubpict->context;
100 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen)(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
110static int
111ProcXvMCQueryVersion(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
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((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
184static int
185ProcXvMCCreateContext(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
279static int
280ProcXvMCDestroyContext(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
298static int
299ProcXvMCCreateSurface(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
357static int
358ProcXvMCDestroySurface(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
376static int
377ProcXvMCCreateSubpicture(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
485static int
486ProcXvMCDestroySubpicture(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
504static int
505ProcXvMCListSubpictureTypes(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)))
1
Taking false branch
525 return BadMatch8; /* No XvMC adaptors */
526
527 if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates
, (&XvMCScreenKeyRec)))
))
2
Assuming 'pScreenPriv' is not null
3
Taking false branch
528 return BadMatch8; /* None this screen */
529
530 for (i = 0; i < pScreenPriv->num_adaptors; i++) {
4
Loop condition is true. Entering loop body
531 if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
5
Taking true branch
532 adaptor = &(pScreenPriv->adaptors[i]);
533 break;
6
Execution continues on line 537
534 }
535 }
536
537 if (!adaptor)
7
Taking false branch
538 return BadMatch8;
539
540 for (i = 0; i < adaptor->num_surfaces; i++) {
8
Loop condition is true. Entering loop body
541 if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
9
Taking true branch
542 surface = adaptor->surfaces[i];
543 break;
10
Execution continues on line 547
544 }
545 }
546
547 if (!surface)
11
Taking false branch
548 return BadMatch8;
549
550 rep = (xvmcListSubpictureTypesReply) {
551 .type = X_Reply1,
552 .sequenceNumber = client->sequence,
553 .num = 0
554 };
555 if (surface->compatible_subpictures)
12
Assuming pointer value is null
13
Taking false branch
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++) {
14
Loop condition is true. Entering loop body
563 pImage = NULL((void*)0);
564 for (j = 0; j < adaptor->num_subpictures; j++) {
15
Loop condition is true. Entering loop body
565 if (surface->compatible_subpictures->xvimage_ids[i] ==
16
Access to field 'xvimage_ids' results in a dereference of a null pointer (loaded from field 'compatible_subpictures')
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
602static int
603ProcXvMCGetDRInfo(ClientPtr client)
604{
605 xvmcGetDRInfoReply rep;
606 XvPortPtr pPort;
607 ScreenPtr pScreen;
608 XvMCScreenPtr pScreenPriv;
609
610#ifdef HAS_XVMCSHM
611 volatile CARD32 *patternP;
612#endif
613
614 REQUEST(xvmcGetDRInfoReq)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
671int (*ProcXvMCVector[xvmcNumRequest(9 + 1)]) (ClientPtr) = {
672ProcXvMCQueryVersion,
673 ProcXvMCListSurfaceTypes,
674 ProcXvMCCreateContext,
675 ProcXvMCDestroyContext,
676 ProcXvMCCreateSurface,
677 ProcXvMCDestroySurface,
678 ProcXvMCCreateSubpicture,
679 ProcXvMCDestroySubpicture,
680 ProcXvMCListSubpictureTypes, ProcXvMCGetDRInfo};
681
682static int
683ProcXvMCDispatch(ClientPtr client)
684{
685 REQUEST(xReq)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
693static int
694SProcXvMCDispatch(ClientPtr client)
695{
696 /* We only support local */
697 return BadImplementation17;
698}
699
700void
701XvMCExtensionInit(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
737static Bool
738XvMCCloseScreen(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
749int
750XvMCScreenInit(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
778XvImagePtr
779XvMCFindXvImage(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
813int
814xf86XvMCRegisterDRInfo(ScreenPtr pScreen, const char *name,
815 const char *busID, int major, int minor, int patchLevel)
816{
817 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen)(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}