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 255d8688b9Smrgstatic const char *xvmc_error_list[] = { 265d8688b9Smrg "BadContext", 275d8688b9Smrg "BadSurface", 285d8688b9Smrg "BadSubpicture" 296f03b1f6Smrg}; 306f03b1f6Smrg 315d8688b9Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY(xvmc_close_display, xvmc_info) 325d8688b9Smrgstatic XEXT_GENERATE_ERROR_STRING(xvmc_error_string, xvmc_extension_name, 335d8688b9Smrg XvMCNumErrors, xvmc_error_list) 346f03b1f6Smrg 356f03b1f6Smrgstatic XExtensionHooks xvmc_extension_hooks = { 365d8688b9Smrg NULL, /* create_gc */ 375d8688b9Smrg NULL, /* copy_gc */ 385d8688b9Smrg NULL, /* flush_gc */ 395d8688b9Smrg NULL, /* free_gc */ 405d8688b9Smrg NULL, /* create_font */ 415d8688b9Smrg NULL, /* free_font */ 425d8688b9Smrg xvmc_close_display, /* close_display */ 435d8688b9Smrg NULL, /* wire_to_event */ 445d8688b9Smrg NULL, /* event_to_wire */ 455d8688b9Smrg NULL, /* error */ 465d8688b9Smrg xvmc_error_string /* error_string */ 476f03b1f6Smrg}; 486f03b1f6Smrg 495d8688b9Smrgstatic XEXT_GENERATE_FIND_DISPLAY(xvmc_find_display, xvmc_info, 505d8688b9Smrg xvmc_extension_name, 515d8688b9Smrg &xvmc_extension_hooks, 525d8688b9Smrg XvMCNumEvents, NULL) 536f03b1f6Smrg 545d8688b9SmrgBool 555d8688b9SmrgXvMCQueryExtension(Display *dpy, int *event_basep, int *error_basep) 566f03b1f6Smrg{ 576f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 586f03b1f6Smrg 596f03b1f6Smrg if (XextHasExtension(info)) { 606f03b1f6Smrg *event_basep = info->codes->first_event; 616f03b1f6Smrg *error_basep = info->codes->first_error; 626f03b1f6Smrg return True; 635d8688b9Smrg } 645d8688b9Smrg else { 656f03b1f6Smrg return False; 666f03b1f6Smrg } 676f03b1f6Smrg} 686f03b1f6Smrg 695d8688b9SmrgStatus 705d8688b9SmrgXvMCQueryVersion(Display *dpy, int *major, int *minor) 716f03b1f6Smrg{ 726f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 736f03b1f6Smrg xvmcQueryVersionReply rep; 745d8688b9Smrg xvmcQueryVersionReq *req; 756f03b1f6Smrg 765d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 776f03b1f6Smrg 785d8688b9Smrg LockDisplay(dpy); 795d8688b9Smrg XvMCGetReq(QueryVersion, req); 805d8688b9Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) { 815d8688b9Smrg UnlockDisplay(dpy); 825d8688b9Smrg SyncHandle(); 836f03b1f6Smrg return BadImplementation; 846f03b1f6Smrg } 855d8688b9Smrg *major = (int) rep.major; 865d8688b9Smrg *minor = (int) rep.minor; 875d8688b9Smrg UnlockDisplay(dpy); 885d8688b9Smrg SyncHandle(); 896f03b1f6Smrg return Success; 906f03b1f6Smrg} 916f03b1f6Smrg 925d8688b9SmrgXvMCSurfaceInfo * 935d8688b9SmrgXvMCListSurfaceTypes(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 1025d8688b9Smrg XvMCCheckExtension(dpy, info, NULL); 10342941e3bSmrg 1045d8688b9Smrg LockDisplay(dpy); 1055d8688b9Smrg XvMCGetReq(ListSurfaceTypes, req); 1065d8688b9Smrg req->port = (CARD32) port; 1075d8688b9Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 1085d8688b9Smrg UnlockDisplay(dpy); 1095d8688b9Smrg SyncHandle(); 1106f03b1f6Smrg return NULL; 1116f03b1f6Smrg } 1126f03b1f6Smrg 1135d8688b9Smrg if (rep.num > 0) { 114190694daSmrg if (rep.num < (INT_MAX / sizeof(XvMCSurfaceInfo))) 115190694daSmrg surface_info = Xmalloc(rep.num * sizeof(XvMCSurfaceInfo)); 1166f03b1f6Smrg 1175d8688b9Smrg if (surface_info) { 1185d8688b9Smrg *num = (int) rep.num; 1195d8688b9Smrg 1205d8688b9Smrg for (CARD32 i = 0; i < rep.num; i++) { 1215d8688b9Smrg xvmcSurfaceInfo sinfo; 1225d8688b9Smrg 1235d8688b9Smrg _XRead(dpy, (char *) &sinfo, sizeof(xvmcSurfaceInfo)); 1245d8688b9Smrg surface_info[i].surface_type_id = (int) sinfo.surface_type_id; 1255d8688b9Smrg surface_info[i].chroma_format = sinfo.chroma_format; 1265d8688b9Smrg surface_info[i].max_width = sinfo.max_width; 1275d8688b9Smrg surface_info[i].max_height = sinfo.max_height; 1285d8688b9Smrg surface_info[i].subpicture_max_width = 1295d8688b9Smrg sinfo.subpicture_max_width; 1305d8688b9Smrg surface_info[i].subpicture_max_height = 1315d8688b9Smrg sinfo.subpicture_max_height; 1325d8688b9Smrg surface_info[i].mc_type = (int) sinfo.mc_type; 1335d8688b9Smrg surface_info[i].flags = (int) sinfo.flags; 1345d8688b9Smrg } 1355d8688b9Smrg } 1365d8688b9Smrg else 1375d8688b9Smrg _XEatDataWords(dpy, rep.length); 1386f03b1f6Smrg } 1396f03b1f6Smrg 1405d8688b9Smrg UnlockDisplay(dpy); 1415d8688b9Smrg SyncHandle(); 1426f03b1f6Smrg return surface_info; 1436f03b1f6Smrg} 1446f03b1f6Smrg 1455d8688b9SmrgXvImageFormatValues * 1465d8688b9SmrgXvMCListSubpictureTypes(Display *dpy, 1475d8688b9Smrg XvPortID port, 1485d8688b9Smrg int surface_type_id, 1495d8688b9Smrg int *count_return) 1506f03b1f6Smrg{ 1516f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 1526f03b1f6Smrg xvmcListSubpictureTypesReply rep; 1536f03b1f6Smrg xvmcListSubpictureTypesReq *req; 1546f03b1f6Smrg XvImageFormatValues *ret = NULL; 1556f03b1f6Smrg 1566f03b1f6Smrg *count_return = 0; 1576f03b1f6Smrg 1585d8688b9Smrg XvMCCheckExtension(dpy, info, NULL); 1596f03b1f6Smrg 1605d8688b9Smrg LockDisplay(dpy); 1615d8688b9Smrg XvMCGetReq(ListSubpictureTypes, req); 1625d8688b9Smrg req->port = (CARD32) port; 1635d8688b9Smrg req->surface_type_id = (CARD32) surface_type_id; 1645d8688b9Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 1655d8688b9Smrg UnlockDisplay(dpy); 1665d8688b9Smrg SyncHandle(); 1676f03b1f6Smrg return NULL; 1686f03b1f6Smrg } 1696f03b1f6Smrg 1705d8688b9Smrg if (rep.num > 0) { 171190694daSmrg if (rep.num < (INT_MAX / sizeof(XvImageFormatValues))) 172190694daSmrg ret = Xmalloc(rep.num * sizeof(XvImageFormatValues)); 1736f03b1f6Smrg 1745d8688b9Smrg if (ret) { 1755d8688b9Smrg *count_return = (int) rep.num; 1765d8688b9Smrg 1775d8688b9Smrg for (CARD32 i = 0; i < rep.num; i++) { 1785d8688b9Smrg xvImageFormatInfo Info; 1795d8688b9Smrg 1805d8688b9Smrg _XRead(dpy, (char *) (&Info), sz_xvImageFormatInfo); 1815d8688b9Smrg ret[i].id = (int) Info.id; 1825d8688b9Smrg ret[i].type = Info.type; 1835d8688b9Smrg ret[i].byte_order = Info.byte_order; 1845d8688b9Smrg memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); 1855d8688b9Smrg ret[i].bits_per_pixel = Info.bpp; 1865d8688b9Smrg ret[i].format = Info.format; 1875d8688b9Smrg ret[i].num_planes = Info.num_planes; 1885d8688b9Smrg ret[i].depth = Info.depth; 1895d8688b9Smrg ret[i].red_mask = Info.red_mask; 1905d8688b9Smrg ret[i].green_mask = Info.green_mask; 1915d8688b9Smrg ret[i].blue_mask = Info.blue_mask; 1925d8688b9Smrg ret[i].y_sample_bits = Info.y_sample_bits; 1935d8688b9Smrg ret[i].u_sample_bits = Info.u_sample_bits; 1945d8688b9Smrg ret[i].v_sample_bits = Info.v_sample_bits; 1955d8688b9Smrg ret[i].horz_y_period = Info.horz_y_period; 1965d8688b9Smrg ret[i].horz_u_period = Info.horz_u_period; 1975d8688b9Smrg ret[i].horz_v_period = Info.horz_v_period; 1985d8688b9Smrg ret[i].vert_y_period = Info.vert_y_period; 1995d8688b9Smrg ret[i].vert_u_period = Info.vert_u_period; 2005d8688b9Smrg ret[i].vert_v_period = Info.vert_v_period; 2015d8688b9Smrg memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); 2025d8688b9Smrg ret[i].scanline_order = Info.scanline_order; 2036f03b1f6Smrg } 2045d8688b9Smrg } 2055d8688b9Smrg else 2065d8688b9Smrg _XEatDataWords(dpy, rep.length); 2076f03b1f6Smrg } 2086f03b1f6Smrg 2095d8688b9Smrg UnlockDisplay(dpy); 2105d8688b9Smrg SyncHandle(); 21142941e3bSmrg return ret; 2126f03b1f6Smrg} 2136f03b1f6Smrg 21442941e3bSmrg/****************************************************************** 2156f03b1f6Smrg These are intended as a protocol interface to be used by direct 2166f03b1f6Smrg rendering libraries. They are not intended to be client viewable 2176f03b1f6Smrg functions. These will stay in place until we have a mechanism in 2186f03b1f6Smrg place similar to that of OpenGL with an libXvMCcore library. 21942941e3bSmrg*******************************************************************/ 22042941e3bSmrg 22142941e3bSmrg/* 2226f03b1f6Smrg _xvmc_create_context - 2236f03b1f6Smrg 2246f03b1f6Smrg Pass in the context with the surface_type_id, width, height, 2256f03b1f6Smrg port and flags filled out. This function will fill out the 2266f03b1f6Smrg context_id and update the width, height and flags field. 2276f03b1f6Smrg The server may return implementation-specific information 2286f03b1f6Smrg back in the priv_data. The size of that information will 2296f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 2306f03b1f6Smrg this function. If returned, the caller is responsible for 2316f03b1f6Smrg freeing it! Generally, such information is only returned if 23242941e3bSmrg an XVMC_DIRECT context was specified. 2336f03b1f6Smrg*/ 2346f03b1f6Smrg 2355d8688b9SmrgStatus 2365d8688b9Smrg_xvmc_create_context(Display *dpy, 2375d8688b9Smrg XvMCContext *context, 2385d8688b9Smrg int *priv_count, 2395d8688b9Smrg CARD32 **priv_data) 2406f03b1f6Smrg{ 2416f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 2426f03b1f6Smrg xvmcCreateContextReply rep; 2436f03b1f6Smrg xvmcCreateContextReq *req; 2446f03b1f6Smrg 2456f03b1f6Smrg *priv_count = 0; 2466f03b1f6Smrg *priv_data = NULL; 2476f03b1f6Smrg 2485d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 2496f03b1f6Smrg 2505d8688b9Smrg LockDisplay(dpy); 2515d8688b9Smrg XvMCGetReq(CreateContext, req); 2526f03b1f6Smrg context->context_id = XAllocID(dpy); 2535d8688b9Smrg req->context_id = (CARD32) context->context_id; 2545d8688b9Smrg req->port = (CARD32) context->port; 2555d8688b9Smrg req->surface_type_id = (CARD32) context->surface_type_id; 2566f03b1f6Smrg req->width = context->width; 2576f03b1f6Smrg req->height = context->height; 2585d8688b9Smrg req->flags = (CARD32) context->flags; 2595d8688b9Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 2605d8688b9Smrg UnlockDisplay(dpy); 2615d8688b9Smrg SyncHandle(); 2626f03b1f6Smrg return BadImplementation; 2636f03b1f6Smrg } 2646f03b1f6Smrg context->width = rep.width_actual; 2656f03b1f6Smrg context->height = rep.height_actual; 2665d8688b9Smrg context->flags = (int) rep.flags_return; 2675d8688b9Smrg 2685d8688b9Smrg if (rep.length) { 2695d8688b9Smrg if (rep.length < (INT_MAX >> 2)) 2705d8688b9Smrg *priv_data = Xmalloc(rep.length << 2); 2715d8688b9Smrg if (*priv_data) { 2725d8688b9Smrg _XRead(dpy, (char *) (*priv_data), rep.length << 2); 2735d8688b9Smrg *priv_count = (int) rep.length; 2745d8688b9Smrg } 2755d8688b9Smrg else 2765d8688b9Smrg _XEatDataWords(dpy, rep.length); 2776f03b1f6Smrg } 2786f03b1f6Smrg 2795d8688b9Smrg UnlockDisplay(dpy); 2805d8688b9Smrg SyncHandle(); 2816f03b1f6Smrg return Success; 2826f03b1f6Smrg} 2836f03b1f6Smrg 2845d8688b9SmrgStatus 2855d8688b9Smrg_xvmc_destroy_context(Display *dpy, XvMCContext *context) 2866f03b1f6Smrg{ 2876f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 2886f03b1f6Smrg xvmcDestroyContextReq *req; 2896f03b1f6Smrg 2905d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 2916f03b1f6Smrg 2925d8688b9Smrg LockDisplay(dpy); 2935d8688b9Smrg XvMCGetReq(DestroyContext, req); 2945d8688b9Smrg req->context_id = (CARD32) context->context_id; 2955d8688b9Smrg UnlockDisplay(dpy); 2965d8688b9Smrg SyncHandle(); 2976f03b1f6Smrg return Success; 2986f03b1f6Smrg} 2996f03b1f6Smrg 3006f03b1f6Smrg/* 3016f03b1f6Smrg _xvmc_create_surface - 3026f03b1f6Smrg 3036f03b1f6Smrg Pass the context and this function will fill out all the 30442941e3bSmrg information in the surface. 3056f03b1f6Smrg The server may return implementation-specific information 3066f03b1f6Smrg back in the priv_data. The size of that information will 3076f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 3086f03b1f6Smrg this function. If returned, the caller is responsible for 3096f03b1f6Smrg freeing it! Generally, such information is returned only if 3106f03b1f6Smrg the context was a direct context. 31142941e3bSmrg 3126f03b1f6Smrg*/ 3136f03b1f6Smrg 3145d8688b9SmrgStatus 3155d8688b9Smrg_xvmc_create_surface(Display *dpy, 3165d8688b9Smrg XvMCContext *context, 3175d8688b9Smrg XvMCSurface *surface, 3185d8688b9Smrg int *priv_count, 3195d8688b9Smrg CARD32 **priv_data) 3206f03b1f6Smrg{ 3216f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3226f03b1f6Smrg xvmcCreateSurfaceReply rep; 3236f03b1f6Smrg xvmcCreateSurfaceReq *req; 3246f03b1f6Smrg 3256f03b1f6Smrg *priv_count = 0; 3266f03b1f6Smrg *priv_data = NULL; 3276f03b1f6Smrg 3285d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 3296f03b1f6Smrg 3305d8688b9Smrg LockDisplay(dpy); 3315d8688b9Smrg XvMCGetReq(CreateSurface, req); 3326f03b1f6Smrg 3336f03b1f6Smrg surface->surface_id = XAllocID(dpy); 3346f03b1f6Smrg surface->context_id = context->context_id; 3356f03b1f6Smrg surface->surface_type_id = context->surface_type_id; 3366f03b1f6Smrg surface->width = context->width; 3376f03b1f6Smrg surface->height = context->height; 3386f03b1f6Smrg 3395d8688b9Smrg req->surface_id = (CARD32) surface->surface_id; 3405d8688b9Smrg req->context_id = (CARD32) surface->context_id; 3415d8688b9Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 3425d8688b9Smrg UnlockDisplay(dpy); 3435d8688b9Smrg SyncHandle(); 3446f03b1f6Smrg return BadImplementation; 3456f03b1f6Smrg } 3466f03b1f6Smrg 3475d8688b9Smrg if (rep.length) { 348cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 349cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 3505d8688b9Smrg if (*priv_data) { 3515d8688b9Smrg _XRead(dpy, (char *) (*priv_data), rep.length << 2); 3525d8688b9Smrg *priv_count = (int) rep.length; 3535d8688b9Smrg } 3545d8688b9Smrg else 355cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 3566f03b1f6Smrg } 3576f03b1f6Smrg 3585d8688b9Smrg UnlockDisplay(dpy); 3595d8688b9Smrg SyncHandle(); 3606f03b1f6Smrg return Success; 3616f03b1f6Smrg} 3626f03b1f6Smrg 3635d8688b9SmrgStatus 3645d8688b9Smrg_xvmc_destroy_surface(Display *dpy, XvMCSurface *surface) 3656f03b1f6Smrg{ 3666f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 3676f03b1f6Smrg xvmcDestroySurfaceReq *req; 3686f03b1f6Smrg 3695d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 3706f03b1f6Smrg 3715d8688b9Smrg LockDisplay(dpy); 3725d8688b9Smrg XvMCGetReq(DestroySurface, req); 3735d8688b9Smrg req->surface_id = (CARD32) surface->surface_id; 3745d8688b9Smrg UnlockDisplay(dpy); 3755d8688b9Smrg SyncHandle(); 3766f03b1f6Smrg return Success; 3776f03b1f6Smrg} 3786f03b1f6Smrg 3796f03b1f6Smrg/* 3806f03b1f6Smrg _xvmc_create_subpicture - 3816f03b1f6Smrg 3826f03b1f6Smrg Pass the subpicture with the width, height and xvimage_id filled 3836f03b1f6Smrg out and this function will fill out everything else in the 3846f03b1f6Smrg subpicture as well as adjust the width and height if needed. 3856f03b1f6Smrg The server may return implementation-specific information 3866f03b1f6Smrg back in the priv_data. The size of that information will 3876f03b1f6Smrg an array of priv_count CARD32s. This data is allocated by 3886f03b1f6Smrg this function. If returned, the caller is responsible for 3896f03b1f6Smrg freeing it! Generally, such information is returned only if 3906f03b1f6Smrg the context was a direct context. 3916f03b1f6Smrg 3926f03b1f6Smrg*/ 3936f03b1f6Smrg 3945d8688b9SmrgStatus 3955d8688b9Smrg_xvmc_create_subpicture(Display *dpy, 3965d8688b9Smrg XvMCContext *context, 3975d8688b9Smrg XvMCSubpicture *subpicture, 3985d8688b9Smrg int *priv_count, 3995d8688b9Smrg CARD32 **priv_data) 4006f03b1f6Smrg{ 4016f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4026f03b1f6Smrg xvmcCreateSubpictureReply rep; 4036f03b1f6Smrg xvmcCreateSubpictureReq *req; 4046f03b1f6Smrg 4056f03b1f6Smrg *priv_count = 0; 4066f03b1f6Smrg *priv_data = NULL; 4076f03b1f6Smrg 4085d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 4096f03b1f6Smrg 4105d8688b9Smrg LockDisplay(dpy); 4115d8688b9Smrg XvMCGetReq(CreateSubpicture, req); 4126f03b1f6Smrg 4136f03b1f6Smrg subpicture->subpicture_id = XAllocID(dpy); 4146f03b1f6Smrg subpicture->context_id = context->context_id; 4156f03b1f6Smrg 4165d8688b9Smrg req->subpicture_id = (CARD32) subpicture->subpicture_id; 4175d8688b9Smrg req->context_id = (CARD32) subpicture->context_id; 4185d8688b9Smrg req->xvimage_id = (CARD32) subpicture->xvimage_id; 4196f03b1f6Smrg req->width = subpicture->width; 4206f03b1f6Smrg req->height = subpicture->height; 4215d8688b9Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 4225d8688b9Smrg UnlockDisplay(dpy); 4235d8688b9Smrg SyncHandle(); 4246f03b1f6Smrg return BadImplementation; 4256f03b1f6Smrg } 4266f03b1f6Smrg 4276f03b1f6Smrg subpicture->width = rep.width_actual; 4286f03b1f6Smrg subpicture->height = rep.height_actual; 4296f03b1f6Smrg subpicture->num_palette_entries = rep.num_palette_entries; 4306f03b1f6Smrg subpicture->entry_bytes = rep.entry_bytes; 4315d8688b9Smrg subpicture->component_order[0] = (char) rep.component_order[0]; 4325d8688b9Smrg subpicture->component_order[1] = (char) rep.component_order[1]; 4335d8688b9Smrg subpicture->component_order[2] = (char) rep.component_order[2]; 4345d8688b9Smrg subpicture->component_order[3] = (char) rep.component_order[3]; 4356f03b1f6Smrg 4365d8688b9Smrg if (rep.length) { 437cc1b55f9Smrg if (rep.length < (INT_MAX >> 2)) 438cc1b55f9Smrg *priv_data = Xmalloc(rep.length << 2); 4395d8688b9Smrg if (*priv_data) { 4405d8688b9Smrg _XRead(dpy, (char *) (*priv_data), rep.length << 2); 4415d8688b9Smrg *priv_count = (int) rep.length; 4425d8688b9Smrg } 4435d8688b9Smrg else 444cc1b55f9Smrg _XEatDataWords(dpy, rep.length); 4456f03b1f6Smrg } 4466f03b1f6Smrg 4475d8688b9Smrg UnlockDisplay(dpy); 4485d8688b9Smrg SyncHandle(); 4496f03b1f6Smrg return Success; 4506f03b1f6Smrg} 4516f03b1f6Smrg 4525d8688b9SmrgStatus 4535d8688b9Smrg_xvmc_destroy_subpicture(Display *dpy, XvMCSubpicture *subpicture) 4546f03b1f6Smrg{ 4556f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4566f03b1f6Smrg xvmcDestroySubpictureReq *req; 4576f03b1f6Smrg 4585d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 4596f03b1f6Smrg 4605d8688b9Smrg LockDisplay(dpy); 4615d8688b9Smrg XvMCGetReq(DestroySubpicture, req); 4625d8688b9Smrg req->subpicture_id = (CARD32) subpicture->subpicture_id; 4635d8688b9Smrg UnlockDisplay(dpy); 4645d8688b9Smrg SyncHandle(); 4656f03b1f6Smrg return Success; 4666f03b1f6Smrg} 4676f03b1f6Smrg 4685d8688b9SmrgStatus 4695d8688b9SmrgXvMCGetDRInfo(Display *dpy, XvPortID port, 4705d8688b9Smrg char **name, char **busID, 4715d8688b9Smrg int *major, int *minor, 4725d8688b9Smrg int *patchLevel, 4735d8688b9Smrg int *isLocal) 4746f03b1f6Smrg{ 4756f03b1f6Smrg XExtDisplayInfo *info = xvmc_find_display(dpy); 4766f03b1f6Smrg xvmcGetDRInfoReply rep; 4776f03b1f6Smrg xvmcGetDRInfoReq *req; 4786f03b1f6Smrg 47942941e3bSmrg#ifdef HAVE_SHMAT 4807448d6e9Smrg int shmKey; 4816f03b1f6Smrg volatile CARD32 *shMem; 4826f03b1f6Smrg#endif 4836f03b1f6Smrg 484190694daSmrg *name = NULL; 485190694daSmrg *busID = NULL; 486190694daSmrg 4875d8688b9Smrg XvMCCheckExtension(dpy, info, BadImplementation); 4886f03b1f6Smrg 4895d8688b9Smrg LockDisplay(dpy); 4905d8688b9Smrg XvMCGetReq(GetDRInfo, req); 4916f03b1f6Smrg 4925d8688b9Smrg req->port = (CARD32) port; 4936f03b1f6Smrg req->magic = 0; 49442941e3bSmrg#ifdef HAVE_SHMAT 4957448d6e9Smrg shmKey = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0600); 4967448d6e9Smrg req->shmKey = (CARD32) shmKey; 4976f03b1f6Smrg 4986f03b1f6Smrg /* 4996f03b1f6Smrg * We fill a shared memory page with a repetitive pattern. If the 5006f03b1f6Smrg * X server can read this pattern, we probably have a local connection. 5016f03b1f6Smrg * Note that we can trigger the remote X server to read any shared 5026f03b1f6Smrg * page on the remote machine, so we shouldn't be able to guess and verify 5034e5182b7Smrg * any complicated data on those pages. That's the explanation of this 5046f03b1f6Smrg * otherwise stupid-looking pattern algorithm. 5056f03b1f6Smrg */ 50642941e3bSmrg 5077448d6e9Smrg if (shmKey >= 0) { 5085d8688b9Smrg shMem = (CARD32 *) shmat(shmKey, NULL, 0); 5095d8688b9Smrg shmctl(shmKey, IPC_RMID, NULL); 5105d8688b9Smrg if (shMem != (void *) -1) { 5115d8688b9Smrg 5125d8688b9Smrg register volatile CARD32 *shMemC = shMem; 5135d8688b9Smrg register int i; 5145d8688b9Smrg CARD32 magic; 5155d8688b9Smrg struct timezone here = {0, 0}; 5165d8688b9Smrg struct timeval now; 5175d8688b9Smrg 5185d8688b9Smrg gettimeofday(&now, &here); 5195d8688b9Smrg magic = now.tv_usec & 0x000FFFFF; 5205d8688b9Smrg req->magic = magic; 5215d8688b9Smrg i = 1024 / sizeof(CARD32); 5225d8688b9Smrg while (i--) { 5235d8688b9Smrg *shMemC++ = magic; 5245d8688b9Smrg magic = ~magic; 5255d8688b9Smrg } 5265d8688b9Smrg } 5275d8688b9Smrg else { 5285d8688b9Smrg req->shmKey = (CARD32) -1; 5295d8688b9Smrg shmKey = -1; 5305d8688b9Smrg } 5316f03b1f6Smrg } 5326f03b1f6Smrg#else 5336f03b1f6Smrg req->shmKey = 0; 5346f03b1f6Smrg#endif 5355d8688b9Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 5365d8688b9Smrg UnlockDisplay(dpy); 5375d8688b9Smrg SyncHandle(); 53842941e3bSmrg#ifdef HAVE_SHMAT 5395d8688b9Smrg if (shmKey >= 0) { 5405d8688b9Smrg shmdt((const void *) shMem); 5415d8688b9Smrg } 5426f03b1f6Smrg#endif 5436f03b1f6Smrg return -1; 5446f03b1f6Smrg } 54542941e3bSmrg#ifdef HAVE_SHMAT 5467448d6e9Smrg if (shmKey >= 0) { 5475d8688b9Smrg shmdt((const void *) shMem); 5487448d6e9Smrg } 5496f03b1f6Smrg#endif 5506f03b1f6Smrg 5516f03b1f6Smrg if (rep.length > 0) { 5525d8688b9Smrg unsigned long realSize = 0; 5535d8688b9Smrg char *tmpBuf = NULL; 5545d8688b9Smrg 5555d8688b9Smrg if ((rep.length < (INT_MAX >> 2)) && 5565d8688b9Smrg /* protect against overflow in strncpy below */ 5575d8688b9Smrg (rep.nameLen + rep.busIDLen > rep.nameLen)) { 5585d8688b9Smrg realSize = rep.length << 2; 5595d8688b9Smrg if (realSize >= (rep.nameLen + rep.busIDLen)) { 5605d8688b9Smrg tmpBuf = Xmalloc(realSize); 5615d8688b9Smrg *name = Xmalloc(rep.nameLen); 5625d8688b9Smrg *busID = Xmalloc(rep.busIDLen); 5635d8688b9Smrg } 5645d8688b9Smrg } 5655d8688b9Smrg 5665d8688b9Smrg if (*name && *busID && tmpBuf) { 5675d8688b9Smrg _XRead(dpy, tmpBuf, (long) realSize); 5685d8688b9Smrg strncpy(*name, tmpBuf, rep.nameLen); 5695d8688b9Smrg (*name)[rep.nameLen == 0 ? 0 : rep.nameLen - 1] = '\0'; 5705d8688b9Smrg strncpy(*busID, tmpBuf + rep.nameLen, rep.busIDLen); 5715d8688b9Smrg (*busID)[rep.busIDLen == 0 ? 0 : rep.busIDLen - 1] = '\0'; 5725d8688b9Smrg XFree(tmpBuf); 5735d8688b9Smrg } 5745d8688b9Smrg else { 5755d8688b9Smrg XFree(*name); 5765d8688b9Smrg *name = NULL; 5775d8688b9Smrg XFree(*busID); 5785d8688b9Smrg *busID = NULL; 5795d8688b9Smrg XFree(tmpBuf); 5805d8688b9Smrg 5815d8688b9Smrg _XEatDataWords(dpy, rep.length); 5825d8688b9Smrg UnlockDisplay(dpy); 5835d8688b9Smrg SyncHandle(); 5845d8688b9Smrg return -1; 5855d8688b9Smrg 5865d8688b9Smrg } 5876f03b1f6Smrg } 5886f03b1f6Smrg 5895d8688b9Smrg UnlockDisplay(dpy); 5905d8688b9Smrg SyncHandle(); 5915d8688b9Smrg *major = (int) rep.major; 5925d8688b9Smrg *minor = (int) rep.minor; 5935d8688b9Smrg *patchLevel = (int) rep.patchLevel; 5947448d6e9Smrg#ifdef HAVE_SHMAT 5957448d6e9Smrg if (shmKey >= 0) 5965d8688b9Smrg *isLocal = (int) rep.isLocal; 5977448d6e9Smrg else 5987448d6e9Smrg#endif 5997448d6e9Smrg *isLocal = 1; 6006f03b1f6Smrg return (rep.length > 0) ? Success : BadImplementation; 6016f03b1f6Smrg} 602