| 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 | } |