diff options
author | daryll <daryll> | 1999-12-05 00:59:08 +0000 |
---|---|---|
committer | daryll <daryll> | 1999-12-05 00:59:08 +0000 |
commit | 504880db5611bf0f57206abe44835959c2729147 (patch) | |
tree | f22ff902680775b5a6fb49364d305b846606716a /xc/lib/Xv/Xv.c |
Initial revision
Diffstat (limited to 'xc/lib/Xv/Xv.c')
-rw-r--r-- | xc/lib/Xv/Xv.c | 873 |
1 files changed, 873 insertions, 0 deletions
diff --git a/xc/lib/Xv/Xv.c b/xc/lib/Xv/Xv.c new file mode 100644 index 000000000..0b14d55a0 --- /dev/null +++ b/xc/lib/Xv/Xv.c @@ -0,0 +1,873 @@ +/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/lib/Xv/Xv.c,v 1.8 1999/05/23 06:33:31 dawes Exp $ */ +/* +** File: +** +** Xv.c --- Xv library extension module. +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 26.06.91 Carver +** - changed XvFreeAdaptors to XvFreeAdaptorInfo +** - changed XvFreeEncodings to XvFreeEncodingInfo +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 240.01.91 Carver +** - version 1.4 upgrade +** +*/ + +#include "Xvlibint.h" +#include "extutil.h" + +static XExtCodes *_XvCodes; +static Bool (* _XvOldWireToEventVideo)(); +static Bool (* _XvOldWireToEventPort)(); +static char *(* _XvOldErrorString)(); + +static Bool _XvWireToEvent(); +static char *_XvErrorString(); + +#define PREAMBLE(stat) \ + LockDisplay(dpy); \ + if ((!_XvCodes) && (!_XvInitExtension(dpy))) \ + { \ + UnlockDisplay(dpy); SyncHandle(); return (stat); \ + } + +#define POSTAMBLE \ + UnlockDisplay(dpy); \ + SyncHandle() + +int +XvQueryExtension( + Display *dpy, + unsigned int *p_version, + unsigned int *p_revision, + unsigned int *p_requestBase, + unsigned int *p_eventBase, + unsigned int *p_errorBase +){ + xvQueryExtensionReq *req; + xvQueryExtensionReply rep; + + PREAMBLE(XvBadExtension); + + XvGetReq(QueryExtension, req); + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) + { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadExtension); + } + + *p_version = rep.version; + *p_revision = rep.revision; + *p_requestBase = _XvCodes->major_opcode; + *p_eventBase = _XvCodes->first_event; + *p_errorBase = _XvCodes->first_error; + + return Success; +} + +int +XvQueryAdaptors( + Display *dpy, + Window window, + unsigned int *p_nAdaptors, + XvAdaptorInfo **p_pAdaptors +){ + xvQueryAdaptorsReq *req; + xvQueryAdaptorsReply rep; + int size,ii,jj; + char *name; + XvAdaptorInfo *pas, *pa; + XvFormat *pfs, *pf; + char *buffer; + union + { + char *buffer; + char *string; + xvAdaptorInfo *pa; + xvFormat *pf; + } u; + + PREAMBLE(XvBadExtension); + + XvGetReq(QueryAdaptors, req); + req->window = window; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) + { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + size = rep.length << 2; + if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) + { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + _XRead (dpy, buffer, size); + + u.buffer = buffer; + + /* GET INPUT ADAPTORS */ + + size = rep.num_adaptors*sizeof(XvAdaptorInfo); + if ((pas=(XvAdaptorInfo *)Xmalloc(size))==NULL) + { + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + + /* INIT ADAPTOR FIELDS */ + + pa = pas; + for (ii=0; ii<rep.num_adaptors; ii++) + { + pa->num_adaptors = 0; + pa->name = (char *)NULL; + pa->formats = (XvFormat *)NULL; + } + + pa = pas; + for (ii=0; ii<rep.num_adaptors; ii++) + { + pa->type = u.pa->type; + pa->base_id = u.pa->base_id; + pa->num_ports = u.pa->num_ports; + pa->num_formats = u.pa->num_formats; + pa->num_adaptors = rep.num_adaptors - ii; + + /* GET ADAPTOR NAME */ + + size = u.pa->name_size; + u.buffer += (sz_xvAdaptorInfo + 3) & ~3; + + if ( (name = (char *)Xmalloc(size+1)) == NULL) + { + XvFreeAdaptorInfo(pas); + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + (void)strncpy(name, u.string, size); + name[size] = '\0'; + pa->name = name; + + u.buffer += (size + 3) & ~3; + + /* GET FORMATS */ + + size = pa->num_formats*sizeof(XvFormat); + if ((pfs=(XvFormat *)Xmalloc(size))==NULL) + { + XvFreeAdaptorInfo(pas); + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + + pf = pfs; + for (jj=0; jj<pa->num_formats; jj++) + { + pf->depth = u.pf->depth; + pf->visual_id = u.pf->visual; + pf++; + + u.buffer += (sz_xvFormat + 3) & ~3; + } + + pa->formats = pfs; + + pa++; + + } + + *p_nAdaptors = rep.num_adaptors; + *p_pAdaptors = pas; + + POSTAMBLE; + + return (Success); +} + + +void +XvFreeAdaptorInfo(XvAdaptorInfo *pAdaptors) +{ + + XvAdaptorInfo *pa; + int ii; + + if (!pAdaptors) return; + + pa = pAdaptors; + + for (ii=0; ii<pAdaptors->num_adaptors; ii++, pa++) + { + if (pa->name) + { + Xfree(pa->name); + } + if (pa->formats) + { + Xfree(pa->formats); + } + } + + Xfree(pAdaptors); +} + +int +XvQueryEncodings( + Display *dpy, + XvPortID port, + unsigned int *p_nEncodings, + XvEncodingInfo **p_pEncodings +){ + xvQueryEncodingsReq *req; + xvQueryEncodingsReply rep; + int size, jj; + char *name; + XvEncodingInfo *pes, *pe; + char *buffer; + union + { + char *buffer; + char *string; + xvEncodingInfo *pe; + } u; + + PREAMBLE(XvBadExtension); + + XvGetReq(QueryEncodings, req); + req->port = port; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) + { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + size = rep.length << 2; + if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) + { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + _XRead (dpy, buffer, size); + + u.buffer = buffer; + + /* GET ENCODINGS */ + + size = rep.num_encodings*sizeof(XvEncodingInfo); + if ( (pes = (XvEncodingInfo *)Xmalloc(size)) == NULL) + { + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + + /* INITIALIZE THE ENCODING POINTER */ + + pe = pes; + for (jj=0; jj<rep.num_encodings; jj++) + { + pe->name = (char *)NULL; + pe->num_encodings = 0; + pe++; + } + + pe = pes; + for (jj=0; jj<rep.num_encodings; jj++) + { + pe->encoding_id = u.pe->encoding; + pe->width = u.pe->width; + pe->height = u.pe->height; + pe->rate.numerator = u.pe->rate.numerator; + pe->rate.denominator = u.pe->rate.denominator; + pe->num_encodings = rep.num_encodings - jj; + + size = u.pe->name_size; + u.buffer += (sz_xvEncodingInfo + 3) & ~3; + + if ( (name = (char *)Xmalloc(size+1)) == NULL) + { + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + strncpy(name, u.string, size); + name[size] = '\0'; + pe->name = name; + pe++; + + u.buffer += (size + 3) & ~3; + + } + + *p_nEncodings = rep.num_encodings; + *p_pEncodings = pes; + + POSTAMBLE; + + return (Success); +} + +void +XvFreeEncodingInfo(XvEncodingInfo *pEncodings) +{ + + XvEncodingInfo *pe; + int ii; + + if (!pEncodings) return; + + pe = pEncodings; + + for (ii=0; ii<pEncodings->num_encodings; ii++, pe++) + { + if (pe->name) Xfree(pe->name); + } + + Xfree(pEncodings); + +} + +int +XvPutVideo( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + xvPutVideoReq *req; + + PREAMBLE(XvBadExtension); + + FlushGC(dpy, gc); + + XvGetReq(PutVideo, req); + + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + POSTAMBLE; + + return Success; +} + +int +XvPutStill( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + xvPutStillReq *req; + + PREAMBLE(XvBadExtension); + + FlushGC(dpy, gc); + + XvGetReq(PutStill, req); + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + POSTAMBLE; + + return Success; +} + +int +XvGetVideo( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + xvGetVideoReq *req; + + PREAMBLE(XvBadExtension); + + FlushGC(dpy, gc); + + XvGetReq(GetVideo, req); + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + POSTAMBLE; + + return Success; +} + +int +XvGetStill( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + xvGetStillReq *req; + + PREAMBLE(XvBadExtension); + + FlushGC(dpy, gc); + + XvGetReq(GetStill, req); + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + POSTAMBLE; + + return Success; +} + +int +XvStopVideo( + Display *dpy, + XvPortID port, + Drawable draw +){ + xvStopVideoReq *req; + + PREAMBLE(XvBadExtension); + + XvGetReq(StopVideo, req); + req->port = port; + req->drawable = draw; + + POSTAMBLE; + + return Success; +} + +int +XvGrabPort( + Display *dpy, + XvPortID port, + Time time +){ + int result; + xvGrabPortReply rep; + xvGrabPortReq *req; + + PREAMBLE(XvBadExtension); + + XvGetReq(GrabPort, req); + req->port = port; + req->time = time; + + if (_XReply (dpy, (xReply *) &rep, 0, xTrue) == 0) + rep.result = GrabSuccess; + + result = rep.result; + + POSTAMBLE; + + return result; +} + +int +XvUngrabPort( + Display *dpy, + XvPortID port, + Time time +){ + xvUngrabPortReq *req; + + PREAMBLE(XvBadExtension); + + XvGetReq(UngrabPort, req); + req->port = port; + req->time = time; + + POSTAMBLE; + + return Success; +} + +int +XvSelectVideoNotify( + Display *dpy, + Drawable drawable, + Bool onoff +){ + register xvSelectVideoNotifyReq *req; + + PREAMBLE(XvBadExtension); + + XvGetReq(SelectVideoNotify, req); + req->drawable = drawable; + req->onoff = onoff; + + POSTAMBLE; + + return Success; +} + +int +XvSelectPortNotify( + Display *dpy, + XvPortID port, + Bool onoff +){ + xvSelectPortNotifyReq *req; + + PREAMBLE(XvBadExtension); + + XvGetReq(SelectPortNotify, req); + req->port = port; + req->onoff = onoff; + + POSTAMBLE; + + return Success; +} + +int +XvSetPortAttribute (dpy, port, attribute, value) + register Display *dpy; + XvPortID port; + Atom attribute; + int value; +{ + register xvSetPortAttributeReq *req; + + PREAMBLE(XvBadExtension); + + XvGetReq(SetPortAttribute, req); + req->port = port; + req->attribute = attribute; + req->value = value; + + POSTAMBLE; + + return (Success); +} + +int +XvGetPortAttribute (dpy, port, attribute, p_value) + register Display *dpy; + XvPortID port; + Atom attribute; + int *p_value; +{ + register xvGetPortAttributeReq *req; + xvGetPortAttributeReply rep; + + PREAMBLE(XvBadExtension); + + XvGetReq(GetPortAttribute, req); + req->port = port; + req->attribute = attribute; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) + { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + *p_value = rep.value; + + POSTAMBLE; + + return (Success); +} + +int +XvQueryBestSize(dpy, port, motion, vid_w, vid_h, drw_w, drw_h, + p_actual_width, p_actual_height) + register Display *dpy; + XvPortID port; + Bool motion; + unsigned int vid_w, vid_h; + unsigned int drw_w, drw_h; + unsigned int *p_actual_width, *p_actual_height; +{ + register xvQueryBestSizeReq *req; + xvQueryBestSizeReply rep; + + PREAMBLE(XvBadExtension); + + XvGetReq(QueryBestSize, req); + req->port = port; + req->motion = motion; + req->vid_w = vid_w; + req->vid_h = vid_h; + req->drw_w = drw_w; + req->drw_h = drw_h; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) + { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + *p_actual_width = rep.actual_width; + *p_actual_height = rep.actual_height; + + POSTAMBLE; + + return (Success); +} + + +XvAttribute* +XvQueryPortAttributes(Display *dpy, XvPortID port, int *num) +{ + xvQueryPortAttributesReq *req; + xvQueryPortAttributesReply rep; + XvAttribute *ret = NULL; + + *num = 0; + + PREAMBLE(NULL); + + XvGetReq(QueryPortAttributes, req); + req->port = port; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return ret; + } + + if(rep.num_attributes) { + int size = (rep.num_attributes * sizeof(XvAttribute)) + rep.text_size; + + if((ret = Xmalloc(size))) { + char* marker = (char*)(&ret[rep.num_attributes]); + xvAttributeInfo Info; + int i; + + for(i = 0; i < rep.num_attributes; i++) { + _XRead(dpy, (char*)(&Info), sz_xvAttributeInfo); + ret[i].flags = (int)Info.flags; + ret[i].name = marker; + _XRead(dpy, marker, Info.size); + marker += Info.size; + (*num)++; + } + } else + _XEatData(dpy, rep.length << 2); + } + + POSTAMBLE; + + return ret; +} + +static Bool +_XvWireToEvent(Display *dpy, XvEvent *re, xvEvent *event) +{ + + if (event->u.u.type == _XvCodes->first_event+XvVideoNotify) + { + re->xvvideo.type = event->u.u.type & 0x7f; + re->xvvideo.serial = + _XSetLastRequestRead(dpy, (xGenericReply *)event); + re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); + re->xvvideo.display = dpy; + re->xvvideo.time = event->u.videoNotify.time; + re->xvvideo.reason = event->u.videoNotify.reason; + re->xvvideo.drawable = event->u.videoNotify.drawable; + re->xvvideo.port_id = event->u.videoNotify.port; + if (_XvOldWireToEventVideo) + { + (void)(* _XvOldWireToEventVideo)(dpy, re, event); + } + } + else if (event->u.u.type == _XvCodes->first_event+XvPortNotify) + { + re->xvport.type = event->u.u.type & 0x7f; + re->xvport.serial = + _XSetLastRequestRead(dpy, (xGenericReply *)event); + re->xvport.send_event = ((event->u.u.type & 0x80) != 0); + re->xvport.display = dpy; + re->xvport.time = event->u.portNotify.time; + re->xvport.port_id = event->u.portNotify.port; + re->xvport.attribute = event->u.portNotify.attribute; + re->xvport.value = event->u.portNotify.value; + if (_XvOldWireToEventPort) + { + (void)(* _XvOldWireToEventPort)(dpy, re, event); + } + } + else + { + return (False); + } + + return (True); +} + +Bool +_XvInitExtension(Display *dpy) +{ + if (!(_XvCodes = XInitExtension (dpy, XvName))) + { + return False; + } + + _XvOldWireToEventVideo = + XESetWireToEvent(dpy, + _XvCodes->first_event + XvVideoNotify, + _XvWireToEvent); + + _XvOldWireToEventPort = + XESetWireToEvent(dpy, + _XvCodes->first_event + XvPortNotify, + _XvWireToEvent); + + _XvOldErrorString = XESetErrorString(dpy, _XvCodes->extension, + _XvErrorString); + + return True; +} + +static char * +_XvErrorString( + Display *dpy, + int code, + XExtCodes *ecodes, + char *buffer, + int size +){ + + if (size < strlen("Encoding") + 1) + { + if (_XvOldErrorString) + return (* _XvOldErrorString)(dpy, code, ecodes, buffer, size); + } + + if (code - ecodes->first_error == XvBadPort) + { + strcpy(buffer, "Port"); + } + else if (code - ecodes->first_error == XvBadEncoding) + { + strcpy(buffer, "Encoding"); + } + else + { + if (_XvOldErrorString) + return (* _XvOldErrorString)(dpy, code, ecodes, buffer, size); + } + + return (char *)NULL; +} |