Bug Summary

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