XvMC.c revision 4e5182b7
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; 1207448d6e9Smrg CARD32 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 138cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 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; 1817448d6e9Smrg CARD32 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 211cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 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) { 277cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 278cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 2796f03b1f6Smrg if(*priv_data) { 2806f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 2816f03b1f6Smrg *priv_count = rep.length; 2826f03b1f6Smrg } else 283cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 2846f03b1f6Smrg } 2856f03b1f6Smrg 2866f03b1f6Smrg UnlockDisplay (dpy); 2876f03b1f6Smrg SyncHandle (); 2886f03b1f6Smrg return Success; 2896f03b1f6Smrg} 2906f03b1f6Smrg 2916f03b1f6SmrgStatus _xvmc_destroy_context ( 2926f03b1f6Smrg Display *dpy, 2936f03b1f6Smrg XvMCContext *context 2946f03b1f6Smrg) 2956f03b1f6Smrg{ 2966f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 2976f03b1f6Smrg xvmcDestroyContextReq *req; 2986f03b1f6Smrg 2996f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3006f03b1f6Smrg 3016f03b1f6Smrg LockDisplay (dpy); 3026f03b1f6Smrg XvMCGetReq (DestroyContext, req); 3036f03b1f6Smrg req->context_id = context->context_id; 3046f03b1f6Smrg UnlockDisplay (dpy); 3056f03b1f6Smrg SyncHandle (); 3066f03b1f6Smrg return Success; 3076f03b1f6Smrg} 3086f03b1f6Smrg 3096f03b1f6Smrg 3106f03b1f6Smrg/* 3116f03b1f6Smrg _xvmc_create_surface - 3126f03b1f6Smrg 3136f03b1f6Smrg Pass the context and this function will fill out all the 31442941e3bSmrg information in the surface. 3156f03b1f6Smrg The server may return implementation-specific information 3166f03b1f6Smrg back in the priv_data. The size of that information will 3176f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 3186f03b1f6Smrg this function. If returned, the caller is responsible for 3196f03b1f6Smrg freeing it! Generally, such information is returned only if 3206f03b1f6Smrg the context was a direct context. 32142941e3bSmrg 3226f03b1f6Smrg*/ 3236f03b1f6Smrg 3246f03b1f6SmrgStatus _xvmc_create_surface ( 3256f03b1f6Smrg Display *dpy, 3266f03b1f6Smrg XvMCContext *context, 3276f03b1f6Smrg XvMCSurface *surface, 3286f03b1f6Smrg int *priv_count, 3296f03b1f6Smrg CARD32 **priv_data 3306f03b1f6Smrg) 3316f03b1f6Smrg{ 3326f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3336f03b1f6Smrg xvmcCreateSurfaceReply rep; 3346f03b1f6Smrg xvmcCreateSurfaceReq *req; 3356f03b1f6Smrg 3366f03b1f6Smrg *priv_count = 0; 3376f03b1f6Smrg *priv_data = NULL; 3386f03b1f6Smrg 3396f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3406f03b1f6Smrg 3416f03b1f6Smrg LockDisplay (dpy); 3426f03b1f6Smrg XvMCGetReq (CreateSurface, req); 3436f03b1f6Smrg 3446f03b1f6Smrg surface->surface_id = XAllocID(dpy); 3456f03b1f6Smrg surface->context_id = context->context_id; 3466f03b1f6Smrg surface->surface_type_id = context->surface_type_id; 3476f03b1f6Smrg surface->width = context->width; 3486f03b1f6Smrg surface->height = context->height; 3496f03b1f6Smrg 3506f03b1f6Smrg req->surface_id = surface->surface_id; 3516f03b1f6Smrg req->context_id = surface->context_id; 3526f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 3536f03b1f6Smrg UnlockDisplay (dpy); 3546f03b1f6Smrg SyncHandle (); 3556f03b1f6Smrg return BadImplementation; 3566f03b1f6Smrg } 3576f03b1f6Smrg 3586f03b1f6Smrg if(rep.length) { 359cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 360cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 3616f03b1f6Smrg if(*priv_data) { 3626f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 3636f03b1f6Smrg *priv_count = rep.length; 3646f03b1f6Smrg } else 365cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 3666f03b1f6Smrg } 3676f03b1f6Smrg 3686f03b1f6Smrg UnlockDisplay (dpy); 3696f03b1f6Smrg SyncHandle (); 3706f03b1f6Smrg return Success; 3716f03b1f6Smrg} 3726f03b1f6Smrg 3736f03b1f6SmrgStatus _xvmc_destroy_surface ( 3746f03b1f6Smrg Display *dpy, 3756f03b1f6Smrg XvMCSurface *surface 3766f03b1f6Smrg) 3776f03b1f6Smrg{ 3786f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3796f03b1f6Smrg xvmcDestroySurfaceReq *req; 3806f03b1f6Smrg 3816f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 3826f03b1f6Smrg 3836f03b1f6Smrg LockDisplay (dpy); 3846f03b1f6Smrg XvMCGetReq (DestroySurface, req); 3856f03b1f6Smrg req->surface_id = surface->surface_id; 3866f03b1f6Smrg UnlockDisplay (dpy); 3876f03b1f6Smrg SyncHandle (); 3886f03b1f6Smrg return Success; 3896f03b1f6Smrg} 3906f03b1f6Smrg 3916f03b1f6Smrg/* 3926f03b1f6Smrg _xvmc_create_subpicture - 3936f03b1f6Smrg 3946f03b1f6Smrg Pass the subpicture with the width, height and xvimage_id filled 3956f03b1f6Smrg out and this function will fill out everything else in the 3966f03b1f6Smrg subpicture as well as adjust the width and height if needed. 3976f03b1f6Smrg The server may return implementation-specific information 3986f03b1f6Smrg back in the priv_data. The size of that information will 3996f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 4006f03b1f6Smrg this function. If returned, the caller is responsible for 4016f03b1f6Smrg freeing it! Generally, such information is returned only if 4026f03b1f6Smrg the context was a direct context. 4036f03b1f6Smrg 4046f03b1f6Smrg*/ 4056f03b1f6Smrg 4066f03b1f6SmrgStatus _xvmc_create_subpicture ( 4076f03b1f6Smrg Display *dpy, 4086f03b1f6Smrg XvMCContext *context, 4096f03b1f6Smrg XvMCSubpicture *subpicture, 4106f03b1f6Smrg int *priv_count, 4116f03b1f6Smrg CARD32 **priv_data 4126f03b1f6Smrg) 4136f03b1f6Smrg{ 4146f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4156f03b1f6Smrg xvmcCreateSubpictureReply rep; 4166f03b1f6Smrg xvmcCreateSubpictureReq *req; 4176f03b1f6Smrg 4186f03b1f6Smrg *priv_count = 0; 4196f03b1f6Smrg *priv_data = NULL; 4206f03b1f6Smrg 4216f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 4226f03b1f6Smrg 4236f03b1f6Smrg LockDisplay (dpy); 4246f03b1f6Smrg XvMCGetReq (CreateSubpicture, req); 4256f03b1f6Smrg 4266f03b1f6Smrg subpicture->subpicture_id = XAllocID(dpy); 4276f03b1f6Smrg subpicture->context_id = context->context_id; 4286f03b1f6Smrg 4296f03b1f6Smrg req->subpicture_id = subpicture->subpicture_id; 4306f03b1f6Smrg req->context_id = subpicture->context_id; 4316f03b1f6Smrg req->xvimage_id = subpicture->xvimage_id; 4326f03b1f6Smrg req->width = subpicture->width; 4336f03b1f6Smrg req->height = subpicture->height; 4346f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 4356f03b1f6Smrg UnlockDisplay (dpy); 4366f03b1f6Smrg SyncHandle (); 4376f03b1f6Smrg return BadImplementation; 4386f03b1f6Smrg } 4396f03b1f6Smrg 4406f03b1f6Smrg subpicture->width = rep.width_actual; 4416f03b1f6Smrg subpicture->height = rep.height_actual; 4426f03b1f6Smrg subpicture->num_palette_entries = rep.num_palette_entries; 4436f03b1f6Smrg subpicture->entry_bytes = rep.entry_bytes; 4446f03b1f6Smrg subpicture->component_order[0] = rep.component_order[0]; 4456f03b1f6Smrg subpicture->component_order[1] = rep.component_order[1]; 4466f03b1f6Smrg subpicture->component_order[2] = rep.component_order[2]; 4476f03b1f6Smrg subpicture->component_order[3] = rep.component_order[3]; 4486f03b1f6Smrg 4496f03b1f6Smrg if(rep.length) { 450cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 451cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 4526f03b1f6Smrg if(*priv_data) { 4536f03b1f6Smrg _XRead(dpy, (char*)(*priv_data), rep.length << 2); 4546f03b1f6Smrg *priv_count = rep.length; 4556f03b1f6Smrg } else 456cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 4576f03b1f6Smrg } 4586f03b1f6Smrg 4596f03b1f6Smrg UnlockDisplay (dpy); 4606f03b1f6Smrg SyncHandle (); 4616f03b1f6Smrg return Success; 4626f03b1f6Smrg} 4636f03b1f6Smrg 4646f03b1f6SmrgStatus _xvmc_destroy_subpicture( 4656f03b1f6Smrg Display *dpy, 4666f03b1f6Smrg XvMCSubpicture *subpicture 4676f03b1f6Smrg) 4686f03b1f6Smrg{ 4696f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4706f03b1f6Smrg xvmcDestroySubpictureReq *req; 4716f03b1f6Smrg 4726f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 4736f03b1f6Smrg 4746f03b1f6Smrg LockDisplay (dpy); 4756f03b1f6Smrg XvMCGetReq (DestroySubpicture, req); 47642941e3bSmrg req->subpicture_id = subpicture->subpicture_id; 4776f03b1f6Smrg UnlockDisplay (dpy); 4786f03b1f6Smrg SyncHandle (); 4796f03b1f6Smrg return Success; 4806f03b1f6Smrg} 4816f03b1f6Smrg 4826f03b1f6SmrgStatus XvMCGetDRInfo(Display *dpy, XvPortID port, 48342941e3bSmrg char **name, char **busID, 48442941e3bSmrg int *major, int *minor, 4856f03b1f6Smrg int *patchLevel, 4866f03b1f6Smrg int *isLocal) 4876f03b1f6Smrg{ 4886f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4896f03b1f6Smrg xvmcGetDRInfoReply rep; 4906f03b1f6Smrg xvmcGetDRInfoReq *req; 4916f03b1f6Smrg CARD32 magic; 4926f03b1f6Smrg 49342941e3bSmrg#ifdef HAVE_SHMAT 4947448d6e9Smrg int shmKey; 4956f03b1f6Smrg volatile CARD32 *shMem; 4966f03b1f6Smrg struct timezone here; 4976f03b1f6Smrg struct timeval now; 4986f03b1f6Smrg here.tz_minuteswest = 0; 4996f03b1f6Smrg here.tz_dsttime = 0; 5006f03b1f6Smrg#endif 5016f03b1f6Smrg 502190694daSmrg *name = NULL; 503190694daSmrg *busID = NULL; 504190694daSmrg 5056f03b1f6Smrg XvMCCheckExtension (dpy, info, BadImplementation); 5066f03b1f6Smrg 5076f03b1f6Smrg LockDisplay (dpy); 5086f03b1f6Smrg XvMCGetReq (GetDRInfo, req); 5096f03b1f6Smrg 5106f03b1f6Smrg req->port = port; 5116f03b1f6Smrg magic = 0; 5126f03b1f6Smrg req->magic = 0; 51342941e3bSmrg#ifdef HAVE_SHMAT 5147448d6e9Smrg shmKey = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0600); 5157448d6e9Smrg req->shmKey = (CARD32) shmKey; 5166f03b1f6Smrg 5176f03b1f6Smrg /* 5186f03b1f6Smrg * We fill a shared memory page with a repetitive pattern. If the 5196f03b1f6Smrg * X server can read this pattern, we probably have a local connection. 5206f03b1f6Smrg * Note that we can trigger the remote X server to read any shared 5216f03b1f6Smrg * page on the remote machine, so we shouldn't be able to guess and verify 5224e5182b7Smrg * any complicated data on those pages. That's the explanation of this 5236f03b1f6Smrg * otherwise stupid-looking pattern algorithm. 5246f03b1f6Smrg */ 52542941e3bSmrg 5267448d6e9Smrg if (shmKey >= 0) { 5277448d6e9Smrg shMem = (CARD32 *) shmat(shmKey, NULL, 0); 5287448d6e9Smrg shmctl(shmKey, IPC_RMID, NULL); 5297448d6e9Smrg if (shMem != (void *) -1) { 5306f03b1f6Smrg 5316f03b1f6Smrg register volatile CARD32 *shMemC = shMem; 5326f03b1f6Smrg register int i; 5336f03b1f6Smrg 5346f03b1f6Smrg gettimeofday( &now, &here); 5356f03b1f6Smrg magic = now.tv_usec & 0x000FFFFF; 5366f03b1f6Smrg req->magic = magic; 5376f03b1f6Smrg i = 1024 / sizeof(CARD32); 5386f03b1f6Smrg while(i--) { 53942941e3bSmrg *shMemC++ = magic; 5406f03b1f6Smrg magic = ~magic; 5416f03b1f6Smrg } 5426f03b1f6Smrg } else { 5436f03b1f6Smrg req->shmKey = -1; 5447448d6e9Smrg shmKey = -1; 5456f03b1f6Smrg } 5466f03b1f6Smrg } 5476f03b1f6Smrg#else 5486f03b1f6Smrg req->shmKey = 0; 5496f03b1f6Smrg#endif 5506f03b1f6Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 5516f03b1f6Smrg UnlockDisplay (dpy); 5526f03b1f6Smrg SyncHandle (); 55342941e3bSmrg#ifdef HAVE_SHMAT 5547448d6e9Smrg if (shmKey >= 0) { 5556f03b1f6Smrg shmdt( (const void *) shMem ); 55642941e3bSmrg } 5576f03b1f6Smrg#endif 5586f03b1f6Smrg return -1; 5596f03b1f6Smrg } 56042941e3bSmrg#ifdef HAVE_SHMAT 5617448d6e9Smrg if (shmKey >= 0) { 5627448d6e9Smrg shmdt( (const void *) shMem ); 5637448d6e9Smrg } 5646f03b1f6Smrg#endif 5656f03b1f6Smrg 5666f03b1f6Smrg if (rep.length > 0) { 567190694daSmrg unsigned long realSize = 0; 568190694daSmrg char *tmpBuf = NULL; 569190694daSmrg 570cc1b55f9Smrg if ((rep.length < (INT_MAX >> 2)) && 571cc1b55f9Smrg /* protect against overflow in strncpy below */ 572cc1b55f9Smrg (rep.nameLen + rep.busIDLen > rep.nameLen)) { 573190694daSmrg realSize = rep.length << 2; 574190694daSmrg if (realSize >= (rep.nameLen + rep.busIDLen)) { 575190694daSmrg tmpBuf = Xmalloc(realSize); 576190694daSmrg *name = Xmalloc(rep.nameLen); 577190694daSmrg *busID = Xmalloc(rep.busIDLen); 57842941e3bSmrg } 5796f03b1f6Smrg } 5806f03b1f6Smrg 5816f03b1f6Smrg if (*name && *busID && tmpBuf) { 5826f03b1f6Smrg _XRead(dpy, tmpBuf, realSize); 5836f03b1f6Smrg strncpy(*name,tmpBuf,rep.nameLen); 584f1c62215Smrg (*name)[rep.nameLen == 0 ? 0 : rep.nameLen - 1] = '\0'; 5856f03b1f6Smrg strncpy(*busID,tmpBuf+rep.nameLen,rep.busIDLen); 586f1c62215Smrg (*busID)[rep.busIDLen == 0 ? 0 : rep.busIDLen - 1] = '\0'; 5876f03b1f6Smrg XFree(tmpBuf); 5886f03b1f6Smrg } else { 589190694daSmrg XFree(*name); 590190694daSmrg *name = NULL; 591190694daSmrg XFree(*busID); 592cc1b55f9Smrg *busID = NULL; 593190694daSmrg XFree(tmpBuf); 5946f03b1f6Smrg 595cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 5966f03b1f6Smrg UnlockDisplay (dpy); 5976f03b1f6Smrg SyncHandle (); 5986f03b1f6Smrg return -1; 5996f03b1f6Smrg 6006f03b1f6Smrg } 6016f03b1f6Smrg } 6026f03b1f6Smrg 6036f03b1f6Smrg UnlockDisplay (dpy); 6046f03b1f6Smrg SyncHandle (); 6056f03b1f6Smrg *major = rep.major; 6066f03b1f6Smrg *minor = rep.minor; 6076f03b1f6Smrg *patchLevel = rep.patchLevel; 6087448d6e9Smrg#ifdef HAVE_SHMAT 6097448d6e9Smrg if (shmKey >= 0) 6107448d6e9Smrg *isLocal = rep.isLocal; 6117448d6e9Smrg else 6127448d6e9Smrg#endif 6137448d6e9Smrg *isLocal = 1; 6146f03b1f6Smrg return (rep.length > 0) ? Success : BadImplementation; 6156f03b1f6Smrg} 6166f03b1f6Smrg 617