aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/XvMC/XvMC.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/XvMC/XvMC.c')
-rw-r--r--nx-X11/lib/XvMC/XvMC.c599
1 files changed, 599 insertions, 0 deletions
diff --git a/nx-X11/lib/XvMC/XvMC.c b/nx-X11/lib/XvMC/XvMC.c
new file mode 100644
index 000000000..8db64098c
--- /dev/null
+++ b/nx-X11/lib/XvMC/XvMC.c
@@ -0,0 +1,599 @@
+/* $XFree86: xc/lib/XvMC/XvMC.c,v 1.4 2001/11/14 21:54:38 mvojkovi Exp $ */
+
+#define NEED_REPLIES
+
+#include <stdio.h>
+#include "XvMClibint.h"
+#ifdef HAS_SHM
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif /* Lynx */
+#endif /* HAS_SHM */
+#include <unistd.h>
+#include <sys/time.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+
+static XExtensionInfo _xvmc_info_data;
+static XExtensionInfo *xvmc_info = &_xvmc_info_data;
+static char *xvmc_extension_name = XvMCName;
+
+static char *xvmc_error_list[] =
+{
+ "BadContext",
+ "BadSurface",
+ "BadSubpicture"
+};
+
+static XEXT_GENERATE_CLOSE_DISPLAY (xvmc_close_display, xvmc_info)
+
+
+static XEXT_GENERATE_ERROR_STRING (xvmc_error_string, xvmc_extension_name,
+ XvMCNumErrors, xvmc_error_list)
+
+
+static XExtensionHooks xvmc_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ xvmc_close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ xvmc_error_string /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (xvmc_find_display, xvmc_info,
+ xvmc_extension_name,
+ &xvmc_extension_hooks,
+ XvMCNumEvents, NULL)
+
+Bool XvMCQueryExtension (Display *dpy, int *event_basep, int *error_basep)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ return True;
+ } else {
+ return False;
+ }
+}
+
+Status XvMCQueryVersion (Display *dpy, int *major, int *minor)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcQueryVersionReply rep;
+ xvmcQueryVersionReq *req;
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (QueryVersion, req);
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return BadImplementation;
+ }
+ *major = rep.major;
+ *minor = rep.minor;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return Success;
+}
+
+
+XvMCSurfaceInfo * XvMCListSurfaceTypes(Display *dpy, XvPortID port, int *num)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcListSurfaceTypesReply rep;
+ xvmcListSurfaceTypesReq *req;
+ XvMCSurfaceInfo *surface_info = NULL;
+
+ *num = 0;
+
+ XvMCCheckExtension (dpy, info, NULL);
+
+ LockDisplay (dpy);
+ XvMCGetReq (ListSurfaceTypes, req);
+ req->port = port;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ if(rep.num > 0) {
+ surface_info =
+ (XvMCSurfaceInfo*)Xmalloc(rep.num * sizeof(XvMCSurfaceInfo));
+
+ if(surface_info) {
+ xvmcSurfaceInfo sinfo;
+ int i;
+
+ *num = rep.num;
+
+ for(i = 0; i < rep.num; i++) {
+ _XRead(dpy, (char*)&sinfo, sizeof(xvmcSurfaceInfo));
+ surface_info[i].surface_type_id = sinfo.surface_type_id;
+ surface_info[i].chroma_format = sinfo.chroma_format;
+ surface_info[i].max_width = sinfo.max_width;
+ surface_info[i].max_height = sinfo.max_height;
+ surface_info[i].subpicture_max_width =
+ sinfo.subpicture_max_width;
+ surface_info[i].subpicture_max_height =
+ sinfo.subpicture_max_height;
+ surface_info[i].mc_type = sinfo.mc_type;
+ surface_info[i].flags = sinfo.flags;
+ }
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return surface_info;
+}
+
+
+XvImageFormatValues * XvMCListSubpictureTypes (
+ Display * dpy,
+ XvPortID port,
+ int surface_type_id,
+ int *count_return
+)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcListSubpictureTypesReply rep;
+ xvmcListSubpictureTypesReq *req;
+ XvImageFormatValues *ret = NULL;
+
+
+ *count_return = 0;
+
+ XvMCCheckExtension (dpy, info, NULL);
+
+
+ LockDisplay (dpy);
+ XvMCGetReq (ListSubpictureTypes, req);
+ req->port = port;
+ req->surface_type_id = surface_type_id;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ if(rep.num > 0) {
+ ret =
+ (XvImageFormatValues*)Xmalloc(rep.num * sizeof(XvImageFormatValues));
+
+ if(ret) {
+ xvImageFormatInfo Info;
+ int i;
+
+ *count_return = rep.num;
+
+ for(i = 0; i < rep.num; i++) {
+ _XRead(dpy, (char*)(&Info), sz_xvImageFormatInfo);
+ ret[i].id = Info.id;
+ ret[i].type = Info.type;
+ ret[i].byte_order = Info.byte_order;
+ memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16);
+ ret[i].bits_per_pixel = Info.bpp;
+ ret[i].format = Info.format;
+ ret[i].num_planes = Info.num_planes;
+ ret[i].depth = Info.depth;
+ ret[i].red_mask = Info.red_mask;
+ ret[i].green_mask = Info.green_mask;
+ ret[i].blue_mask = Info.blue_mask;
+ ret[i].y_sample_bits = Info.y_sample_bits;
+ ret[i].u_sample_bits = Info.u_sample_bits;
+ ret[i].v_sample_bits = Info.v_sample_bits;
+ ret[i].horz_y_period = Info.horz_y_period;
+ ret[i].horz_u_period = Info.horz_u_period;
+ ret[i].horz_v_period = Info.horz_v_period;
+ ret[i].vert_y_period = Info.vert_y_period;
+ ret[i].vert_u_period = Info.vert_u_period;
+ ret[i].vert_v_period = Info.vert_v_period;
+ memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32);
+ ret[i].scanline_order = Info.scanline_order;
+ }
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return ret;
+}
+
+
+/******************************************************************
+ These are intended as a protocol interface to be used by direct
+ rendering libraries. They are not intended to be client viewable
+ functions. These will stay in place until we have a mechanism in
+ place similar to that of OpenGL with an libXvMCcore library.
+*******************************************************************/
+
+/*
+ _xvmc_create_context -
+
+ Pass in the context with the surface_type_id, width, height,
+ port and flags filled out. This function will fill out the
+ context_id and update the width, height and flags field.
+ The server may return implementation-specific information
+ back in the priv_data. The size of that information will
+ an array of priv_count CARD32s. This data is allocated by
+ this function. If returned, the caller is responsible for
+ freeing it! Generally, such information is only returned if
+ an XVMC_DIRECT context was specified.
+*/
+
+
+Status _xvmc_create_context (
+ Display *dpy,
+ XvMCContext *context,
+ int *priv_count,
+ CARD32 **priv_data
+)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcCreateContextReply rep;
+ xvmcCreateContextReq *req;
+
+ *priv_count = 0;
+ *priv_data = NULL;
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (CreateContext, req);
+ context->context_id = XAllocID(dpy);
+ req->context_id = context->context_id;
+ req->port = context->port;
+ req->surface_type_id = context->surface_type_id;
+ req->width = context->width;
+ req->height = context->height;
+ req->flags = context->flags;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return BadImplementation;
+ }
+ context->width = rep.width_actual;
+ context->height = rep.height_actual;
+ context->flags = rep.flags_return;
+
+ if(rep.length) {
+ *priv_data = Xmalloc(rep.length << 2);
+ if(*priv_data) {
+ _XRead(dpy, (char*)(*priv_data), rep.length << 2);
+ *priv_count = rep.length;
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return Success;
+}
+
+Status _xvmc_destroy_context (
+ Display *dpy,
+ XvMCContext *context
+)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcDestroyContextReq *req;
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (DestroyContext, req);
+ req->context_id = context->context_id;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return Success;
+}
+
+
+/*
+ _xvmc_create_surface -
+
+ Pass the context and this function will fill out all the
+ information in the surface.
+ The server may return implementation-specific information
+ back in the priv_data. The size of that information will
+ an array of priv_count CARD32s. This data is allocated by
+ this function. If returned, the caller is responsible for
+ freeing it! Generally, such information is returned only if
+ the context was a direct context.
+
+*/
+
+Status _xvmc_create_surface (
+ Display *dpy,
+ XvMCContext *context,
+ XvMCSurface *surface,
+ int *priv_count,
+ CARD32 **priv_data
+)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcCreateSurfaceReply rep;
+ xvmcCreateSurfaceReq *req;
+
+ *priv_count = 0;
+ *priv_data = NULL;
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (CreateSurface, req);
+
+ surface->surface_id = XAllocID(dpy);
+ surface->context_id = context->context_id;
+ surface->surface_type_id = context->surface_type_id;
+ surface->width = context->width;
+ surface->height = context->height;
+
+ req->surface_id = surface->surface_id;
+ req->context_id = surface->context_id;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return BadImplementation;
+ }
+
+ if(rep.length) {
+ *priv_data = Xmalloc(rep.length << 2);
+ if(*priv_data) {
+ _XRead(dpy, (char*)(*priv_data), rep.length << 2);
+ *priv_count = rep.length;
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return Success;
+}
+
+Status _xvmc_destroy_surface (
+ Display *dpy,
+ XvMCSurface *surface
+)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcDestroySurfaceReq *req;
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (DestroySurface, req);
+ req->surface_id = surface->surface_id;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return Success;
+}
+
+/*
+ _xvmc_create_subpicture -
+
+ Pass the subpicture with the width, height and xvimage_id filled
+ out and this function will fill out everything else in the
+ subpicture as well as adjust the width and height if needed.
+ The server may return implementation-specific information
+ back in the priv_data. The size of that information will
+ an array of priv_count CARD32s. This data is allocated by
+ this function. If returned, the caller is responsible for
+ freeing it! Generally, such information is returned only if
+ the context was a direct context.
+
+*/
+
+Status _xvmc_create_subpicture (
+ Display *dpy,
+ XvMCContext *context,
+ XvMCSubpicture *subpicture,
+ int *priv_count,
+ CARD32 **priv_data
+)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcCreateSubpictureReply rep;
+ xvmcCreateSubpictureReq *req;
+
+ *priv_count = 0;
+ *priv_data = NULL;
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (CreateSubpicture, req);
+
+ subpicture->subpicture_id = XAllocID(dpy);
+ subpicture->context_id = context->context_id;
+
+ req->subpicture_id = subpicture->subpicture_id;
+ req->context_id = subpicture->context_id;
+ req->xvimage_id = subpicture->xvimage_id;
+ req->width = subpicture->width;
+ req->height = subpicture->height;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return BadImplementation;
+ }
+
+ subpicture->width = rep.width_actual;
+ subpicture->height = rep.height_actual;
+ subpicture->num_palette_entries = rep.num_palette_entries;
+ subpicture->entry_bytes = rep.entry_bytes;
+ subpicture->component_order[0] = rep.component_order[0];
+ subpicture->component_order[1] = rep.component_order[1];
+ subpicture->component_order[2] = rep.component_order[2];
+ subpicture->component_order[3] = rep.component_order[3];
+
+ if(rep.length) {
+ *priv_data = Xmalloc(rep.length << 2);
+ if(*priv_data) {
+ _XRead(dpy, (char*)(*priv_data), rep.length << 2);
+ *priv_count = rep.length;
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return Success;
+}
+
+Status _xvmc_destroy_subpicture(
+ Display *dpy,
+ XvMCSubpicture *subpicture
+)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcDestroySubpictureReq *req;
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (DestroySubpicture, req);
+ req->subpicture_id = subpicture->subpicture_id;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return Success;
+}
+
+Status XvMCGetDRInfo(Display *dpy, XvPortID port,
+ char **name, char **busID,
+ int *major, int *minor,
+ int *patchLevel,
+ int *isLocal)
+{
+ XExtDisplayInfo *info = xvmc_find_display(dpy);
+ xvmcGetDRInfoReply rep;
+ xvmcGetDRInfoReq *req;
+ char *tmpBuf = NULL;
+ CARD32 magic;
+
+#ifdef HAS_SHM
+ volatile CARD32 *shMem;
+ struct timezone here;
+ struct timeval now;
+ here.tz_minuteswest = 0;
+ here.tz_dsttime = 0;
+#endif
+
+ XvMCCheckExtension (dpy, info, BadImplementation);
+
+ LockDisplay (dpy);
+ XvMCGetReq (GetDRInfo, req);
+
+ req->port = port;
+ magic = 0;
+ req->magic = 0;
+#ifdef HAS_SHM
+ req->shmKey = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0600);
+
+ /*
+ * We fill a shared memory page with a repetitive pattern. If the
+ * X server can read this pattern, we probably have a local connection.
+ * Note that we can trigger the remote X server to read any shared
+ * page on the remote machine, so we shouldn't be able to guess and verify
+ * any complicated data on those pages. Thats the explanation of this
+ * otherwise stupid-looking pattern algorithm.
+ */
+
+ if (req->shmKey >= 0) {
+ shMem = (CARD32 *) shmat(req->shmKey, 0, 0);
+ shmctl( req->shmKey, IPC_RMID, 0);
+ if ( shMem ) {
+
+ register volatile CARD32 *shMemC = shMem;
+ register int i;
+
+ gettimeofday( &now, &here);
+ magic = now.tv_usec & 0x000FFFFF;
+ req->magic = magic;
+ i = 1024 / sizeof(CARD32);
+ while(i--) {
+ *shMemC++ = magic;
+ magic = ~magic;
+ }
+ } else {
+ req->shmKey = -1;
+ }
+ }
+#else
+ req->shmKey = 0;
+#endif
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+#ifdef HAS_SHM
+ if ( req->shmKey >= 0) {
+ shmdt( (const void *) shMem );
+ }
+#endif
+ return -1;
+ }
+#ifdef HAS_SHM
+ shmdt( (const void *) shMem );
+#endif
+
+ if (rep.length > 0) {
+
+ int realSize = rep.length << 2;
+
+ tmpBuf = (char *) Xmalloc(realSize);
+ if (tmpBuf) {
+ *name = (char *) Xmalloc(rep.nameLen);
+ if (*name) {
+ *busID = (char *) Xmalloc(rep.busIDLen);
+ if (! *busID) {
+ XFree(*name);
+ XFree(tmpBuf);
+ }
+ } else {
+ XFree(tmpBuf);
+ }
+ }
+
+ if (*name && *busID && tmpBuf) {
+
+ _XRead(dpy, tmpBuf, realSize);
+ strncpy(*name,tmpBuf,rep.nameLen);
+ strncpy(*busID,tmpBuf+rep.nameLen,rep.busIDLen);
+ XFree(tmpBuf);
+
+ } else {
+
+ _XEatData(dpy, realSize);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return -1;
+
+ }
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *major = rep.major;
+ *minor = rep.minor;
+ *patchLevel = rep.patchLevel;
+ *isLocal = (req->shmKey > 0) ? rep.isLocal : 1;
+ return (rep.length > 0) ? Success : BadImplementation;
+}
+