File: | Xv.c |
Location: | line 246, column 16 |
Description: | Size argument is greater than the length of the destination buffer |
1 | /*********************************************************** | |||||
2 | Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, | |||||
3 | and the Massachusetts Institute of Technology, Cambridge, Massachusetts. | |||||
4 | ||||||
5 | All Rights Reserved | |||||
6 | ||||||
7 | Permission to use, copy, modify, and distribute this software and its | |||||
8 | documentation for any purpose and without fee is hereby granted, | |||||
9 | provided that the above copyright notice appear in all copies and that | |||||
10 | both that copyright notice and this permission notice appear in | |||||
11 | supporting documentation, and that the names of Digital or MIT not be | |||||
12 | used in advertising or publicity pertaining to distribution of the | |||||
13 | software without specific, written prior permission. | |||||
14 | ||||||
15 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |||||
16 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |||||
17 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |||||
18 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||||
19 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||||
20 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||||
21 | SOFTWARE. | |||||
22 | ||||||
23 | ******************************************************************/ | |||||
24 | /* | |||||
25 | ** File: | |||||
26 | ** | |||||
27 | ** Xv.c --- Xv library extension module. | |||||
28 | ** | |||||
29 | ** Author: | |||||
30 | ** | |||||
31 | ** David Carver (Digital Workstation Engineering/Project Athena) | |||||
32 | ** | |||||
33 | ** Revisions: | |||||
34 | ** | |||||
35 | ** 26.06.91 Carver | |||||
36 | ** - changed XvFreeAdaptors to XvFreeAdaptorInfo | |||||
37 | ** - changed XvFreeEncodings to XvFreeEncodingInfo | |||||
38 | ** | |||||
39 | ** 11.06.91 Carver | |||||
40 | ** - changed SetPortControl to SetPortAttribute | |||||
41 | ** - changed GetPortControl to GetPortAttribute | |||||
42 | ** - changed QueryBestSize | |||||
43 | ** | |||||
44 | ** 15.05.91 Carver | |||||
45 | ** - version 2.0 upgrade | |||||
46 | ** | |||||
47 | ** 240.01.91 Carver | |||||
48 | ** - version 1.4 upgrade | |||||
49 | ** | |||||
50 | */ | |||||
51 | ||||||
52 | #ifdef HAVE_CONFIG_H1 | |||||
53 | # include "config.h" | |||||
54 | #endif | |||||
55 | ||||||
56 | #include <stdio.h> | |||||
57 | #include "Xvlibint.h" | |||||
58 | #include <X11/extensions/Xext.h> | |||||
59 | #include <X11/extensions/extutil.h> | |||||
60 | #include <X11/extensions/XShm.h> | |||||
61 | #include <limits.h> | |||||
62 | ||||||
63 | static XExtensionInfo _xv_info_data; | |||||
64 | static XExtensionInfo *xv_info = &_xv_info_data; | |||||
65 | static const char *xv_extension_name = XvName"XVideo"; | |||||
66 | ||||||
67 | #define XvCheckExtension(dpy, i, val)if (!((i) && ((i)->codes))) { XMissingExtension (dpy , xv_extension_name); return val; } \ | |||||
68 | XextCheckExtension(dpy, i, xv_extension_name, val)if (!((i) && ((i)->codes))) { XMissingExtension (dpy , xv_extension_name); return val; } | |||||
69 | ||||||
70 | #define pad_to_int32(bytes)(((bytes) + 3) & ~3U) (((bytes) + 3) & ~3U) | |||||
71 | ||||||
72 | static char *xv_error_string(Display *dpy, int code, XExtCodes *codes, | |||||
73 | char *buf, int n); | |||||
74 | static int xv_close_display(Display *dpy, XExtCodes *codes); | |||||
75 | static Boolint xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire); | |||||
76 | ||||||
77 | static XExtensionHooks xv_extension_hooks = { | |||||
78 | NULL((void*)0), /* create_gc */ | |||||
79 | NULL((void*)0), /* copy_gc */ | |||||
80 | NULL((void*)0), /* flush_gc */ | |||||
81 | NULL((void*)0), /* free_gc */ | |||||
82 | NULL((void*)0), /* create_font */ | |||||
83 | NULL((void*)0), /* free_font */ | |||||
84 | xv_close_display, /* close_display */ | |||||
85 | xv_wire_to_event, /* wire_to_event */ | |||||
86 | NULL((void*)0), /* event_to_wire */ | |||||
87 | NULL((void*)0), /* error */ | |||||
88 | xv_error_string /* error_string */ | |||||
89 | }; | |||||
90 | ||||||
91 | ||||||
92 | static const char *xv_error_list[] = { | |||||
93 | "BadPort", /* XvBadPort */ | |||||
94 | "BadEncoding", /* XvBadEncoding */ | |||||
95 | "BadControl" /* XvBadControl */ | |||||
96 | }; | |||||
97 | ||||||
98 | static XEXT_GENERATE_CLOSE_DISPLAY(xv_close_display, xv_info)int xv_close_display (Display *dpy, XExtCodes *codes) { return XextRemoveDisplay (xv_info, dpy); } | |||||
99 | ||||||
100 | static XEXT_GENERATE_FIND_DISPLAY(xv_find_display, xv_info,XExtDisplayInfo *xv_find_display (Display *dpy) { XExtDisplayInfo *dpyinfo; if (!xv_info) { if (!(xv_info = XextCreateExtension ())) return ((void*)0); } if (!(dpyinfo = XextFindDisplay (xv_info , dpy))) dpyinfo = XextAddDisplay (xv_info,dpy,xv_extension_name ,&xv_extension_hooks,2,((void*)0)); return dpyinfo; } | |||||
101 | xv_extension_name, &xv_extension_hooks,XExtDisplayInfo *xv_find_display (Display *dpy) { XExtDisplayInfo *dpyinfo; if (!xv_info) { if (!(xv_info = XextCreateExtension ())) return ((void*)0); } if (!(dpyinfo = XextFindDisplay (xv_info , dpy))) dpyinfo = XextAddDisplay (xv_info,dpy,xv_extension_name ,&xv_extension_hooks,2,((void*)0)); return dpyinfo; } | |||||
102 | XvNumEvents, NULL)XExtDisplayInfo *xv_find_display (Display *dpy) { XExtDisplayInfo *dpyinfo; if (!xv_info) { if (!(xv_info = XextCreateExtension ())) return ((void*)0); } if (!(dpyinfo = XextFindDisplay (xv_info , dpy))) dpyinfo = XextAddDisplay (xv_info,dpy,xv_extension_name ,&xv_extension_hooks,2,((void*)0)); return dpyinfo; } | |||||
103 | ||||||
104 | static XEXT_GENERATE_ERROR_STRING(xv_error_string, xv_extension_name,char *xv_error_string (Display *dpy, int code, XExtCodes *codes , char *buf, int n) { code -= codes->first_error; if (code >= 0 && code < 3) { char tmp[256]; __builtin___snprintf_chk (tmp, sizeof(tmp), 0, __builtin_object_size (tmp, 2 > 1 ? 1 : 0), "%s.%d", xv_extension_name, code); XGetErrorDatabaseText (dpy, "XProtoError", tmp, xv_error_list[code], buf, n); return buf; } return (char *)0; } | |||||
105 | XvNumErrors, xv_error_list)char *xv_error_string (Display *dpy, int code, XExtCodes *codes , char *buf, int n) { code -= codes->first_error; if (code >= 0 && code < 3) { char tmp[256]; __builtin___snprintf_chk (tmp, sizeof(tmp), 0, __builtin_object_size (tmp, 2 > 1 ? 1 : 0), "%s.%d", xv_extension_name, code); XGetErrorDatabaseText (dpy, "XProtoError", tmp, xv_error_list[code], buf, n); return buf; } return (char *)0; } | |||||
106 | ||||||
107 | ||||||
108 | int | |||||
109 | XvQueryExtension( | |||||
110 | Display *dpy, | |||||
111 | unsigned int *p_version, | |||||
112 | unsigned int *p_revision, | |||||
113 | unsigned int *p_requestBase, | |||||
114 | unsigned int *p_eventBase, | |||||
115 | unsigned int *p_errorBase) | |||||
116 | { | |||||
117 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
118 | xvQueryExtensionReq *req; | |||||
119 | xvQueryExtensionReply rep; | |||||
120 | int status; | |||||
121 | ||||||
122 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
123 | ||||||
124 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
125 | ||||||
126 | XvGetReq(QueryExtension, req)req = (xvQueryExtensionReq *) _XGetRequest( dpy, (CARD8) info ->codes->major_opcode, 4); req->xvReqType = 0;; | |||||
127 | ||||||
128 | if (!_XReply(dpy, (xReply *) &rep, 0, xFalse0)) { | |||||
129 | status = XvBadExtension1; | |||||
130 | goto out; | |||||
131 | } | |||||
132 | ||||||
133 | *p_version = rep.version; | |||||
134 | *p_revision = rep.revision; | |||||
135 | *p_requestBase = info->codes->major_opcode; | |||||
136 | *p_eventBase = info->codes->first_event; | |||||
137 | *p_errorBase = info->codes->first_error; | |||||
138 | ||||||
139 | status = Success0; | |||||
140 | ||||||
141 | out: | |||||
142 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
143 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
144 | ||||||
145 | return status; | |||||
146 | } | |||||
147 | ||||||
148 | int | |||||
149 | XvQueryAdaptors( | |||||
150 | Display *dpy, | |||||
151 | Window window, | |||||
152 | unsigned int *p_nAdaptors, | |||||
153 | XvAdaptorInfo **p_pAdaptors) | |||||
154 | { | |||||
155 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
156 | xvQueryAdaptorsReq *req; | |||||
157 | xvQueryAdaptorsReply rep; | |||||
158 | size_t size; | |||||
159 | unsigned int ii, jj; | |||||
160 | char *name; | |||||
161 | XvAdaptorInfo *pas = NULL((void*)0), *pa; | |||||
162 | XvFormat *pfs, *pf; | |||||
163 | char *buffer = NULL((void*)0); | |||||
164 | union { | |||||
165 | char *buffer; | |||||
166 | char *string; | |||||
167 | xvAdaptorInfo *pa; | |||||
168 | xvFormat *pf; | |||||
169 | } u; | |||||
170 | int status; | |||||
171 | ||||||
172 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
173 | ||||||
174 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
175 | ||||||
176 | XvGetReq(QueryAdaptors, req)req = (xvQueryAdaptorsReq *) _XGetRequest( dpy, (CARD8) info-> codes->major_opcode, 8); req->xvReqType = 1;; | |||||
177 | req->window = window; | |||||
178 | ||||||
179 | /* READ THE REPLY */ | |||||
180 | ||||||
181 | if (_XReply(dpy, (xReply *) &rep, 0, xFalse0) == 0) { | |||||
| ||||||
182 | rep.num_adaptors = 0; | |||||
183 | status = XvBadReply4; | |||||
184 | goto out; | |||||
185 | } | |||||
186 | ||||||
187 | size = rep.length << 2; | |||||
188 | if (size > 0) { | |||||
189 | if ((buffer = Xmalloc(size)malloc(((size) == 0 ? 1 : (size)))) == NULL((void*)0)) { | |||||
190 | _XEatDataWords(dpy, rep.length); | |||||
191 | status = XvBadAlloc5; | |||||
192 | goto out; | |||||
193 | } | |||||
194 | _XRead(dpy, buffer, (long) size); | |||||
195 | } | |||||
196 | ||||||
197 | /* GET INPUT ADAPTORS */ | |||||
198 | ||||||
199 | if (rep.num_adaptors == 0) { | |||||
200 | /* If there's no adaptors, there's nothing more to do. */ | |||||
201 | status = Success0; | |||||
202 | goto out; | |||||
203 | } | |||||
204 | ||||||
205 | if (size < (rep.num_adaptors * sz_xvAdaptorInfo12)) { | |||||
206 | /* If there's not enough data for the number of adaptors, | |||||
207 | then we have a problem. */ | |||||
208 | status = XvBadReply4; | |||||
209 | goto out; | |||||
210 | } | |||||
211 | ||||||
212 | size = rep.num_adaptors * sizeof(XvAdaptorInfo); | |||||
213 | if ((pas = Xmalloc(size)malloc(((size) == 0 ? 1 : (size)))) == NULL((void*)0)) { | |||||
214 | status = XvBadAlloc5; | |||||
215 | goto out; | |||||
216 | } | |||||
217 | ||||||
218 | /* INIT ADAPTOR FIELDS */ | |||||
219 | ||||||
220 | pa = pas; | |||||
221 | for (ii = 0; ii < rep.num_adaptors; ii++) { | |||||
222 | pa->num_adaptors = 0; | |||||
223 | pa->name = (char *) NULL((void*)0); | |||||
224 | pa->formats = (XvFormat *) NULL((void*)0); | |||||
225 | pa++; | |||||
226 | } | |||||
227 | ||||||
228 | u.buffer = buffer; | |||||
229 | pa = pas; | |||||
230 | for (ii = 0; ii < rep.num_adaptors; ii++) { | |||||
231 | pa->type = u.pa->type; | |||||
232 | pa->base_id = u.pa->base_id; | |||||
233 | pa->num_ports = u.pa->num_ports; | |||||
234 | pa->num_formats = u.pa->num_formats; | |||||
235 | pa->num_adaptors = rep.num_adaptors - ii; | |||||
236 | ||||||
237 | /* GET ADAPTOR NAME */ | |||||
238 | ||||||
239 | size = u.pa->name_size; | |||||
240 | u.buffer += pad_to_int32(sz_xvAdaptorInfo)(((12) + 3) & ~3U); | |||||
241 | ||||||
242 | if ((name = Xmalloc(size + 1)malloc(((size + 1) == 0 ? 1 : (size + 1)))) == NULL((void*)0)) { | |||||
243 | status = XvBadAlloc5; | |||||
244 | goto out; | |||||
245 | } | |||||
246 | (void) strncpy(name, u.string, size)__builtin___strncpy_chk (name, u.string, size, __builtin_object_size (name, 2 > 1 ? 1 : 0)); | |||||
| ||||||
247 | name[size] = '\0'; | |||||
248 | pa->name = name; | |||||
249 | ||||||
250 | u.buffer += pad_to_int32(size)(((size) + 3) & ~3U); | |||||
251 | ||||||
252 | /* GET FORMATS */ | |||||
253 | ||||||
254 | size = pa->num_formats * sizeof(XvFormat); | |||||
255 | if ((pfs = Xmalloc(size)malloc(((size) == 0 ? 1 : (size)))) == NULL((void*)0)) { | |||||
256 | status = XvBadAlloc5; | |||||
257 | goto out; | |||||
258 | } | |||||
259 | ||||||
260 | pf = pfs; | |||||
261 | for (jj = 0; jj < pa->num_formats; jj++) { | |||||
262 | pf->depth = u.pf->depth; | |||||
263 | pf->visual_id = u.pf->visual; | |||||
264 | pf++; | |||||
265 | ||||||
266 | u.buffer += pad_to_int32(sz_xvFormat)(((8) + 3) & ~3U); | |||||
267 | } | |||||
268 | ||||||
269 | pa->formats = pfs; | |||||
270 | ||||||
271 | pa++; | |||||
272 | ||||||
273 | } | |||||
274 | ||||||
275 | status = Success0; | |||||
276 | ||||||
277 | out: | |||||
278 | if (status != Success0) { | |||||
279 | XvFreeAdaptorInfo(pas); | |||||
280 | pas = NULL((void*)0); | |||||
281 | } | |||||
282 | ||||||
283 | *p_nAdaptors = rep.num_adaptors; | |||||
284 | *p_pAdaptors = pas; | |||||
285 | ||||||
286 | Xfree(buffer)free((buffer)); | |||||
287 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
288 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
289 | ||||||
290 | return status; | |||||
291 | } | |||||
292 | ||||||
293 | ||||||
294 | void | |||||
295 | XvFreeAdaptorInfo(XvAdaptorInfo *pAdaptors) | |||||
296 | { | |||||
297 | XvAdaptorInfo *pa; | |||||
298 | unsigned int ii; | |||||
299 | ||||||
300 | if (!pAdaptors) | |||||
301 | return; | |||||
302 | ||||||
303 | pa = pAdaptors; | |||||
304 | ||||||
305 | for (ii = 0; ii < pAdaptors->num_adaptors; ii++, pa++) { | |||||
306 | if (pa->name) { | |||||
307 | Xfree(pa->name)free((pa->name)); | |||||
308 | } | |||||
309 | if (pa->formats) { | |||||
310 | Xfree(pa->formats)free((pa->formats)); | |||||
311 | } | |||||
312 | } | |||||
313 | ||||||
314 | Xfree(pAdaptors)free((pAdaptors)); | |||||
315 | } | |||||
316 | ||||||
317 | int | |||||
318 | XvQueryEncodings( | |||||
319 | Display *dpy, | |||||
320 | XvPortID port, | |||||
321 | unsigned int *p_nEncodings, | |||||
322 | XvEncodingInfo ** p_pEncodings) | |||||
323 | { | |||||
324 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
325 | xvQueryEncodingsReq *req; | |||||
326 | xvQueryEncodingsReply rep; | |||||
327 | size_t size; | |||||
328 | unsigned int jj; | |||||
329 | char *name; | |||||
330 | XvEncodingInfo *pes = NULL((void*)0), *pe; | |||||
331 | char *buffer = NULL((void*)0); | |||||
332 | union { | |||||
333 | char *buffer; | |||||
334 | char *string; | |||||
335 | xvEncodingInfo *pe; | |||||
336 | } u; | |||||
337 | int status; | |||||
338 | ||||||
339 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
340 | ||||||
341 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
342 | ||||||
343 | XvGetReq(QueryEncodings, req)req = (xvQueryEncodingsReq *) _XGetRequest( dpy, (CARD8) info ->codes->major_opcode, 8); req->xvReqType = 2;; | |||||
344 | req->port = port; | |||||
345 | ||||||
346 | /* READ THE REPLY */ | |||||
347 | ||||||
348 | if (_XReply(dpy, (xReply *) &rep, 0, xFalse0) == 0) { | |||||
349 | rep.num_encodings = 0; | |||||
350 | status = XvBadReply4; | |||||
351 | goto out; | |||||
352 | } | |||||
353 | ||||||
354 | size = rep.length << 2; | |||||
355 | if (size > 0) { | |||||
356 | if ((buffer = Xmalloc(size)malloc(((size) == 0 ? 1 : (size)))) == NULL((void*)0)) { | |||||
357 | _XEatDataWords(dpy, rep.length); | |||||
358 | status = XvBadAlloc5; | |||||
359 | goto out; | |||||
360 | } | |||||
361 | _XRead(dpy, buffer, (long) size); | |||||
362 | } | |||||
363 | ||||||
364 | /* GET ENCODINGS */ | |||||
365 | ||||||
366 | if (rep.num_encodings == 0) { | |||||
367 | /* If there's no encodings, there's nothing more to do. */ | |||||
368 | status = Success0; | |||||
369 | goto out; | |||||
370 | } | |||||
371 | ||||||
372 | if (size < (rep.num_encodings * sz_xvEncodingInfo(12 + 8))) { | |||||
373 | /* If there's not enough data for the number of adaptors, | |||||
374 | then we have a problem. */ | |||||
375 | status = XvBadReply4; | |||||
376 | goto out; | |||||
377 | } | |||||
378 | ||||||
379 | size = rep.num_encodings * sizeof(XvEncodingInfo); | |||||
380 | if ((pes = Xmalloc(size)malloc(((size) == 0 ? 1 : (size)))) == NULL((void*)0)) { | |||||
381 | status = XvBadAlloc5; | |||||
382 | goto out; | |||||
383 | } | |||||
384 | ||||||
385 | /* INITIALIZE THE ENCODING POINTER */ | |||||
386 | ||||||
387 | pe = pes; | |||||
388 | for (jj = 0; jj < rep.num_encodings; jj++) { | |||||
389 | pe->name = (char *) NULL((void*)0); | |||||
390 | pe->num_encodings = 0; | |||||
391 | pe++; | |||||
392 | } | |||||
393 | ||||||
394 | u.buffer = buffer; | |||||
395 | ||||||
396 | pe = pes; | |||||
397 | for (jj = 0; jj < rep.num_encodings; jj++) { | |||||
398 | pe->encoding_id = u.pe->encoding; | |||||
399 | pe->width = u.pe->width; | |||||
400 | pe->height = u.pe->height; | |||||
401 | pe->rate.numerator = u.pe->rate.numerator; | |||||
402 | pe->rate.denominator = u.pe->rate.denominator; | |||||
403 | pe->num_encodings = rep.num_encodings - jj; | |||||
404 | ||||||
405 | size = u.pe->name_size; | |||||
406 | u.buffer += pad_to_int32(sz_xvEncodingInfo)((((12 + 8)) + 3) & ~3U); | |||||
407 | ||||||
408 | if ((name = Xmalloc(size + 1)malloc(((size + 1) == 0 ? 1 : (size + 1)))) == NULL((void*)0)) { | |||||
409 | status = XvBadAlloc5; | |||||
410 | goto out; | |||||
411 | } | |||||
412 | strncpy(name, u.string, size)__builtin___strncpy_chk (name, u.string, size, __builtin_object_size (name, 2 > 1 ? 1 : 0)); | |||||
413 | name[size] = '\0'; | |||||
414 | pe->name = name; | |||||
415 | pe++; | |||||
416 | ||||||
417 | u.buffer += pad_to_int32(size)(((size) + 3) & ~3U); | |||||
418 | } | |||||
419 | ||||||
420 | status = Success0; | |||||
421 | ||||||
422 | out: | |||||
423 | if (status != Success0) { | |||||
424 | XvFreeEncodingInfo(pes); | |||||
425 | pes = NULL((void*)0); | |||||
426 | } | |||||
427 | ||||||
428 | *p_nEncodings = rep.num_encodings; | |||||
429 | *p_pEncodings = pes; | |||||
430 | ||||||
431 | Xfree(buffer)free((buffer)); | |||||
432 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
433 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
434 | ||||||
435 | return (Success0); | |||||
436 | } | |||||
437 | ||||||
438 | void | |||||
439 | XvFreeEncodingInfo(XvEncodingInfo *pEncodings) | |||||
440 | { | |||||
441 | XvEncodingInfo *pe; | |||||
442 | unsigned long ii; | |||||
443 | ||||||
444 | if (!pEncodings) | |||||
445 | return; | |||||
446 | ||||||
447 | pe = pEncodings; | |||||
448 | ||||||
449 | for (ii = 0; ii < pEncodings->num_encodings; ii++, pe++) { | |||||
450 | if (pe->name) | |||||
451 | Xfree(pe->name)free((pe->name)); | |||||
452 | } | |||||
453 | ||||||
454 | Xfree(pEncodings)free((pEncodings)); | |||||
455 | } | |||||
456 | ||||||
457 | int | |||||
458 | XvPutVideo( | |||||
459 | Display *dpy, | |||||
460 | XvPortID port, | |||||
461 | Drawable d, | |||||
462 | GC gc, | |||||
463 | int vx, int vy, | |||||
464 | unsigned int vw, unsigned int vh, | |||||
465 | int dx, int dy, | |||||
466 | unsigned int dw, unsigned int dh) | |||||
467 | { | |||||
468 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
469 | xvPutVideoReq *req; | |||||
470 | ||||||
471 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
472 | ||||||
473 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
474 | ||||||
475 | FlushGC(dpy, gc)if ((gc)->dirty) _XFlushGCCache((dpy), (gc)); | |||||
476 | ||||||
477 | XvGetReq(PutVideo, req)req = (xvPutVideoReq *) _XGetRequest( dpy, (CARD8) info->codes ->major_opcode, 32); req->xvReqType = 5;; | |||||
478 | ||||||
479 | req->port = port; | |||||
480 | req->drawable = d; | |||||
481 | req->gc = gc->gid; | |||||
482 | req->vid_x = vx; | |||||
483 | req->vid_y = vy; | |||||
484 | req->vid_w = vw; | |||||
485 | req->vid_h = vh; | |||||
486 | req->drw_x = dx; | |||||
487 | req->drw_y = dy; | |||||
488 | req->drw_w = dw; | |||||
489 | req->drw_h = dh; | |||||
490 | ||||||
491 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
492 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
493 | ||||||
494 | return Success0; | |||||
495 | } | |||||
496 | ||||||
497 | int | |||||
498 | XvPutStill( | |||||
499 | Display *dpy, | |||||
500 | XvPortID port, | |||||
501 | Drawable d, | |||||
502 | GC gc, | |||||
503 | int vx, int vy, | |||||
504 | unsigned int vw, unsigned int vh, | |||||
505 | int dx, int dy, | |||||
506 | unsigned int dw, unsigned int dh) | |||||
507 | { | |||||
508 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
509 | xvPutStillReq *req; | |||||
510 | ||||||
511 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
512 | ||||||
513 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
514 | ||||||
515 | FlushGC(dpy, gc)if ((gc)->dirty) _XFlushGCCache((dpy), (gc)); | |||||
516 | ||||||
517 | XvGetReq(PutStill, req)req = (xvPutStillReq *) _XGetRequest( dpy, (CARD8) info->codes ->major_opcode, 32); req->xvReqType = 6;; | |||||
518 | req->port = port; | |||||
519 | req->drawable = d; | |||||
520 | req->gc = gc->gid; | |||||
521 | req->vid_x = vx; | |||||
522 | req->vid_y = vy; | |||||
523 | req->vid_w = vw; | |||||
524 | req->vid_h = vh; | |||||
525 | req->drw_x = dx; | |||||
526 | req->drw_y = dy; | |||||
527 | req->drw_w = dw; | |||||
528 | req->drw_h = dh; | |||||
529 | ||||||
530 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
531 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
532 | ||||||
533 | return Success0; | |||||
534 | } | |||||
535 | ||||||
536 | int | |||||
537 | XvGetVideo( | |||||
538 | Display *dpy, | |||||
539 | XvPortID port, | |||||
540 | Drawable d, | |||||
541 | GC gc, | |||||
542 | int vx, int vy, | |||||
543 | unsigned int vw, unsigned int vh, | |||||
544 | int dx, int dy, | |||||
545 | unsigned int dw, unsigned int dh) | |||||
546 | { | |||||
547 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
548 | xvGetVideoReq *req; | |||||
549 | ||||||
550 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
551 | ||||||
552 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
553 | ||||||
554 | FlushGC(dpy, gc)if ((gc)->dirty) _XFlushGCCache((dpy), (gc)); | |||||
555 | ||||||
556 | XvGetReq(GetVideo, req)req = (xvGetVideoReq *) _XGetRequest( dpy, (CARD8) info->codes ->major_opcode, 32); req->xvReqType = 7;; | |||||
557 | req->port = port; | |||||
558 | req->drawable = d; | |||||
559 | req->gc = gc->gid; | |||||
560 | req->vid_x = vx; | |||||
561 | req->vid_y = vy; | |||||
562 | req->vid_w = vw; | |||||
563 | req->vid_h = vh; | |||||
564 | req->drw_x = dx; | |||||
565 | req->drw_y = dy; | |||||
566 | req->drw_w = dw; | |||||
567 | req->drw_h = dh; | |||||
568 | ||||||
569 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
570 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
571 | ||||||
572 | return Success0; | |||||
573 | } | |||||
574 | ||||||
575 | int | |||||
576 | XvGetStill( | |||||
577 | Display *dpy, | |||||
578 | XvPortID port, | |||||
579 | Drawable d, | |||||
580 | GC gc, | |||||
581 | int vx, int vy, | |||||
582 | unsigned int vw, unsigned int vh, | |||||
583 | int dx, int dy, | |||||
584 | unsigned int dw, unsigned int dh) | |||||
585 | { | |||||
586 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
587 | xvGetStillReq *req; | |||||
588 | ||||||
589 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
590 | ||||||
591 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
592 | ||||||
593 | FlushGC(dpy, gc)if ((gc)->dirty) _XFlushGCCache((dpy), (gc)); | |||||
594 | ||||||
595 | XvGetReq(GetStill, req)req = (xvGetStillReq *) _XGetRequest( dpy, (CARD8) info->codes ->major_opcode, 32); req->xvReqType = 8;; | |||||
596 | req->port = port; | |||||
597 | req->drawable = d; | |||||
598 | req->gc = gc->gid; | |||||
599 | req->vid_x = vx; | |||||
600 | req->vid_y = vy; | |||||
601 | req->vid_w = vw; | |||||
602 | req->vid_h = vh; | |||||
603 | req->drw_x = dx; | |||||
604 | req->drw_y = dy; | |||||
605 | req->drw_w = dw; | |||||
606 | req->drw_h = dh; | |||||
607 | ||||||
608 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
609 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
610 | ||||||
611 | return Success0; | |||||
612 | } | |||||
613 | ||||||
614 | int | |||||
615 | XvStopVideo(Display *dpy, XvPortID port, Drawable draw) | |||||
616 | { | |||||
617 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
618 | xvStopVideoReq *req; | |||||
619 | ||||||
620 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
621 | ||||||
622 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
623 | ||||||
624 | XvGetReq(StopVideo, req)req = (xvStopVideoReq *) _XGetRequest( dpy, (CARD8) info-> codes->major_opcode, 12); req->xvReqType = 9;; | |||||
625 | req->port = port; | |||||
626 | req->drawable = draw; | |||||
627 | ||||||
628 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
629 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
630 | ||||||
631 | return Success0; | |||||
632 | } | |||||
633 | ||||||
634 | int | |||||
635 | XvGrabPort(Display *dpy, XvPortID port, Time time) | |||||
636 | { | |||||
637 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
638 | int result; | |||||
639 | xvGrabPortReply rep; | |||||
640 | xvGrabPortReq *req; | |||||
641 | ||||||
642 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
643 | ||||||
644 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
645 | ||||||
646 | XvGetReq(GrabPort, req)req = (xvGrabPortReq *) _XGetRequest( dpy, (CARD8) info->codes ->major_opcode, 12); req->xvReqType = 3;; | |||||
647 | req->port = port; | |||||
648 | req->time = time; | |||||
649 | ||||||
650 | if (_XReply(dpy, (xReply *) &rep, 0, xTrue1) == 0) | |||||
651 | rep.result = GrabSuccess0; | |||||
652 | ||||||
653 | result = rep.result; | |||||
654 | ||||||
655 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
656 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
657 | ||||||
658 | return result; | |||||
659 | } | |||||
660 | ||||||
661 | int | |||||
662 | XvUngrabPort(Display *dpy, XvPortID port, Time time) | |||||
663 | { | |||||
664 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
665 | xvUngrabPortReq *req; | |||||
666 | ||||||
667 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
668 | ||||||
669 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
670 | ||||||
671 | XvGetReq(UngrabPort, req)req = (xvUngrabPortReq *) _XGetRequest( dpy, (CARD8) info-> codes->major_opcode, 12); req->xvReqType = 4;; | |||||
672 | req->port = port; | |||||
673 | req->time = time; | |||||
674 | ||||||
675 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
676 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
677 | ||||||
678 | return Success0; | |||||
679 | } | |||||
680 | ||||||
681 | int | |||||
682 | XvSelectVideoNotify(Display *dpy, Drawable drawable, Boolint onoff) | |||||
683 | { | |||||
684 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
685 | xvSelectVideoNotifyReq *req; | |||||
686 | ||||||
687 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
688 | ||||||
689 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
690 | ||||||
691 | XvGetReq(SelectVideoNotify, req)req = (xvSelectVideoNotifyReq *) _XGetRequest( dpy, (CARD8) info ->codes->major_opcode, 12); req->xvReqType = 10;; | |||||
692 | req->drawable = drawable; | |||||
693 | req->onoff = onoff; | |||||
694 | ||||||
695 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
696 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
697 | ||||||
698 | return Success0; | |||||
699 | } | |||||
700 | ||||||
701 | int | |||||
702 | XvSelectPortNotify(Display *dpy, XvPortID port, Boolint onoff) | |||||
703 | { | |||||
704 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
705 | xvSelectPortNotifyReq *req; | |||||
706 | ||||||
707 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
708 | ||||||
709 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
710 | ||||||
711 | XvGetReq(SelectPortNotify, req)req = (xvSelectPortNotifyReq *) _XGetRequest( dpy, (CARD8) info ->codes->major_opcode, 12); req->xvReqType = 11;; | |||||
712 | req->port = port; | |||||
713 | req->onoff = onoff; | |||||
714 | ||||||
715 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
716 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
717 | ||||||
718 | return Success0; | |||||
719 | } | |||||
720 | ||||||
721 | int | |||||
722 | XvSetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int value) | |||||
723 | { | |||||
724 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
725 | xvSetPortAttributeReq *req; | |||||
726 | ||||||
727 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
728 | ||||||
729 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
730 | ||||||
731 | XvGetReq(SetPortAttribute, req)req = (xvSetPortAttributeReq *) _XGetRequest( dpy, (CARD8) info ->codes->major_opcode, 16); req->xvReqType = 13;; | |||||
732 | req->port = port; | |||||
733 | req->attribute = attribute; | |||||
734 | req->value = value; | |||||
735 | ||||||
736 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
737 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
738 | ||||||
739 | return (Success0); | |||||
740 | } | |||||
741 | ||||||
742 | int | |||||
743 | XvGetPortAttribute(Display *dpy, XvPortID port, Atom attribute, int *p_value) | |||||
744 | { | |||||
745 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
746 | xvGetPortAttributeReq *req; | |||||
747 | xvGetPortAttributeReply rep; | |||||
748 | int status; | |||||
749 | ||||||
750 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
751 | ||||||
752 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
753 | ||||||
754 | XvGetReq(GetPortAttribute, req)req = (xvGetPortAttributeReq *) _XGetRequest( dpy, (CARD8) info ->codes->major_opcode, 12); req->xvReqType = 14;; | |||||
755 | req->port = port; | |||||
756 | req->attribute = attribute; | |||||
757 | ||||||
758 | /* READ THE REPLY */ | |||||
759 | ||||||
760 | if (_XReply(dpy, (xReply *) &rep, 0, xFalse0) == 0) { | |||||
761 | status = XvBadReply4; | |||||
762 | } | |||||
763 | else { | |||||
764 | *p_value = rep.value; | |||||
765 | status = Success0; | |||||
766 | } | |||||
767 | ||||||
768 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
769 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
770 | ||||||
771 | return status; | |||||
772 | } | |||||
773 | ||||||
774 | int | |||||
775 | XvQueryBestSize( | |||||
776 | Display *dpy, | |||||
777 | XvPortID port, | |||||
778 | Boolint motion, | |||||
779 | unsigned int vid_w, | |||||
780 | unsigned int vid_h, | |||||
781 | unsigned int drw_w, | |||||
782 | unsigned int drw_h, | |||||
783 | unsigned int *p_actual_width, | |||||
784 | unsigned int *p_actual_height) | |||||
785 | { | |||||
786 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
787 | xvQueryBestSizeReq *req; | |||||
788 | xvQueryBestSizeReply rep; | |||||
789 | int status; | |||||
790 | ||||||
791 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
792 | ||||||
793 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
794 | ||||||
795 | XvGetReq(QueryBestSize, req)req = (xvQueryBestSizeReq *) _XGetRequest( dpy, (CARD8) info-> codes->major_opcode, 20); req->xvReqType = 12;; | |||||
796 | req->port = port; | |||||
797 | req->motion = motion; | |||||
798 | req->vid_w = vid_w; | |||||
799 | req->vid_h = vid_h; | |||||
800 | req->drw_w = drw_w; | |||||
801 | req->drw_h = drw_h; | |||||
802 | ||||||
803 | /* READ THE REPLY */ | |||||
804 | ||||||
805 | if (_XReply(dpy, (xReply *) &rep, 0, xFalse0) == 0) { | |||||
806 | status = XvBadReply4; | |||||
807 | } | |||||
808 | else { | |||||
809 | *p_actual_width = rep.actual_width; | |||||
810 | *p_actual_height = rep.actual_height; | |||||
811 | status = Success0; | |||||
812 | } | |||||
813 | ||||||
814 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
815 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
816 | ||||||
817 | return status; | |||||
818 | } | |||||
819 | ||||||
820 | ||||||
821 | XvAttribute * | |||||
822 | XvQueryPortAttributes(Display *dpy, XvPortID port, int *num) | |||||
823 | { | |||||
824 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
825 | xvQueryPortAttributesReq *req; | |||||
826 | xvQueryPortAttributesReply rep; | |||||
827 | XvAttribute *ret = NULL((void*)0); | |||||
828 | ||||||
829 | *num = 0; | |||||
830 | ||||||
831 | XvCheckExtension(dpy, info, NULL)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return ((void*)0); }; | |||||
832 | ||||||
833 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
834 | ||||||
835 | XvGetReq(QueryPortAttributes, req)req = (xvQueryPortAttributesReq *) _XGetRequest( dpy, (CARD8) info->codes->major_opcode, 8); req->xvReqType = 15;; | |||||
836 | req->port = port; | |||||
837 | ||||||
838 | /* READ THE REPLY */ | |||||
839 | ||||||
840 | if (_XReply(dpy, (xReply *) &rep, 0, xFalse0) == 0) { | |||||
841 | goto out; | |||||
842 | } | |||||
843 | ||||||
844 | /* | |||||
845 | * X server sends data packed as: | |||||
846 | * attribute1, name1, attribute2, name2, ... | |||||
847 | * We allocate a single buffer large enough to hold them all and | |||||
848 | * then de-interleave the data so we return it to clients as: | |||||
849 | * attribute1, attribute2, ..., name1, name2, ... | |||||
850 | * so that clients may refer to attributes as a simple array of | |||||
851 | * structs: attributes[0], attributes[1], ... | |||||
852 | * and free it as a single/simple buffer. | |||||
853 | */ | |||||
854 | ||||||
855 | if (rep.num_attributes) { | |||||
856 | unsigned long size; | |||||
857 | ||||||
858 | /* limit each part to no more than one half the max size */ | |||||
859 | if ((rep.num_attributes < ((INT_MAX2147483647 / 2) / sizeof(XvAttribute))) && | |||||
860 | (rep.text_size < (INT_MAX2147483647 / 2) - 1)) { | |||||
861 | size = (rep.num_attributes * sizeof(XvAttribute)) + | |||||
862 | rep.text_size + 1; | |||||
863 | ret = Xmalloc(size)malloc(((size) == 0 ? 1 : (size))); | |||||
864 | } | |||||
865 | ||||||
866 | if (ret != NULL((void*)0)) { | |||||
867 | char *marker = (char *) (&ret[rep.num_attributes]); | |||||
868 | xvAttributeInfo Info; | |||||
869 | unsigned int i; | |||||
870 | ||||||
871 | /* keep track of remaining room for text strings */ | |||||
872 | size = rep.text_size; | |||||
873 | ||||||
874 | for (i = 0; i < rep.num_attributes; i++) { | |||||
875 | _XRead(dpy, (char *) (&Info), sz_xvAttributeInfo16); | |||||
876 | ret[i].flags = (int) Info.flags; | |||||
877 | ret[i].min_value = Info.min; | |||||
878 | ret[i].max_value = Info.max; | |||||
879 | ret[i].name = marker; | |||||
880 | if (Info.size <= size) { | |||||
881 | _XRead(dpy, marker, Info.size); | |||||
882 | marker += Info.size; | |||||
883 | size -= Info.size; | |||||
884 | } | |||||
885 | (*num)++; | |||||
886 | } | |||||
887 | ||||||
888 | /* ensure final string is nil-terminated to avoid exposure of | |||||
889 | uninitialized memory */ | |||||
890 | *marker = '\0'; | |||||
891 | } | |||||
892 | else | |||||
893 | _XEatDataWords(dpy, rep.length); | |||||
894 | } | |||||
895 | ||||||
896 | out: | |||||
897 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
898 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
899 | ||||||
900 | return ret; | |||||
901 | } | |||||
902 | ||||||
903 | XvImageFormatValues * | |||||
904 | XvListImageFormats(Display *dpy, XvPortID port, int *num) | |||||
905 | { | |||||
906 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
907 | xvListImageFormatsReq *req; | |||||
908 | xvListImageFormatsReply rep; | |||||
909 | XvImageFormatValues *ret = NULL((void*)0); | |||||
910 | ||||||
911 | *num = 0; | |||||
912 | ||||||
913 | XvCheckExtension(dpy, info, NULL)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return ((void*)0); }; | |||||
914 | ||||||
915 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
916 | ||||||
917 | XvGetReq(ListImageFormats, req)req = (xvListImageFormatsReq *) _XGetRequest( dpy, (CARD8) info ->codes->major_opcode, 8); req->xvReqType = 16;; | |||||
918 | req->port = port; | |||||
919 | ||||||
920 | /* READ THE REPLY */ | |||||
921 | ||||||
922 | if (_XReply(dpy, (xReply *) &rep, 0, xFalse0) == 0) { | |||||
923 | goto out; | |||||
924 | } | |||||
925 | ||||||
926 | if (rep.num_formats) { | |||||
927 | if (rep.num_formats < (INT_MAX2147483647 / sizeof(XvImageFormatValues))) | |||||
928 | ret = Xmalloc(rep.num_formats * sizeof(XvImageFormatValues))malloc(((rep.num_formats * sizeof(XvImageFormatValues)) == 0 ? 1 : (rep.num_formats * sizeof(XvImageFormatValues)))); | |||||
929 | ||||||
930 | if (ret != NULL((void*)0)) { | |||||
931 | xvImageFormatInfo Info; | |||||
932 | unsigned int i; | |||||
933 | ||||||
934 | for (i = 0; i < rep.num_formats; i++) { | |||||
935 | _XRead(dpy, (char *) (&Info), sz_xvImageFormatInfo128); | |||||
936 | ret[i].id = Info.id; | |||||
937 | ret[i].type = Info.type; | |||||
938 | ret[i].byte_order = Info.byte_order; | |||||
939 | memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16)__builtin___memcpy_chk (&(ret[i].guid[0]), &(Info.guid [0]), 16, __builtin_object_size (&(ret[i].guid[0]), 0)); | |||||
940 | ret[i].bits_per_pixel = Info.bpp; | |||||
941 | ret[i].format = Info.format; | |||||
942 | ret[i].num_planes = Info.num_planes; | |||||
943 | ret[i].depth = Info.depth; | |||||
944 | ret[i].red_mask = Info.red_mask; | |||||
945 | ret[i].green_mask = Info.green_mask; | |||||
946 | ret[i].blue_mask = Info.blue_mask; | |||||
947 | ret[i].y_sample_bits = Info.y_sample_bits; | |||||
948 | ret[i].u_sample_bits = Info.u_sample_bits; | |||||
949 | ret[i].v_sample_bits = Info.v_sample_bits; | |||||
950 | ret[i].horz_y_period = Info.horz_y_period; | |||||
951 | ret[i].horz_u_period = Info.horz_u_period; | |||||
952 | ret[i].horz_v_period = Info.horz_v_period; | |||||
953 | ret[i].vert_y_period = Info.vert_y_period; | |||||
954 | ret[i].vert_u_period = Info.vert_u_period; | |||||
955 | ret[i].vert_v_period = Info.vert_v_period; | |||||
956 | memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32)__builtin___memcpy_chk (&(ret[i].component_order[0]), & (Info.comp_order[0]), 32, __builtin_object_size (&(ret[i] .component_order[0]), 0)); | |||||
957 | ret[i].scanline_order = Info.scanline_order; | |||||
958 | (*num)++; | |||||
959 | } | |||||
960 | } | |||||
961 | else | |||||
962 | _XEatDataWords(dpy, rep.length); | |||||
963 | } | |||||
964 | ||||||
965 | out: | |||||
966 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
967 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
968 | ||||||
969 | return ret; | |||||
970 | } | |||||
971 | ||||||
972 | XvImage * | |||||
973 | XvCreateImage( | |||||
974 | Display *dpy, | |||||
975 | XvPortID port, | |||||
976 | int id, | |||||
977 | char *data, | |||||
978 | int width, | |||||
979 | int height) | |||||
980 | { | |||||
981 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
982 | xvQueryImageAttributesReq *req; | |||||
983 | xvQueryImageAttributesReply rep; | |||||
984 | XvImage *ret = NULL((void*)0); | |||||
985 | ||||||
986 | XvCheckExtension(dpy, info, NULL)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return ((void*)0); }; | |||||
987 | ||||||
988 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
989 | ||||||
990 | XvGetReq(QueryImageAttributes, req)req = (xvQueryImageAttributesReq *) _XGetRequest( dpy, (CARD8 ) info->codes->major_opcode, 16); req->xvReqType = 17 ;; | |||||
991 | req->id = id; | |||||
992 | req->port = port; | |||||
993 | req->width = width; | |||||
994 | req->height = height; | |||||
995 | ||||||
996 | /* READ THE REPLY */ | |||||
997 | ||||||
998 | if (!_XReply(dpy, (xReply *) &rep, 0, xFalse0)) { | |||||
999 | goto out; | |||||
1000 | } | |||||
1001 | ||||||
1002 | if (rep.num_planes < ((INT_MAX2147483647 >> 3) - sizeof(XvImage))) | |||||
1003 | ret = Xmalloc(sizeof(XvImage) + (rep.num_planes << 3))malloc(((sizeof(XvImage) + (rep.num_planes << 3)) == 0 ? 1 : (sizeof(XvImage) + (rep.num_planes << 3)))); | |||||
1004 | ||||||
1005 | if (ret != NULL((void*)0)) { | |||||
1006 | ret->id = id; | |||||
1007 | ret->width = rep.width; | |||||
1008 | ret->height = rep.height; | |||||
1009 | ret->data_size = rep.data_size; | |||||
1010 | ret->num_planes = rep.num_planes; | |||||
1011 | ret->pitches = (int *) (&ret[1]); | |||||
1012 | ret->offsets = ret->pitches + rep.num_planes; | |||||
1013 | ret->data = data; | |||||
1014 | ret->obdata = NULL((void*)0); | |||||
1015 | _XRead(dpy, (char *) (ret->pitches), rep.num_planes << 2); | |||||
1016 | _XRead(dpy, (char *) (ret->offsets), rep.num_planes << 2); | |||||
1017 | } | |||||
1018 | else | |||||
1019 | _XEatDataWords(dpy, rep.length); | |||||
1020 | ||||||
1021 | out: | |||||
1022 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
1023 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
1024 | ||||||
1025 | return ret; | |||||
1026 | } | |||||
1027 | ||||||
1028 | XvImage * | |||||
1029 | XvShmCreateImage( | |||||
1030 | Display *dpy, | |||||
1031 | XvPortID port, | |||||
1032 | int id, | |||||
1033 | char *data, | |||||
1034 | int width, | |||||
1035 | int height, | |||||
1036 | XShmSegmentInfo *shminfo) | |||||
1037 | { | |||||
1038 | XvImage *ret; | |||||
1039 | ||||||
1040 | ret = XvCreateImage(dpy, port, id, data, width, height); | |||||
1041 | ||||||
1042 | if (ret) | |||||
1043 | ret->obdata = (XPointer) shminfo; | |||||
1044 | ||||||
1045 | return ret; | |||||
1046 | } | |||||
1047 | ||||||
1048 | int | |||||
1049 | XvPutImage( | |||||
1050 | Display *dpy, | |||||
1051 | XvPortID port, | |||||
1052 | Drawable d, | |||||
1053 | GC gc, | |||||
1054 | XvImage *image, | |||||
1055 | int src_x, int src_y, | |||||
1056 | unsigned int src_w, unsigned int src_h, | |||||
1057 | int dest_x, int dest_y, | |||||
1058 | unsigned int dest_w, unsigned int dest_h) | |||||
1059 | { | |||||
1060 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
1061 | xvPutImageReq *req; | |||||
1062 | unsigned int len; | |||||
1063 | ||||||
1064 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
1065 | ||||||
1066 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
1067 | ||||||
1068 | FlushGC(dpy, gc)if ((gc)->dirty) _XFlushGCCache((dpy), (gc)); | |||||
1069 | ||||||
1070 | XvGetReq(PutImage, req)req = (xvPutImageReq *) _XGetRequest( dpy, (CARD8) info->codes ->major_opcode, 40); req->xvReqType = 18;; | |||||
1071 | ||||||
1072 | req->port = port; | |||||
1073 | req->drawable = d; | |||||
1074 | req->gc = gc->gid; | |||||
1075 | req->id = image->id; | |||||
1076 | req->src_x = src_x; | |||||
1077 | req->src_y = src_y; | |||||
1078 | req->src_w = src_w; | |||||
1079 | req->src_h = src_h; | |||||
1080 | req->drw_x = dest_x; | |||||
1081 | req->drw_y = dest_y; | |||||
1082 | req->drw_w = dest_w; | |||||
1083 | req->drw_h = dest_h; | |||||
1084 | req->width = image->width; | |||||
1085 | req->height = image->height; | |||||
1086 | ||||||
1087 | len = ((unsigned int) image->data_size + 3) >> 2; | |||||
1088 | SetReqLen(req, len, len)req->length += len; | |||||
1089 | ||||||
1090 | /* Yes it's kindof lame that we are sending the whole thing, | |||||
1091 | but for video all of it may be needed even if displaying | |||||
1092 | only a subsection, and I don't want to go through the | |||||
1093 | trouble of creating subregions to send */ | |||||
1094 | Data(dpy, (char *) image->data, image->data_size){ if (dpy->bufptr + (image->data_size) <= dpy->bufmax ) { __builtin___memcpy_chk (dpy->bufptr, (char *) image-> data, (int)image->data_size, __builtin_object_size (dpy-> bufptr, 0)); dpy->bufptr += ((image->data_size) + 3) & ~3; } else _XSend(dpy, (char *) image->data, image->data_size );}; | |||||
1095 | ||||||
1096 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
1097 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
1098 | ||||||
1099 | return Success0; | |||||
1100 | } | |||||
1101 | ||||||
1102 | int | |||||
1103 | XvShmPutImage( | |||||
1104 | Display *dpy, | |||||
1105 | XvPortID port, | |||||
1106 | Drawable d, | |||||
1107 | GC gc, | |||||
1108 | XvImage *image, | |||||
1109 | int src_x, int src_y, | |||||
1110 | unsigned int src_w, unsigned int src_h, | |||||
1111 | int dest_x, int dest_y, | |||||
1112 | unsigned int dest_w, unsigned int dest_h, | |||||
1113 | Boolint send_event) | |||||
1114 | { | |||||
1115 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
1116 | XShmSegmentInfo *shminfo = (XShmSegmentInfo *) image->obdata; | |||||
1117 | xvShmPutImageReq *req; | |||||
1118 | ||||||
1119 | XvCheckExtension(dpy, info, XvBadExtension)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 1; }; | |||||
1120 | ||||||
1121 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
1122 | ||||||
1123 | FlushGC(dpy, gc)if ((gc)->dirty) _XFlushGCCache((dpy), (gc)); | |||||
1124 | ||||||
1125 | XvGetReq(ShmPutImage, req)req = (xvShmPutImageReq *) _XGetRequest( dpy, (CARD8) info-> codes->major_opcode, 52); req->xvReqType = 19;; | |||||
1126 | ||||||
1127 | req->port = port; | |||||
1128 | req->drawable = d; | |||||
1129 | req->gc = gc->gid; | |||||
1130 | req->shmseg = shminfo->shmseg; | |||||
1131 | req->id = image->id; | |||||
1132 | req->src_x = src_x; | |||||
1133 | req->src_y = src_y; | |||||
1134 | req->src_w = src_w; | |||||
1135 | req->src_h = src_h; | |||||
1136 | req->drw_x = dest_x; | |||||
1137 | req->drw_y = dest_y; | |||||
1138 | req->drw_w = dest_w; | |||||
1139 | req->drw_h = dest_h; | |||||
1140 | req->offset = image->data - shminfo->shmaddr; | |||||
1141 | req->width = image->width; | |||||
1142 | req->height = image->height; | |||||
1143 | req->send_event = send_event; | |||||
1144 | ||||||
1145 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
1146 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||||
1147 | ||||||
1148 | return Success0; | |||||
1149 | } | |||||
1150 | ||||||
1151 | ||||||
1152 | static Boolint | |||||
1153 | xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) | |||||
1154 | { | |||||
1155 | XExtDisplayInfo *info = xv_find_display(dpy); | |||||
1156 | XvEvent *re = (XvEvent *) host; | |||||
1157 | xvEvent *event = (xvEvent *) wire; | |||||
1158 | ||||||
1159 | XvCheckExtension(dpy, info, False)if (!((info) && ((info)->codes))) { XMissingExtension (dpy, xv_extension_name); return 0; }; | |||||
1160 | ||||||
1161 | switch ((event->u.u.type & 0x7F) - info->codes->first_event) { | |||||
1162 | case XvVideoNotify0: | |||||
1163 | re->xvvideo.type = event->u.u.type & 0x7f; | |||||
1164 | re->xvvideo.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); | |||||
1165 | re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); | |||||
1166 | re->xvvideo.display = dpy; | |||||
1167 | re->xvvideo.time = event->u.videoNotify.time; | |||||
1168 | re->xvvideo.reason = event->u.videoNotify.reason; | |||||
1169 | re->xvvideo.drawable = event->u.videoNotify.drawable; | |||||
1170 | re->xvvideo.port_id = event->u.videoNotify.port; | |||||
1171 | break; | |||||
1172 | case XvPortNotify1: | |||||
1173 | re->xvport.type = event->u.u.type & 0x7f; | |||||
1174 | re->xvport.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); | |||||
1175 | re->xvport.send_event = ((event->u.u.type & 0x80) != 0); | |||||
1176 | re->xvport.display = dpy; | |||||
1177 | re->xvport.time = event->u.portNotify.time; | |||||
1178 | re->xvport.port_id = event->u.portNotify.port; | |||||
1179 | re->xvport.attribute = event->u.portNotify.attribute; | |||||
1180 | re->xvport.value = event->u.portNotify.value; | |||||
1181 | break; | |||||
1182 | default: | |||||
1183 | return False0; | |||||
1184 | } | |||||
1185 | ||||||
1186 | return (True1); | |||||
1187 | } |