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