XvMC.c revision 190694da
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 216f03b1f6Smrgstatic XExtensionInfo _xvmc_info_data; 226f03b1f6Smrgstatic XExtensionInfo *xvmc_info = &_xvmc_info_data; 2342941e3bSmrgstatic const char *xvmc_extension_name = XvMCName; 246f03b1f6Smrg 2542941e3bSmrgstatic const char *xvmc_error_list[] = 266f03b1f6Smrg{ 276f03b1f6Smrg "BadContext", 286f03b1f6Smrg "BadSurface", 296f03b1f6Smrg "BadSubpicture" 306f03b1f6Smrg}; 316f03b1f6Smrg 326f03b1f6Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY (xvmc_close_display, xvmc_info) 336f03b1f6Smrg 346f03b1f6Smrg 356f03b1f6Smrgstatic XEXT_GENERATE_ERROR_STRING (xvmc_error_string, xvmc_extension_name, 366f03b1f6Smrg XvMCNumErrors, xvmc_error_list) 376f03b1f6Smrg 386f03b1f6Smrg 396f03b1f6Smrgstatic XExtensionHooks xvmc_extension_hooks = { 406f03b1f6Smrg NULL, /* create_gc */ 416f03b1f6Smrg NULL, /* copy_gc */ 426f03b1f6Smrg NULL, /* flush_gc */ 436f03b1f6Smrg NULL, /* free_gc */ 446f03b1f6Smrg NULL, /* create_font */ 456f03b1f6Smrg NULL, /* free_font */ 466f03b1f6Smrg xvmc_close_display, /* close_display */ 476f03b1f6Smrg NULL, /* wire_to_event */ 486f03b1f6Smrg NULL, /* event_to_wire */ 496f03b1f6Smrg NULL, /* error */ 506f03b1f6Smrg xvmc_error_string /* error_string */ 516f03b1f6Smrg}; 526f03b1f6Smrg 536f03b1f6Smrgstatic XEXT_GENERATE_FIND_DISPLAY (xvmc_find_display, xvmc_info, 546f03b1f6Smrg xvmc_extension_name, 556f03b1f6Smrg &xvmc_extension_hooks, 566f03b1f6Smrg XvMCNumEvents, NULL) 576f03b1f6Smrg 586f03b1f6SmrgBool XvMCQueryExtension (Display *dpy, int *event_basep, int *error_basep) 596f03b1f6Smrg{ 606f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 616f03b1f6Smrg 626f03b1f6Smrg if (XextHasExtension(info)) { 636f03b1f6Smrg *event_basep = info->codes->first_event; 646f03b1f6Smrg *error_basep = info->codes->first_error; 656f03b1f6Smrg return True; 666f03b1f6Smrg } else { 676f03b1f6Smrg return False; 686f03b1f6Smrg } 696f03b1f6Smrg} 706f03b1f6Smrg 716f03b1f6SmrgStatus XvMCQueryVersion (Display *dpy, int *major, int *minor) 726f03b1f6Smrg{ 736f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 746f03b1f6Smrg xvmcQueryVersionReply rep; 756f03b1f6Smrg xvmcQueryVersionReq *req; 766f03b1f6Smrg 776f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 786f03b1f6Smrg 796f03b1f6Smrg LockDisplay (dpy); 806f03b1f6Smrg XvMCGetReq (QueryVersion, req); 816f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 826f03b1f6Smrg UnlockDisplay (dpy); 836f03b1f6Smrg SyncHandle (); 846f03b1f6Smrg return BadImplementation; 856f03b1f6Smrg } 866f03b1f6Smrg *major = rep.major; 876f03b1f6Smrg *minor = rep.minor; 886f03b1f6Smrg UnlockDisplay (dpy); 896f03b1f6Smrg SyncHandle (); 906f03b1f6Smrg return Success; 916f03b1f6Smrg} 926f03b1f6Smrg 936f03b1f6Smrg 946f03b1f6SmrgXvMCSurfaceInfo * XvMCListSurfaceTypes(Display *dpy, XvPortID port, int *num) 956f03b1f6Smrg{ 966f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 976f03b1f6Smrg xvmcListSurfaceTypesReply rep; 986f03b1f6Smrg xvmcListSurfaceTypesReq *req; 996f03b1f6Smrg XvMCSurfaceInfo *surface_info = NULL; 1006f03b1f6Smrg 1016f03b1f6Smrg *num = 0; 1026f03b1f6Smrg 1036f03b1f6Smrg XvMCCheckExtension (dpy, info, NULL); 10442941e3bSmrg 1056f03b1f6Smrg LockDisplay (dpy); 1066f03b1f6Smrg XvMCGetReq (ListSurfaceTypes, req); 1076f03b1f6Smrg req->port = port; 1086f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 1096f03b1f6Smrg UnlockDisplay (dpy); 1106f03b1f6Smrg SyncHandle (); 1116f03b1f6Smrg return NULL; 1126f03b1f6Smrg } 1136f03b1f6Smrg 1146f03b1f6Smrg if(rep.num > 0) { 115190694daSmrg if (rep.num < (INT_MAX / sizeof(XvMCSurfaceInfo))) 116190694daSmrg surface_info = Xmalloc(rep.num * sizeof(XvMCSurfaceInfo)); 1176f03b1f6Smrg 1186f03b1f6Smrg if(surface_info) { 1196f03b1f6Smrg xvmcSurfaceInfo sinfo; 1206f03b1f6Smrg int i; 1216f03b1f6Smrg 1226f03b1f6Smrg *num = rep.num; 1236f03b1f6Smrg 1246f03b1f6Smrg for(i = 0; i < rep.num; i++) { 1256f03b1f6Smrg _XRead(dpy, (char*)&sinfo, sizeof(xvmcSurfaceInfo)); 1266f03b1f6Smrg surface_info[i].surface_type_id = sinfo.surface_type_id; 1276f03b1f6Smrg surface_info[i].chroma_format = sinfo.chroma_format; 1286f03b1f6Smrg surface_info[i].max_width = sinfo.max_width; 1296f03b1f6Smrg surface_info[i].max_height = sinfo.max_height; 13042941e3bSmrg surface_info[i].subpicture_max_width = 1316f03b1f6Smrg sinfo.subpicture_max_width; 13242941e3bSmrg surface_info[i].subpicture_max_height = 1336f03b1f6Smrg sinfo.subpicture_max_height; 1346f03b1f6Smrg surface_info[i].mc_type = sinfo.mc_type; 1356f03b1f6Smrg surface_info[i].flags = sinfo.flags; 1366f03b1f6Smrg } 1376f03b1f6Smrg } else 1386f03b1f6Smrg _XEatData(dpy, rep.length << 2); 1396f03b1f6Smrg } 1406f03b1f6Smrg 1416f03b1f6Smrg UnlockDisplay (dpy); 1426f03b1f6Smrg SyncHandle (); 1436f03b1f6Smrg return surface_info; 1446f03b1f6Smrg} 1456f03b1f6Smrg 1466f03b1f6Smrg 1476f03b1f6SmrgXvImageFormatValues * XvMCListSubpictureTypes ( 1486f03b1f6Smrg Display * dpy, 1496f03b1f6Smrg XvPortID port, 1506f03b1f6Smrg int surface_type_id, 1516f03b1f6Smrg int *count_return 1526f03b1f6Smrg) 1536f03b1f6Smrg{ 1546f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 1556f03b1f6Smrg xvmcListSubpictureTypesReply rep; 1566f03b1f6Smrg xvmcListSubpictureTypesReq *req; 1576f03b1f6Smrg XvImageFormatValues *ret = NULL; 1586f03b1f6Smrg 1596f03b1f6Smrg 1606f03b1f6Smrg *count_return = 0; 1616f03b1f6Smrg 1626f03b1f6Smrg XvMCCheckExtension (dpy, info, NULL); 1636f03b1f6Smrg 1646f03b1f6Smrg 1656f03b1f6Smrg LockDisplay (dpy); 1666f03b1f6Smrg XvMCGetReq (ListSubpictureTypes, req); 1676f03b1f6Smrg req->port = port; 1686f03b1f6Smrg req->surface_type_id = surface_type_id; 1696f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 1706f03b1f6Smrg UnlockDisplay (dpy); 1716f03b1f6Smrg SyncHandle (); 1726f03b1f6Smrg return NULL; 1736f03b1f6Smrg } 1746f03b1f6Smrg 1756f03b1f6Smrg if(rep.num > 0) { 176190694daSmrg if (rep.num < (INT_MAX / sizeof(XvImageFormatValues))) 177190694daSmrg ret = Xmalloc(rep.num * sizeof(XvImageFormatValues)); 1786f03b1f6Smrg 1796f03b1f6Smrg if(ret) { 1806f03b1f6Smrg xvImageFormatInfo Info; 1816f03b1f6Smrg int i; 1826f03b1f6Smrg 1836f03b1f6Smrg *count_return = rep.num; 1846f03b1f6Smrg 1856f03b1f6Smrg for(i = 0; i < rep.num; i++) { 1866f03b1f6Smrg _XRead(dpy, (char*)(&Info), sz_xvImageFormatInfo); 18742941e3bSmrg ret[i].id = Info.id; 18842941e3bSmrg ret[i].type = Info.type; 18942941e3bSmrg ret[i].byte_order = Info.byte_order; 1906f03b1f6Smrg memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); 19142941e3bSmrg ret[i].bits_per_pixel = Info.bpp; 19242941e3bSmrg ret[i].format = Info.format; 19342941e3bSmrg ret[i].num_planes = Info.num_planes; 19442941e3bSmrg ret[i].depth = Info.depth; 19542941e3bSmrg ret[i].red_mask = Info.red_mask; 19642941e3bSmrg ret[i].green_mask = Info.green_mask; 19742941e3bSmrg ret[i].blue_mask = Info.blue_mask; 19842941e3bSmrg ret[i].y_sample_bits = Info.y_sample_bits; 19942941e3bSmrg ret[i].u_sample_bits = Info.u_sample_bits; 2006f03b1f6Smrg ret[i].v_sample_bits = Info.v_sample_bits; 2016f03b1f6Smrg ret[i].horz_y_period = Info.horz_y_period; 2026f03b1f6Smrg ret[i].horz_u_period = Info.horz_u_period; 2036f03b1f6Smrg ret[i].horz_v_period = Info.horz_v_period; 2046f03b1f6Smrg ret[i].vert_y_period = Info.vert_y_period; 2056f03b1f6Smrg ret[i].vert_u_period = Info.vert_u_period; 2066f03b1f6Smrg ret[i].vert_v_period = Info.vert_v_period; 2076f03b1f6Smrg memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); 2086f03b1f6Smrg ret[i].scanline_order = Info.scanline_order; 2096f03b1f6Smrg } 2106f03b1f6Smrg } else 2116f03b1f6Smrg _XEatData(dpy, rep.length << 2); 2126f03b1f6Smrg } 2136f03b1f6Smrg 2146f03b1f6Smrg UnlockDisplay (dpy); 2156f03b1f6Smrg SyncHandle (); 21642941e3bSmrg return ret; 2176f03b1f6Smrg} 2186f03b1f6Smrg 2196f03b1f6Smrg 22042941e3bSmrg/****************************************************************** 2216f03b1f6Smrg These are intended as a protocol interface to be used by direct 2226f03b1f6Smrg rendering libraries. They are not intended to be client viewable 2236f03b1f6Smrg functions. These will stay in place until we have a mechanism in 2246f03b1f6Smrg place similar to that of OpenGL with an libXvMCcore library. 22542941e3bSmrg*******************************************************************/ 22642941e3bSmrg 22742941e3bSmrg/* 2286f03b1f6Smrg _xvmc_create_context - 2296f03b1f6Smrg 2306f03b1f6Smrg Pass in the context with the surface_type_id, width, height, 2316f03b1f6Smrg port and flags filled out. This function will fill out the 2326f03b1f6Smrg context_id and update the width, height and flags field. 2336f03b1f6Smrg The server may return implementation-specific information 2346f03b1f6Smrg back in the priv_data. The size of that information will 2356f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 2366f03b1f6Smrg this function. If returned, the caller is responsible for 2376f03b1f6Smrg freeing it! Generally, such information is only returned if 23842941e3bSmrg an XVMC_DIRECT context was specified. 2396f03b1f6Smrg*/ 2406f03b1f6Smrg 2416f03b1f6Smrg 2426f03b1f6SmrgStatus _xvmc_create_context ( 2436f03b1f6Smrg Display *dpy, 2446f03b1f6Smrg XvMCContext *context, 2456f03b1f6Smrg int *priv_count, 2466f03b1f6Smrg CARD32 **priv_data 2476f03b1f6Smrg) 2486f03b1f6Smrg{ 2496f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 2506f03b1f6Smrg xvmcCreateContextReply rep; 2516f03b1f6Smrg xvmcCreateContextReq *req; 2526f03b1f6Smrg 2536f03b1f6Smrg *priv_count = 0; 2546f03b1f6Smrg *priv_data = NULL; 2556f03b1f6Smrg 2566f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 2576f03b1f6Smrg 2586f03b1f6Smrg LockDisplay (dpy); 2596f03b1f6Smrg XvMCGetReq (CreateContext, req); 2606f03b1f6Smrg context->context_id = XAllocID(dpy); 2616f03b1f6Smrg req->context_id = context->context_id; 2626f03b1f6Smrg req->port = context->port; 2636f03b1f6Smrg req->surface_type_id = context->surface_type_id; 2646f03b1f6Smrg req->width = context->width; 2656f03b1f6Smrg req->height = context->height; 2666f03b1f6Smrg req->flags = context->flags; 2676f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 2686f03b1f6Smrg UnlockDisplay (dpy); 2696f03b1f6Smrg SyncHandle (); 2706f03b1f6Smrg return BadImplementation; 2716f03b1f6Smrg } 2726f03b1f6Smrg context->width = rep.width_actual; 2736f03b1f6Smrg context->height = rep.height_actual; 2746f03b1f6Smrg context->flags = rep.flags_return; 2756f03b1f6Smrg 2766f03b1f6Smrg if(rep.length) { 2776f03b1f6Smrg *priv_data = Xmalloc(rep.length << 2); 2786f03b1f6Smrg if(*priv_data) { 2796f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 2806f03b1f6Smrg *priv_count = rep.length; 2816f03b1f6Smrg } else 2826f03b1f6Smrg _XEatData(dpy, rep.length << 2); 2836f03b1f6Smrg } 2846f03b1f6Smrg 2856f03b1f6Smrg UnlockDisplay (dpy); 2866f03b1f6Smrg SyncHandle (); 2876f03b1f6Smrg return Success; 2886f03b1f6Smrg} 2896f03b1f6Smrg 2906f03b1f6SmrgStatus _xvmc_destroy_context ( 2916f03b1f6Smrg Display *dpy, 2926f03b1f6Smrg XvMCContext *context 2936f03b1f6Smrg) 2946f03b1f6Smrg{ 2956f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 2966f03b1f6Smrg xvmcDestroyContextReq *req; 2976f03b1f6Smrg 2986f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 2996f03b1f6Smrg 3006f03b1f6Smrg LockDisplay (dpy); 3016f03b1f6Smrg XvMCGetReq (DestroyContext, req); 3026f03b1f6Smrg req->context_id = context->context_id; 3036f03b1f6Smrg UnlockDisplay (dpy); 3046f03b1f6Smrg SyncHandle (); 3056f03b1f6Smrg return Success; 3066f03b1f6Smrg} 3076f03b1f6Smrg 3086f03b1f6Smrg 3096f03b1f6Smrg/* 3106f03b1f6Smrg _xvmc_create_surface - 3116f03b1f6Smrg 3126f03b1f6Smrg Pass the context and this function will fill out all the 31342941e3bSmrg information in the surface. 3146f03b1f6Smrg The server may return implementation-specific information 3156f03b1f6Smrg back in the priv_data. The size of that information will 3166f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 3176f03b1f6Smrg this function. If returned, the caller is responsible for 3186f03b1f6Smrg freeing it! Generally, such information is returned only if 3196f03b1f6Smrg the context was a direct context. 32042941e3bSmrg 3216f03b1f6Smrg*/ 3226f03b1f6Smrg 3236f03b1f6SmrgStatus _xvmc_create_surface ( 3246f03b1f6Smrg Display *dpy, 3256f03b1f6Smrg XvMCContext *context, 3266f03b1f6Smrg XvMCSurface *surface, 3276f03b1f6Smrg int *priv_count, 3286f03b1f6Smrg CARD32 **priv_data 3296f03b1f6Smrg) 3306f03b1f6Smrg{ 3316f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3326f03b1f6Smrg xvmcCreateSurfaceReply rep; 3336f03b1f6Smrg xvmcCreateSurfaceReq *req; 3346f03b1f6Smrg 3356f03b1f6Smrg *priv_count = 0; 3366f03b1f6Smrg *priv_data = NULL; 3376f03b1f6Smrg 3386f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3396f03b1f6Smrg 3406f03b1f6Smrg LockDisplay (dpy); 3416f03b1f6Smrg XvMCGetReq (CreateSurface, req); 3426f03b1f6Smrg 3436f03b1f6Smrg surface->surface_id = XAllocID(dpy); 3446f03b1f6Smrg surface->context_id = context->context_id; 3456f03b1f6Smrg surface->surface_type_id = context->surface_type_id; 3466f03b1f6Smrg surface->width = context->width; 3476f03b1f6Smrg surface->height = context->height; 3486f03b1f6Smrg 3496f03b1f6Smrg req->surface_id = surface->surface_id; 3506f03b1f6Smrg req->context_id = surface->context_id; 3516f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 3526f03b1f6Smrg UnlockDisplay (dpy); 3536f03b1f6Smrg SyncHandle (); 3546f03b1f6Smrg return BadImplementation; 3556f03b1f6Smrg } 3566f03b1f6Smrg 3576f03b1f6Smrg if(rep.length) { 3586f03b1f6Smrg *priv_data = Xmalloc(rep.length << 2); 3596f03b1f6Smrg if(*priv_data) { 3606f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 3616f03b1f6Smrg *priv_count = rep.length; 3626f03b1f6Smrg } else 3636f03b1f6Smrg _XEatData(dpy, rep.length << 2); 3646f03b1f6Smrg } 3656f03b1f6Smrg 3666f03b1f6Smrg UnlockDisplay (dpy); 3676f03b1f6Smrg SyncHandle (); 3686f03b1f6Smrg return Success; 3696f03b1f6Smrg} 3706f03b1f6Smrg 3716f03b1f6SmrgStatus _xvmc_destroy_surface ( 3726f03b1f6Smrg Display *dpy, 3736f03b1f6Smrg XvMCSurface *surface 3746f03b1f6Smrg) 3756f03b1f6Smrg{ 3766f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3776f03b1f6Smrg xvmcDestroySurfaceReq *req; 3786f03b1f6Smrg 3796f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3806f03b1f6Smrg 3816f03b1f6Smrg LockDisplay (dpy); 3826f03b1f6Smrg XvMCGetReq (DestroySurface, req); 3836f03b1f6Smrg req->surface_id = surface->surface_id; 3846f03b1f6Smrg UnlockDisplay (dpy); 3856f03b1f6Smrg SyncHandle (); 3866f03b1f6Smrg return Success; 3876f03b1f6Smrg} 3886f03b1f6Smrg 3896f03b1f6Smrg/* 3906f03b1f6Smrg _xvmc_create_subpicture - 3916f03b1f6Smrg 3926f03b1f6Smrg Pass the subpicture with the width, height and xvimage_id filled 3936f03b1f6Smrg out and this function will fill out everything else in the 3946f03b1f6Smrg subpicture as well as adjust the width and height if needed. 3956f03b1f6Smrg The server may return implementation-specific information 3966f03b1f6Smrg back in the priv_data. The size of that information will 3976f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 3986f03b1f6Smrg this function. If returned, the caller is responsible for 3996f03b1f6Smrg freeing it! Generally, such information is returned only if 4006f03b1f6Smrg the context was a direct context. 4016f03b1f6Smrg 4026f03b1f6Smrg*/ 4036f03b1f6Smrg 4046f03b1f6SmrgStatus _xvmc_create_subpicture ( 4056f03b1f6Smrg Display *dpy, 4066f03b1f6Smrg XvMCContext *context, 4076f03b1f6Smrg XvMCSubpicture *subpicture, 4086f03b1f6Smrg int *priv_count, 4096f03b1f6Smrg CARD32 **priv_data 4106f03b1f6Smrg) 4116f03b1f6Smrg{ 4126f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4136f03b1f6Smrg xvmcCreateSubpictureReply rep; 4146f03b1f6Smrg xvmcCreateSubpictureReq *req; 4156f03b1f6Smrg 4166f03b1f6Smrg *priv_count = 0; 4176f03b1f6Smrg *priv_data = NULL; 4186f03b1f6Smrg 4196f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 4206f03b1f6Smrg 4216f03b1f6Smrg LockDisplay (dpy); 4226f03b1f6Smrg XvMCGetReq (CreateSubpicture, req); 4236f03b1f6Smrg 4246f03b1f6Smrg subpicture->subpicture_id = XAllocID(dpy); 4256f03b1f6Smrg subpicture->context_id = context->context_id; 4266f03b1f6Smrg 4276f03b1f6Smrg req->subpicture_id = subpicture->subpicture_id; 4286f03b1f6Smrg req->context_id = subpicture->context_id; 4296f03b1f6Smrg req->xvimage_id = subpicture->xvimage_id; 4306f03b1f6Smrg req->width = subpicture->width; 4316f03b1f6Smrg req->height = subpicture->height; 4326f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 4336f03b1f6Smrg UnlockDisplay (dpy); 4346f03b1f6Smrg SyncHandle (); 4356f03b1f6Smrg return BadImplementation; 4366f03b1f6Smrg } 4376f03b1f6Smrg 4386f03b1f6Smrg subpicture->width = rep.width_actual; 4396f03b1f6Smrg subpicture->height = rep.height_actual; 4406f03b1f6Smrg subpicture->num_palette_entries = rep.num_palette_entries; 4416f03b1f6Smrg subpicture->entry_bytes = rep.entry_bytes; 4426f03b1f6Smrg subpicture->component_order[0] = rep.component_order[0]; 4436f03b1f6Smrg subpicture->component_order[1] = rep.component_order[1]; 4446f03b1f6Smrg subpicture->component_order[2] = rep.component_order[2]; 4456f03b1f6Smrg subpicture->component_order[3] = rep.component_order[3]; 4466f03b1f6Smrg 4476f03b1f6Smrg if(rep.length) { 4486f03b1f6Smrg *priv_data = Xmalloc(rep.length << 2); 4496f03b1f6Smrg if(*priv_data) { 4506f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 4516f03b1f6Smrg *priv_count = rep.length; 4526f03b1f6Smrg } else 4536f03b1f6Smrg _XEatData(dpy, rep.length << 2); 4546f03b1f6Smrg } 4556f03b1f6Smrg 4566f03b1f6Smrg UnlockDisplay (dpy); 4576f03b1f6Smrg SyncHandle (); 4586f03b1f6Smrg return Success; 4596f03b1f6Smrg} 4606f03b1f6Smrg 4616f03b1f6SmrgStatus _xvmc_destroy_subpicture( 4626f03b1f6Smrg Display *dpy, 4636f03b1f6Smrg XvMCSubpicture *subpicture 4646f03b1f6Smrg) 4656f03b1f6Smrg{ 4666f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4676f03b1f6Smrg xvmcDestroySubpictureReq *req; 4686f03b1f6Smrg 4696f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 4706f03b1f6Smrg 4716f03b1f6Smrg LockDisplay (dpy); 4726f03b1f6Smrg XvMCGetReq (DestroySubpicture, req); 47342941e3bSmrg req->subpicture_id = subpicture->subpicture_id; 4746f03b1f6Smrg UnlockDisplay (dpy); 4756f03b1f6Smrg SyncHandle (); 4766f03b1f6Smrg return Success; 4776f03b1f6Smrg} 4786f03b1f6Smrg 4796f03b1f6SmrgStatus XvMCGetDRInfo(Display *dpy, XvPortID port, 48042941e3bSmrg char **name, char **busID, 48142941e3bSmrg int *major, int *minor, 4826f03b1f6Smrg int *patchLevel, 4836f03b1f6Smrg int *isLocal) 4846f03b1f6Smrg{ 4856f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4866f03b1f6Smrg xvmcGetDRInfoReply rep; 4876f03b1f6Smrg xvmcGetDRInfoReq *req; 4886f03b1f6Smrg CARD32 magic; 4896f03b1f6Smrg 49042941e3bSmrg#ifdef HAVE_SHMAT 4916f03b1f6Smrg volatile CARD32 *shMem; 4926f03b1f6Smrg struct timezone here; 4936f03b1f6Smrg struct timeval now; 4946f03b1f6Smrg here.tz_minuteswest = 0; 4956f03b1f6Smrg here.tz_dsttime = 0; 4966f03b1f6Smrg#endif 4976f03b1f6Smrg 498190694daSmrg *name = NULL; 499190694daSmrg *busID = NULL; 500190694daSmrg 5016f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 5026f03b1f6Smrg 5036f03b1f6Smrg LockDisplay (dpy); 5046f03b1f6Smrg XvMCGetReq (GetDRInfo, req); 5056f03b1f6Smrg 5066f03b1f6Smrg req->port = port; 5076f03b1f6Smrg magic = 0; 5086f03b1f6Smrg req->magic = 0; 50942941e3bSmrg#ifdef HAVE_SHMAT 5106f03b1f6Smrg req->shmKey = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0600); 5116f03b1f6Smrg 5126f03b1f6Smrg /* 5136f03b1f6Smrg * We fill a shared memory page with a repetitive pattern. If the 5146f03b1f6Smrg * X server can read this pattern, we probably have a local connection. 5156f03b1f6Smrg * Note that we can trigger the remote X server to read any shared 5166f03b1f6Smrg * page on the remote machine, so we shouldn't be able to guess and verify 5176f03b1f6Smrg * any complicated data on those pages. Thats the explanation of this 5186f03b1f6Smrg * otherwise stupid-looking pattern algorithm. 5196f03b1f6Smrg */ 52042941e3bSmrg 5216f03b1f6Smrg if (req->shmKey >= 0) { 5226f03b1f6Smrg shMem = (CARD32 *) shmat(req->shmKey, NULL, 0); 5236f03b1f6Smrg shmctl( req->shmKey, IPC_RMID, NULL); 52442941e3bSmrg if ( shMem ) { 5256f03b1f6Smrg 5266f03b1f6Smrg register volatile CARD32 *shMemC = shMem; 5276f03b1f6Smrg register int i; 5286f03b1f6Smrg 5296f03b1f6Smrg gettimeofday( &now, &here); 5306f03b1f6Smrg magic = now.tv_usec & 0x000FFFFF; 5316f03b1f6Smrg req->magic = magic; 5326f03b1f6Smrg i = 1024 / sizeof(CARD32); 5336f03b1f6Smrg while(i--) { 53442941e3bSmrg *shMemC++ = magic; 5356f03b1f6Smrg magic = ~magic; 5366f03b1f6Smrg } 5376f03b1f6Smrg } else { 5386f03b1f6Smrg req->shmKey = -1; 5396f03b1f6Smrg } 5406f03b1f6Smrg } 5416f03b1f6Smrg#else 5426f03b1f6Smrg req->shmKey = 0; 5436f03b1f6Smrg#endif 5446f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 5456f03b1f6Smrg UnlockDisplay (dpy); 5466f03b1f6Smrg SyncHandle (); 54742941e3bSmrg#ifdef HAVE_SHMAT 5486f03b1f6Smrg if ( req->shmKey >= 0) { 5496f03b1f6Smrg shmdt( (const void *) shMem ); 55042941e3bSmrg } 5516f03b1f6Smrg#endif 5526f03b1f6Smrg return -1; 5536f03b1f6Smrg } 55442941e3bSmrg#ifdef HAVE_SHMAT 5556f03b1f6Smrg shmdt( (const void *) shMem ); 5566f03b1f6Smrg#endif 5576f03b1f6Smrg 5586f03b1f6Smrg if (rep.length > 0) { 559190694daSmrg unsigned long realSize = 0; 560190694daSmrg char *tmpBuf = NULL; 561190694daSmrg 562190694daSmrg if (rep.length < (INT_MAX >> 2)) { 563190694daSmrg realSize = rep.length << 2; 564190694daSmrg if (realSize >= (rep.nameLen + rep.busIDLen)) { 565190694daSmrg tmpBuf = Xmalloc(realSize); 566190694daSmrg *name = Xmalloc(rep.nameLen); 567190694daSmrg *busID = Xmalloc(rep.busIDLen); 56842941e3bSmrg } 5696f03b1f6Smrg } 5706f03b1f6Smrg 5716f03b1f6Smrg if (*name && *busID && tmpBuf) { 5726f03b1f6Smrg _XRead(dpy, tmpBuf, realSize); 5736f03b1f6Smrg strncpy(*name,tmpBuf,rep.nameLen); 574190694daSmrg name[rep.nameLen - 1] = '\0'; 5756f03b1f6Smrg strncpy(*busID,tmpBuf+rep.nameLen,rep.busIDLen); 576190694daSmrg busID[rep.busIDLen - 1] = '\0'; 5776f03b1f6Smrg XFree(tmpBuf); 5786f03b1f6Smrg } else { 579190694daSmrg XFree(*name); 580190694daSmrg *name = NULL; 581190694daSmrg XFree(*busID); 582190694daSmrg *name = NULL; 583190694daSmrg XFree(tmpBuf); 5846f03b1f6Smrg 5856f03b1f6Smrg _XEatData(dpy, realSize); 5866f03b1f6Smrg UnlockDisplay (dpy); 5876f03b1f6Smrg SyncHandle (); 5886f03b1f6Smrg return -1; 5896f03b1f6Smrg 5906f03b1f6Smrg } 5916f03b1f6Smrg } 5926f03b1f6Smrg 5936f03b1f6Smrg UnlockDisplay (dpy); 5946f03b1f6Smrg SyncHandle (); 5956f03b1f6Smrg *major = rep.major; 5966f03b1f6Smrg *minor = rep.minor; 5976f03b1f6Smrg *patchLevel = rep.patchLevel; 5986f03b1f6Smrg *isLocal = (req->shmKey > 0) ? rep.isLocal : 1; 5996f03b1f6Smrg return (rep.length > 0) ? Success : BadImplementation; 6006f03b1f6Smrg} 6016f03b1f6Smrg 602