XvMC.c revision cc1b55f9
16f03b1f6Smrg#ifdef HAVE_CONFIG_H 26f03b1f6Smrg#include <config.h> 36f03b1f6Smrg#endif 46f03b1f6Smrg#include <stdio.h> 56f03b1f6Smrg#include "XvMClibint.h" 642941e3bSmrg#ifdef HAVE_SHMAT 76f03b1f6Smrg#ifndef Lynx 86f03b1f6Smrg#include <sys/ipc.h> 96f03b1f6Smrg#include <sys/shm.h> 106f03b1f6Smrg#else 116f03b1f6Smrg#include <ipc.h> 126f03b1f6Smrg#include <shm.h> 136f03b1f6Smrg#endif /* Lynx */ 1442941e3bSmrg#endif /* HAVE_SHMAT */ 156f03b1f6Smrg#include <unistd.h> 166f03b1f6Smrg#include <sys/time.h> 176f03b1f6Smrg#include <X11/extensions/Xext.h> 186f03b1f6Smrg#include <X11/extensions/extutil.h> 19190694daSmrg#include <limits.h> 206f03b1f6Smrg 21cc1b55f9Smrg#ifndef HAVE__XEATDATAWORDS 22cc1b55f9Smrgstatic inline void _XEatDataWords(Display *dpy, unsigned long n) 23cc1b55f9Smrg{ 24cc1b55f9Smrg# ifndef LONG64 25cc1b55f9Smrg if (n >= (ULONG_MAX >> 2)) 26cc1b55f9Smrg _XIOError(dpy); 27cc1b55f9Smrg# endif 28cc1b55f9Smrg _XEatData (dpy, n << 2); 29cc1b55f9Smrg} 30cc1b55f9Smrg#endif 31cc1b55f9Smrg 326f03b1f6Smrgstatic XExtensionInfo _xvmc_info_data; 336f03b1f6Smrgstatic XExtensionInfo *xvmc_info = &_xvmc_info_data; 3442941e3bSmrgstatic const char *xvmc_extension_name = XvMCName; 356f03b1f6Smrg 3642941e3bSmrgstatic const char *xvmc_error_list[] = 376f03b1f6Smrg{ 386f03b1f6Smrg "BadContext", 396f03b1f6Smrg "BadSurface", 406f03b1f6Smrg "BadSubpicture" 416f03b1f6Smrg}; 426f03b1f6Smrg 436f03b1f6Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY (xvmc_close_display, xvmc_info) 446f03b1f6Smrg 456f03b1f6Smrg 466f03b1f6Smrgstatic XEXT_GENERATE_ERROR_STRING (xvmc_error_string, xvmc_extension_name, 476f03b1f6Smrg XvMCNumErrors, xvmc_error_list) 486f03b1f6Smrg 496f03b1f6Smrg 506f03b1f6Smrgstatic XExtensionHooks xvmc_extension_hooks = { 516f03b1f6Smrg NULL, /* create_gc */ 526f03b1f6Smrg NULL, /* copy_gc */ 536f03b1f6Smrg NULL, /* flush_gc */ 546f03b1f6Smrg NULL, /* free_gc */ 556f03b1f6Smrg NULL, /* create_font */ 566f03b1f6Smrg NULL, /* free_font */ 576f03b1f6Smrg xvmc_close_display, /* close_display */ 586f03b1f6Smrg NULL, /* wire_to_event */ 596f03b1f6Smrg NULL, /* event_to_wire */ 606f03b1f6Smrg NULL, /* error */ 616f03b1f6Smrg xvmc_error_string /* error_string */ 626f03b1f6Smrg}; 636f03b1f6Smrg 646f03b1f6Smrgstatic XEXT_GENERATE_FIND_DISPLAY (xvmc_find_display, xvmc_info, 656f03b1f6Smrg xvmc_extension_name, 666f03b1f6Smrg &xvmc_extension_hooks, 676f03b1f6Smrg XvMCNumEvents, NULL) 686f03b1f6Smrg 696f03b1f6SmrgBool XvMCQueryExtension (Display *dpy, int *event_basep, int *error_basep) 706f03b1f6Smrg{ 716f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 726f03b1f6Smrg 736f03b1f6Smrg if (XextHasExtension(info)) { 746f03b1f6Smrg *event_basep = info->codes->first_event; 756f03b1f6Smrg *error_basep = info->codes->first_error; 766f03b1f6Smrg return True; 776f03b1f6Smrg } else { 786f03b1f6Smrg return False; 796f03b1f6Smrg } 806f03b1f6Smrg} 816f03b1f6Smrg 826f03b1f6SmrgStatus XvMCQueryVersion (Display *dpy, int *major, int *minor) 836f03b1f6Smrg{ 846f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 856f03b1f6Smrg xvmcQueryVersionReply rep; 866f03b1f6Smrg xvmcQueryVersionReq *req; 876f03b1f6Smrg 886f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 896f03b1f6Smrg 906f03b1f6Smrg LockDisplay (dpy); 916f03b1f6Smrg XvMCGetReq (QueryVersion, req); 926f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 936f03b1f6Smrg UnlockDisplay (dpy); 946f03b1f6Smrg SyncHandle (); 956f03b1f6Smrg return BadImplementation; 966f03b1f6Smrg } 976f03b1f6Smrg *major = rep.major; 986f03b1f6Smrg *minor = rep.minor; 996f03b1f6Smrg UnlockDisplay (dpy); 1006f03b1f6Smrg SyncHandle (); 1016f03b1f6Smrg return Success; 1026f03b1f6Smrg} 1036f03b1f6Smrg 1046f03b1f6Smrg 1056f03b1f6SmrgXvMCSurfaceInfo * XvMCListSurfaceTypes(Display *dpy, XvPortID port, int *num) 1066f03b1f6Smrg{ 1076f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 1086f03b1f6Smrg xvmcListSurfaceTypesReply rep; 1096f03b1f6Smrg xvmcListSurfaceTypesReq *req; 1106f03b1f6Smrg XvMCSurfaceInfo *surface_info = NULL; 1116f03b1f6Smrg 1126f03b1f6Smrg *num = 0; 1136f03b1f6Smrg 1146f03b1f6Smrg XvMCCheckExtension (dpy, info, NULL); 11542941e3bSmrg 1166f03b1f6Smrg LockDisplay (dpy); 1176f03b1f6Smrg XvMCGetReq (ListSurfaceTypes, req); 1186f03b1f6Smrg req->port = port; 1196f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 1206f03b1f6Smrg UnlockDisplay (dpy); 1216f03b1f6Smrg SyncHandle (); 1226f03b1f6Smrg return NULL; 1236f03b1f6Smrg } 1246f03b1f6Smrg 1256f03b1f6Smrg if(rep.num > 0) { 126190694daSmrg if (rep.num < (INT_MAX / sizeof(XvMCSurfaceInfo))) 127190694daSmrg surface_info = Xmalloc(rep.num * sizeof(XvMCSurfaceInfo)); 1286f03b1f6Smrg 1296f03b1f6Smrg if(surface_info) { 1306f03b1f6Smrg xvmcSurfaceInfo sinfo; 1316f03b1f6Smrg int i; 1326f03b1f6Smrg 1336f03b1f6Smrg *num = rep.num; 1346f03b1f6Smrg 1356f03b1f6Smrg for(i = 0; i < rep.num; i++) { 1366f03b1f6Smrg _XRead(dpy, (char*)&sinfo, sizeof(xvmcSurfaceInfo)); 1376f03b1f6Smrg surface_info[i].surface_type_id = sinfo.surface_type_id; 1386f03b1f6Smrg surface_info[i].chroma_format = sinfo.chroma_format; 1396f03b1f6Smrg surface_info[i].max_width = sinfo.max_width; 1406f03b1f6Smrg surface_info[i].max_height = sinfo.max_height; 14142941e3bSmrg surface_info[i].subpicture_max_width = 1426f03b1f6Smrg sinfo.subpicture_max_width; 14342941e3bSmrg surface_info[i].subpicture_max_height = 1446f03b1f6Smrg sinfo.subpicture_max_height; 1456f03b1f6Smrg surface_info[i].mc_type = sinfo.mc_type; 1466f03b1f6Smrg surface_info[i].flags = sinfo.flags; 1476f03b1f6Smrg } 1486f03b1f6Smrg } else 149cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 1506f03b1f6Smrg } 1516f03b1f6Smrg 1526f03b1f6Smrg UnlockDisplay (dpy); 1536f03b1f6Smrg SyncHandle (); 1546f03b1f6Smrg return surface_info; 1556f03b1f6Smrg} 1566f03b1f6Smrg 1576f03b1f6Smrg 1586f03b1f6SmrgXvImageFormatValues * XvMCListSubpictureTypes ( 1596f03b1f6Smrg Display * dpy, 1606f03b1f6Smrg XvPortID port, 1616f03b1f6Smrg int surface_type_id, 1626f03b1f6Smrg int *count_return 1636f03b1f6Smrg) 1646f03b1f6Smrg{ 1656f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 1666f03b1f6Smrg xvmcListSubpictureTypesReply rep; 1676f03b1f6Smrg xvmcListSubpictureTypesReq *req; 1686f03b1f6Smrg XvImageFormatValues *ret = NULL; 1696f03b1f6Smrg 1706f03b1f6Smrg 1716f03b1f6Smrg *count_return = 0; 1726f03b1f6Smrg 1736f03b1f6Smrg XvMCCheckExtension (dpy, info, NULL); 1746f03b1f6Smrg 1756f03b1f6Smrg 1766f03b1f6Smrg LockDisplay (dpy); 1776f03b1f6Smrg XvMCGetReq (ListSubpictureTypes, req); 1786f03b1f6Smrg req->port = port; 1796f03b1f6Smrg req->surface_type_id = surface_type_id; 1806f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 1816f03b1f6Smrg UnlockDisplay (dpy); 1826f03b1f6Smrg SyncHandle (); 1836f03b1f6Smrg return NULL; 1846f03b1f6Smrg } 1856f03b1f6Smrg 1866f03b1f6Smrg if(rep.num > 0) { 187190694daSmrg if (rep.num < (INT_MAX / sizeof(XvImageFormatValues))) 188190694daSmrg ret = Xmalloc(rep.num * sizeof(XvImageFormatValues)); 1896f03b1f6Smrg 1906f03b1f6Smrg if(ret) { 1916f03b1f6Smrg xvImageFormatInfo Info; 1926f03b1f6Smrg int i; 1936f03b1f6Smrg 1946f03b1f6Smrg *count_return = rep.num; 1956f03b1f6Smrg 1966f03b1f6Smrg for(i = 0; i < rep.num; i++) { 1976f03b1f6Smrg _XRead(dpy, (char*)(&Info), sz_xvImageFormatInfo); 19842941e3bSmrg ret[i].id = Info.id; 19942941e3bSmrg ret[i].type = Info.type; 20042941e3bSmrg ret[i].byte_order = Info.byte_order; 2016f03b1f6Smrg memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); 20242941e3bSmrg ret[i].bits_per_pixel = Info.bpp; 20342941e3bSmrg ret[i].format = Info.format; 20442941e3bSmrg ret[i].num_planes = Info.num_planes; 20542941e3bSmrg ret[i].depth = Info.depth; 20642941e3bSmrg ret[i].red_mask = Info.red_mask; 20742941e3bSmrg ret[i].green_mask = Info.green_mask; 20842941e3bSmrg ret[i].blue_mask = Info.blue_mask; 20942941e3bSmrg ret[i].y_sample_bits = Info.y_sample_bits; 21042941e3bSmrg ret[i].u_sample_bits = Info.u_sample_bits; 2116f03b1f6Smrg ret[i].v_sample_bits = Info.v_sample_bits; 2126f03b1f6Smrg ret[i].horz_y_period = Info.horz_y_period; 2136f03b1f6Smrg ret[i].horz_u_period = Info.horz_u_period; 2146f03b1f6Smrg ret[i].horz_v_period = Info.horz_v_period; 2156f03b1f6Smrg ret[i].vert_y_period = Info.vert_y_period; 2166f03b1f6Smrg ret[i].vert_u_period = Info.vert_u_period; 2176f03b1f6Smrg ret[i].vert_v_period = Info.vert_v_period; 2186f03b1f6Smrg memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); 2196f03b1f6Smrg ret[i].scanline_order = Info.scanline_order; 2206f03b1f6Smrg } 2216f03b1f6Smrg } else 222cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 2236f03b1f6Smrg } 2246f03b1f6Smrg 2256f03b1f6Smrg UnlockDisplay (dpy); 2266f03b1f6Smrg SyncHandle (); 22742941e3bSmrg return ret; 2286f03b1f6Smrg} 2296f03b1f6Smrg 2306f03b1f6Smrg 23142941e3bSmrg/****************************************************************** 2326f03b1f6Smrg These are intended as a protocol interface to be used by direct 2336f03b1f6Smrg rendering libraries. They are not intended to be client viewable 2346f03b1f6Smrg functions. These will stay in place until we have a mechanism in 2356f03b1f6Smrg place similar to that of OpenGL with an libXvMCcore library. 23642941e3bSmrg*******************************************************************/ 23742941e3bSmrg 23842941e3bSmrg/* 2396f03b1f6Smrg _xvmc_create_context - 2406f03b1f6Smrg 2416f03b1f6Smrg Pass in the context with the surface_type_id, width, height, 2426f03b1f6Smrg port and flags filled out. This function will fill out the 2436f03b1f6Smrg context_id and update the width, height and flags field. 2446f03b1f6Smrg The server may return implementation-specific information 2456f03b1f6Smrg back in the priv_data. The size of that information will 2466f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 2476f03b1f6Smrg this function. If returned, the caller is responsible for 2486f03b1f6Smrg freeing it! Generally, such information is only returned if 24942941e3bSmrg an XVMC_DIRECT context was specified. 2506f03b1f6Smrg*/ 2516f03b1f6Smrg 2526f03b1f6Smrg 2536f03b1f6SmrgStatus _xvmc_create_context ( 2546f03b1f6Smrg Display *dpy, 2556f03b1f6Smrg XvMCContext *context, 2566f03b1f6Smrg int *priv_count, 2576f03b1f6Smrg CARD32 **priv_data 2586f03b1f6Smrg) 2596f03b1f6Smrg{ 2606f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 2616f03b1f6Smrg xvmcCreateContextReply rep; 2626f03b1f6Smrg xvmcCreateContextReq *req; 2636f03b1f6Smrg 2646f03b1f6Smrg *priv_count = 0; 2656f03b1f6Smrg *priv_data = NULL; 2666f03b1f6Smrg 2676f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 2686f03b1f6Smrg 2696f03b1f6Smrg LockDisplay (dpy); 2706f03b1f6Smrg XvMCGetReq (CreateContext, req); 2716f03b1f6Smrg context->context_id = XAllocID(dpy); 2726f03b1f6Smrg req->context_id = context->context_id; 2736f03b1f6Smrg req->port = context->port; 2746f03b1f6Smrg req->surface_type_id = context->surface_type_id; 2756f03b1f6Smrg req->width = context->width; 2766f03b1f6Smrg req->height = context->height; 2776f03b1f6Smrg req->flags = context->flags; 2786f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 2796f03b1f6Smrg UnlockDisplay (dpy); 2806f03b1f6Smrg SyncHandle (); 2816f03b1f6Smrg return BadImplementation; 2826f03b1f6Smrg } 2836f03b1f6Smrg context->width = rep.width_actual; 2846f03b1f6Smrg context->height = rep.height_actual; 2856f03b1f6Smrg context->flags = rep.flags_return; 2866f03b1f6Smrg 2876f03b1f6Smrg if(rep.length) { 288cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 289cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 2906f03b1f6Smrg if(*priv_data) { 2916f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 2926f03b1f6Smrg *priv_count = rep.length; 2936f03b1f6Smrg } else 294cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 2956f03b1f6Smrg } 2966f03b1f6Smrg 2976f03b1f6Smrg UnlockDisplay (dpy); 2986f03b1f6Smrg SyncHandle (); 2996f03b1f6Smrg return Success; 3006f03b1f6Smrg} 3016f03b1f6Smrg 3026f03b1f6SmrgStatus _xvmc_destroy_context ( 3036f03b1f6Smrg Display *dpy, 3046f03b1f6Smrg XvMCContext *context 3056f03b1f6Smrg) 3066f03b1f6Smrg{ 3076f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3086f03b1f6Smrg xvmcDestroyContextReq *req; 3096f03b1f6Smrg 3106f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3116f03b1f6Smrg 3126f03b1f6Smrg LockDisplay (dpy); 3136f03b1f6Smrg XvMCGetReq (DestroyContext, req); 3146f03b1f6Smrg req->context_id = context->context_id; 3156f03b1f6Smrg UnlockDisplay (dpy); 3166f03b1f6Smrg SyncHandle (); 3176f03b1f6Smrg return Success; 3186f03b1f6Smrg} 3196f03b1f6Smrg 3206f03b1f6Smrg 3216f03b1f6Smrg/* 3226f03b1f6Smrg _xvmc_create_surface - 3236f03b1f6Smrg 3246f03b1f6Smrg Pass the context and this function will fill out all the 32542941e3bSmrg information in the surface. 3266f03b1f6Smrg The server may return implementation-specific information 3276f03b1f6Smrg back in the priv_data. The size of that information will 3286f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 3296f03b1f6Smrg this function. If returned, the caller is responsible for 3306f03b1f6Smrg freeing it! Generally, such information is returned only if 3316f03b1f6Smrg the context was a direct context. 33242941e3bSmrg 3336f03b1f6Smrg*/ 3346f03b1f6Smrg 3356f03b1f6SmrgStatus _xvmc_create_surface ( 3366f03b1f6Smrg Display *dpy, 3376f03b1f6Smrg XvMCContext *context, 3386f03b1f6Smrg XvMCSurface *surface, 3396f03b1f6Smrg int *priv_count, 3406f03b1f6Smrg CARD32 **priv_data 3416f03b1f6Smrg) 3426f03b1f6Smrg{ 3436f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3446f03b1f6Smrg xvmcCreateSurfaceReply rep; 3456f03b1f6Smrg xvmcCreateSurfaceReq *req; 3466f03b1f6Smrg 3476f03b1f6Smrg *priv_count = 0; 3486f03b1f6Smrg *priv_data = NULL; 3496f03b1f6Smrg 3506f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3516f03b1f6Smrg 3526f03b1f6Smrg LockDisplay (dpy); 3536f03b1f6Smrg XvMCGetReq (CreateSurface, req); 3546f03b1f6Smrg 3556f03b1f6Smrg surface->surface_id = XAllocID(dpy); 3566f03b1f6Smrg surface->context_id = context->context_id; 3576f03b1f6Smrg surface->surface_type_id = context->surface_type_id; 3586f03b1f6Smrg surface->width = context->width; 3596f03b1f6Smrg surface->height = context->height; 3606f03b1f6Smrg 3616f03b1f6Smrg req->surface_id = surface->surface_id; 3626f03b1f6Smrg req->context_id = surface->context_id; 3636f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 3646f03b1f6Smrg UnlockDisplay (dpy); 3656f03b1f6Smrg SyncHandle (); 3666f03b1f6Smrg return BadImplementation; 3676f03b1f6Smrg } 3686f03b1f6Smrg 3696f03b1f6Smrg if(rep.length) { 370cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 371cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 3726f03b1f6Smrg if(*priv_data) { 3736f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 3746f03b1f6Smrg *priv_count = rep.length; 3756f03b1f6Smrg } else 376cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 3776f03b1f6Smrg } 3786f03b1f6Smrg 3796f03b1f6Smrg UnlockDisplay (dpy); 3806f03b1f6Smrg SyncHandle (); 3816f03b1f6Smrg return Success; 3826f03b1f6Smrg} 3836f03b1f6Smrg 3846f03b1f6SmrgStatus _xvmc_destroy_surface ( 3856f03b1f6Smrg Display *dpy, 3866f03b1f6Smrg XvMCSurface *surface 3876f03b1f6Smrg) 3886f03b1f6Smrg{ 3896f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3906f03b1f6Smrg xvmcDestroySurfaceReq *req; 3916f03b1f6Smrg 3926f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3936f03b1f6Smrg 3946f03b1f6Smrg LockDisplay (dpy); 3956f03b1f6Smrg XvMCGetReq (DestroySurface, req); 3966f03b1f6Smrg req->surface_id = surface->surface_id; 3976f03b1f6Smrg UnlockDisplay (dpy); 3986f03b1f6Smrg SyncHandle (); 3996f03b1f6Smrg return Success; 4006f03b1f6Smrg} 4016f03b1f6Smrg 4026f03b1f6Smrg/* 4036f03b1f6Smrg _xvmc_create_subpicture - 4046f03b1f6Smrg 4056f03b1f6Smrg Pass the subpicture with the width, height and xvimage_id filled 4066f03b1f6Smrg out and this function will fill out everything else in the 4076f03b1f6Smrg subpicture as well as adjust the width and height if needed. 4086f03b1f6Smrg The server may return implementation-specific information 4096f03b1f6Smrg back in the priv_data. The size of that information will 4106f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 4116f03b1f6Smrg this function. If returned, the caller is responsible for 4126f03b1f6Smrg freeing it! Generally, such information is returned only if 4136f03b1f6Smrg the context was a direct context. 4146f03b1f6Smrg 4156f03b1f6Smrg*/ 4166f03b1f6Smrg 4176f03b1f6SmrgStatus _xvmc_create_subpicture ( 4186f03b1f6Smrg Display *dpy, 4196f03b1f6Smrg XvMCContext *context, 4206f03b1f6Smrg XvMCSubpicture *subpicture, 4216f03b1f6Smrg int *priv_count, 4226f03b1f6Smrg CARD32 **priv_data 4236f03b1f6Smrg) 4246f03b1f6Smrg{ 4256f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4266f03b1f6Smrg xvmcCreateSubpictureReply rep; 4276f03b1f6Smrg xvmcCreateSubpictureReq *req; 4286f03b1f6Smrg 4296f03b1f6Smrg *priv_count = 0; 4306f03b1f6Smrg *priv_data = NULL; 4316f03b1f6Smrg 4326f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 4336f03b1f6Smrg 4346f03b1f6Smrg LockDisplay (dpy); 4356f03b1f6Smrg XvMCGetReq (CreateSubpicture, req); 4366f03b1f6Smrg 4376f03b1f6Smrg subpicture->subpicture_id = XAllocID(dpy); 4386f03b1f6Smrg subpicture->context_id = context->context_id; 4396f03b1f6Smrg 4406f03b1f6Smrg req->subpicture_id = subpicture->subpicture_id; 4416f03b1f6Smrg req->context_id = subpicture->context_id; 4426f03b1f6Smrg req->xvimage_id = subpicture->xvimage_id; 4436f03b1f6Smrg req->width = subpicture->width; 4446f03b1f6Smrg req->height = subpicture->height; 4456f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 4466f03b1f6Smrg UnlockDisplay (dpy); 4476f03b1f6Smrg SyncHandle (); 4486f03b1f6Smrg return BadImplementation; 4496f03b1f6Smrg } 4506f03b1f6Smrg 4516f03b1f6Smrg subpicture->width = rep.width_actual; 4526f03b1f6Smrg subpicture->height = rep.height_actual; 4536f03b1f6Smrg subpicture->num_palette_entries = rep.num_palette_entries; 4546f03b1f6Smrg subpicture->entry_bytes = rep.entry_bytes; 4556f03b1f6Smrg subpicture->component_order[0] = rep.component_order[0]; 4566f03b1f6Smrg subpicture->component_order[1] = rep.component_order[1]; 4576f03b1f6Smrg subpicture->component_order[2] = rep.component_order[2]; 4586f03b1f6Smrg subpicture->component_order[3] = rep.component_order[3]; 4596f03b1f6Smrg 4606f03b1f6Smrg if(rep.length) { 461cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 462cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 4636f03b1f6Smrg if(*priv_data) { 4646f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 4656f03b1f6Smrg *priv_count = rep.length; 4666f03b1f6Smrg } else 467cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 4686f03b1f6Smrg } 4696f03b1f6Smrg 4706f03b1f6Smrg UnlockDisplay (dpy); 4716f03b1f6Smrg SyncHandle (); 4726f03b1f6Smrg return Success; 4736f03b1f6Smrg} 4746f03b1f6Smrg 4756f03b1f6SmrgStatus _xvmc_destroy_subpicture( 4766f03b1f6Smrg Display *dpy, 4776f03b1f6Smrg XvMCSubpicture *subpicture 4786f03b1f6Smrg) 4796f03b1f6Smrg{ 4806f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4816f03b1f6Smrg xvmcDestroySubpictureReq *req; 4826f03b1f6Smrg 4836f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 4846f03b1f6Smrg 4856f03b1f6Smrg LockDisplay (dpy); 4866f03b1f6Smrg XvMCGetReq (DestroySubpicture, req); 48742941e3bSmrg req->subpicture_id = subpicture->subpicture_id; 4886f03b1f6Smrg UnlockDisplay (dpy); 4896f03b1f6Smrg SyncHandle (); 4906f03b1f6Smrg return Success; 4916f03b1f6Smrg} 4926f03b1f6Smrg 4936f03b1f6SmrgStatus XvMCGetDRInfo(Display *dpy, XvPortID port, 49442941e3bSmrg char **name, char **busID, 49542941e3bSmrg int *major, int *minor, 4966f03b1f6Smrg int *patchLevel, 4976f03b1f6Smrg int *isLocal) 4986f03b1f6Smrg{ 4996f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 5006f03b1f6Smrg xvmcGetDRInfoReply rep; 5016f03b1f6Smrg xvmcGetDRInfoReq *req; 5026f03b1f6Smrg CARD32 magic; 5036f03b1f6Smrg 50442941e3bSmrg#ifdef HAVE_SHMAT 5056f03b1f6Smrg volatile CARD32 *shMem; 5066f03b1f6Smrg struct timezone here; 5076f03b1f6Smrg struct timeval now; 5086f03b1f6Smrg here.tz_minuteswest = 0; 5096f03b1f6Smrg here.tz_dsttime = 0; 5106f03b1f6Smrg#endif 5116f03b1f6Smrg 512190694daSmrg *name = NULL; 513190694daSmrg *busID = NULL; 514190694daSmrg 5156f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 5166f03b1f6Smrg 5176f03b1f6Smrg LockDisplay (dpy); 5186f03b1f6Smrg XvMCGetReq (GetDRInfo, req); 5196f03b1f6Smrg 5206f03b1f6Smrg req->port = port; 5216f03b1f6Smrg magic = 0; 5226f03b1f6Smrg req->magic = 0; 52342941e3bSmrg#ifdef HAVE_SHMAT 5246f03b1f6Smrg req->shmKey = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0600); 5256f03b1f6Smrg 5266f03b1f6Smrg /* 5276f03b1f6Smrg * We fill a shared memory page with a repetitive pattern. If the 5286f03b1f6Smrg * X server can read this pattern, we probably have a local connection. 5296f03b1f6Smrg * Note that we can trigger the remote X server to read any shared 5306f03b1f6Smrg * page on the remote machine, so we shouldn't be able to guess and verify 5316f03b1f6Smrg * any complicated data on those pages. Thats the explanation of this 5326f03b1f6Smrg * otherwise stupid-looking pattern algorithm. 5336f03b1f6Smrg */ 53442941e3bSmrg 5356f03b1f6Smrg if (req->shmKey >= 0) { 5366f03b1f6Smrg shMem = (CARD32 *) shmat(req->shmKey, NULL, 0); 5376f03b1f6Smrg shmctl( req->shmKey, IPC_RMID, NULL); 53842941e3bSmrg if ( shMem ) { 5396f03b1f6Smrg 5406f03b1f6Smrg register volatile CARD32 *shMemC = shMem; 5416f03b1f6Smrg register int i; 5426f03b1f6Smrg 5436f03b1f6Smrg gettimeofday( &now, &here); 5446f03b1f6Smrg magic = now.tv_usec & 0x000FFFFF; 5456f03b1f6Smrg req->magic = magic; 5466f03b1f6Smrg i = 1024 / sizeof(CARD32); 5476f03b1f6Smrg while(i--) { 54842941e3bSmrg *shMemC++ = magic; 5496f03b1f6Smrg magic = ~magic; 5506f03b1f6Smrg } 5516f03b1f6Smrg } else { 5526f03b1f6Smrg req->shmKey = -1; 5536f03b1f6Smrg } 5546f03b1f6Smrg } 5556f03b1f6Smrg#else 5566f03b1f6Smrg req->shmKey = 0; 5576f03b1f6Smrg#endif 5586f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 5596f03b1f6Smrg UnlockDisplay (dpy); 5606f03b1f6Smrg SyncHandle (); 56142941e3bSmrg#ifdef HAVE_SHMAT 5626f03b1f6Smrg if ( req->shmKey >= 0) { 5636f03b1f6Smrg shmdt( (const void *) shMem ); 56442941e3bSmrg } 5656f03b1f6Smrg#endif 5666f03b1f6Smrg return -1; 5676f03b1f6Smrg } 56842941e3bSmrg#ifdef HAVE_SHMAT 5696f03b1f6Smrg shmdt( (const void *) shMem ); 5706f03b1f6Smrg#endif 5716f03b1f6Smrg 5726f03b1f6Smrg if (rep.length > 0) { 573190694daSmrg unsigned long realSize = 0; 574190694daSmrg char *tmpBuf = NULL; 575190694daSmrg 576cc1b55f9Smrg if ((rep.length < (INT_MAX >> 2)) && 577cc1b55f9Smrg /* protect against overflow in strncpy below */ 578cc1b55f9Smrg (rep.nameLen + rep.busIDLen > rep.nameLen)) { 579190694daSmrg realSize = rep.length << 2; 580190694daSmrg if (realSize >= (rep.nameLen + rep.busIDLen)) { 581190694daSmrg tmpBuf = Xmalloc(realSize); 582190694daSmrg *name = Xmalloc(rep.nameLen); 583190694daSmrg *busID = Xmalloc(rep.busIDLen); 58442941e3bSmrg } 5856f03b1f6Smrg } 5866f03b1f6Smrg 5876f03b1f6Smrg if (*name && *busID && tmpBuf) { 5886f03b1f6Smrg _XRead(dpy, tmpBuf, realSize); 5896f03b1f6Smrg strncpy(*name,tmpBuf,rep.nameLen); 590cc1b55f9Smrg (*name)[rep.nameLen - 1] = '\0'; 5916f03b1f6Smrg strncpy(*busID,tmpBuf+rep.nameLen,rep.busIDLen); 592cc1b55f9Smrg (*busID)[rep.busIDLen - 1] = '\0'; 5936f03b1f6Smrg XFree(tmpBuf); 5946f03b1f6Smrg } else { 595190694daSmrg XFree(*name); 596190694daSmrg *name = NULL; 597190694daSmrg XFree(*busID); 598cc1b55f9Smrg *busID = NULL; 599190694daSmrg XFree(tmpBuf); 6006f03b1f6Smrg 601cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 6026f03b1f6Smrg UnlockDisplay (dpy); 6036f03b1f6Smrg SyncHandle (); 6046f03b1f6Smrg return -1; 6056f03b1f6Smrg 6066f03b1f6Smrg } 6076f03b1f6Smrg } 6086f03b1f6Smrg 6096f03b1f6Smrg UnlockDisplay (dpy); 6106f03b1f6Smrg SyncHandle (); 6116f03b1f6Smrg *major = rep.major; 6126f03b1f6Smrg *minor = rep.minor; 6136f03b1f6Smrg *patchLevel = rep.patchLevel; 6146f03b1f6Smrg *isLocal = (req->shmKey > 0) ? rep.isLocal : 1; 6156f03b1f6Smrg return (rep.length > 0) ? Success : BadImplementation; 6166f03b1f6Smrg} 6176f03b1f6Smrg 618