diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
commit | 9508a382f8a9f241dab097d921b6d290c1c3a776 (patch) | |
tree | fa456480bae7040c3f971a70b390f2d091c680b5 /Xext/xvdisp.c | |
parent | ded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff) |
Initial revision
Diffstat (limited to 'Xext/xvdisp.c')
-rw-r--r-- | Xext/xvdisp.c | 2214 |
1 files changed, 2214 insertions, 0 deletions
diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c new file mode 100644 index 000000000..3d321e8ae --- /dev/null +++ b/Xext/xvdisp.c @@ -0,0 +1,2214 @@ +/*********************************************************** +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/programs/Xserver/Xext/xvdisp.c,v 1.25 2001/11/18 23:55:48 mvojkovi Exp $ */ + +/* +** File: +** +** xvdisp.c --- Xv server extension dispatch module. +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 24.01.91 Carver +** - version 1.4 upgrade +** +*/ + +#include "X.h" +#include "Xproto.h" +#include "misc.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "dixstruct.h" +#include "resource.h" +#include "opaque.h" + +#include "Xv.h" +#include "Xvproto.h" +#include "xvdix.h" +#ifdef MITSHM +#define _XSHM_SERVER_ +#include "shmstr.h" +#endif + +#ifdef EXTMODULE +#include "xf86_ansic.h" +#endif + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" + +unsigned long XvXRTPort; + +#ifdef MITSHM +static int XineramaXvShmPutImage(ClientPtr); +#endif +static int XineramaXvPutImage(ClientPtr); +static int XineramaXvPutVideo(ClientPtr); +static int XineramaXvPutStill(ClientPtr); +static int XineramaXvSetPortAttribute(ClientPtr); +static int XineramaXvStopVideo(ClientPtr); +#endif + +/* INTERNAL */ + +static int ProcXvQueryExtension(ClientPtr); +static int ProcXvQueryAdaptors(ClientPtr); +static int ProcXvQueryEncodings(ClientPtr); +static int ProcXvPutVideo(ClientPtr); +static int ProcXvPutStill(ClientPtr); +static int ProcXvGetVideo(ClientPtr); +static int ProcXvGetStill(ClientPtr); +static int ProcXvGrabPort(ClientPtr); +static int ProcXvUngrabPort(ClientPtr); +static int ProcXvSelectVideoNotify(ClientPtr); +static int ProcXvSelectPortNotify(ClientPtr); +static int ProcXvStopVideo(ClientPtr); +static int ProcXvSetPortAttribute(ClientPtr); +static int ProcXvGetPortAttribute(ClientPtr); +static int ProcXvQueryBestSize(ClientPtr); +static int ProcXvQueryPortAttributes(ClientPtr); +static int ProcXvPutImage(ClientPtr); +#ifdef MITSHM +static int ProcXvShmPutImage(ClientPtr); +#endif +static int ProcXvQueryImageAttributes(ClientPtr); +static int ProcXvListImageFormats(ClientPtr); + +static int SProcXvQueryExtension(ClientPtr); +static int SProcXvQueryAdaptors(ClientPtr); +static int SProcXvQueryEncodings(ClientPtr); +static int SProcXvPutVideo(ClientPtr); +static int SProcXvPutStill(ClientPtr); +static int SProcXvGetVideo(ClientPtr); +static int SProcXvGetStill(ClientPtr); +static int SProcXvGrabPort(ClientPtr); +static int SProcXvUngrabPort(ClientPtr); +static int SProcXvSelectVideoNotify(ClientPtr); +static int SProcXvSelectPortNotify(ClientPtr); +static int SProcXvStopVideo(ClientPtr); +static int SProcXvSetPortAttribute(ClientPtr); +static int SProcXvGetPortAttribute(ClientPtr); +static int SProcXvQueryBestSize(ClientPtr); +static int SProcXvQueryPortAttributes(ClientPtr); +static int SProcXvPutImage(ClientPtr); +#ifdef MITSHM +static int SProcXvShmPutImage(ClientPtr); +#endif +static int SProcXvQueryImageAttributes(ClientPtr); +static int SProcXvListImageFormats(ClientPtr); + +static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *); +static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *); +static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *); +static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *); +static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *); +static int SWriteFormat(ClientPtr, xvFormat *); +static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *); +static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *); +static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *); +static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *); +static int SWriteQueryPortAttributesReply( + ClientPtr, xvQueryPortAttributesReply *); +static int SWriteQueryImageAttributesReply( + ClientPtr, xvQueryImageAttributesReply*); +static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*); +static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*); + +#define _WriteQueryAdaptorsReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d) + +#define _WriteQueryExtensionReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d) + +#define _WriteQueryEncodingsReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d) + +#define _WriteAdaptorInfo(_c,_d) \ + if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \ + else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d) + +#define _WriteAttributeInfo(_c,_d) \ + if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \ + else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d) + +#define _WriteEncodingInfo(_c,_d) \ + if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \ + else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d) + +#define _WriteFormat(_c,_d) \ + if ((_c)->swapped) SWriteFormat(_c, _d); \ + else WriteToClient(_c, sz_xvFormat, (char*)_d) + +#define _WriteGrabPortReply(_c,_d) \ + if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \ + else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d) + +#define _WriteGetPortAttributeReply(_c,_d) \ + if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \ + else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d) + +#define _WriteQueryBestSizeReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d) + +#define _WriteQueryPortAttributesReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d) + +#define _WriteQueryImageAttributesReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d) + +#define _WriteListImageFormatsReply(_c,_d) \ + if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \ + else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d) + +#define _WriteImageFormatInfo(_c,_d) \ + if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \ + else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d) + +#define _AllocatePort(_i,_p) \ + ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success + +/* +** ProcXvDispatch +** +** +** +*/ + +int +ProcXvDispatch(ClientPtr client) +{ + REQUEST(xReq); + + UpdateCurrentTime(); + + switch (stuff->data) + { + case xv_QueryExtension: return(ProcXvQueryExtension(client)); + case xv_QueryAdaptors: return(ProcXvQueryAdaptors(client)); + case xv_QueryEncodings: return(ProcXvQueryEncodings(client)); + case xv_PutVideo: +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return(XineramaXvPutVideo(client)); + else +#endif + return(ProcXvPutVideo(client)); + case xv_PutStill: +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return(XineramaXvPutStill(client)); + else +#endif + return(ProcXvPutStill(client)); + case xv_GetVideo: return(ProcXvGetVideo(client)); + case xv_GetStill: return(ProcXvGetStill(client)); + case xv_GrabPort: return(ProcXvGrabPort(client)); + case xv_UngrabPort: return(ProcXvUngrabPort(client)); + case xv_SelectVideoNotify: return(ProcXvSelectVideoNotify(client)); + case xv_SelectPortNotify: return(ProcXvSelectPortNotify(client)); + case xv_StopVideo: +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return(XineramaXvStopVideo(client)); + else +#endif + return(ProcXvStopVideo(client)); + case xv_SetPortAttribute: +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return(XineramaXvSetPortAttribute(client)); + else +#endif + return(ProcXvSetPortAttribute(client)); + case xv_GetPortAttribute: return(ProcXvGetPortAttribute(client)); + case xv_QueryBestSize: return(ProcXvQueryBestSize(client)); + case xv_QueryPortAttributes: return(ProcXvQueryPortAttributes(client)); + case xv_PutImage: +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return(XineramaXvPutImage(client)); + else +#endif + return(ProcXvPutImage(client)); +#ifdef MITSHM + case xv_ShmPutImage: +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return(XineramaXvShmPutImage(client)); + else +#endif + return(ProcXvShmPutImage(client)); +#endif + case xv_QueryImageAttributes: return(ProcXvQueryImageAttributes(client)); + case xv_ListImageFormats: return(ProcXvListImageFormats(client)); + default: + if (stuff->data < xvNumRequests) + { + SendErrorToClient(client, XvReqCode, stuff->data, 0, + BadImplementation); + return(BadImplementation); + } + else + { + SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); + return(BadRequest); + } + } +} + +int +SProcXvDispatch(ClientPtr client) +{ + REQUEST(xReq); + + UpdateCurrentTime(); + + switch (stuff->data) + { + case xv_QueryExtension: return(SProcXvQueryExtension(client)); + case xv_QueryAdaptors: return(SProcXvQueryAdaptors(client)); + case xv_QueryEncodings: return(SProcXvQueryEncodings(client)); + case xv_PutVideo: return(SProcXvPutVideo(client)); + case xv_PutStill: return(SProcXvPutStill(client)); + case xv_GetVideo: return(SProcXvGetVideo(client)); + case xv_GetStill: return(SProcXvGetStill(client)); + case xv_GrabPort: return(SProcXvGrabPort(client)); + case xv_UngrabPort: return(SProcXvUngrabPort(client)); + case xv_SelectVideoNotify: return(SProcXvSelectVideoNotify(client)); + case xv_SelectPortNotify: return(SProcXvSelectPortNotify(client)); + case xv_StopVideo: return(SProcXvStopVideo(client)); + case xv_SetPortAttribute: return(SProcXvSetPortAttribute(client)); + case xv_GetPortAttribute: return(SProcXvGetPortAttribute(client)); + case xv_QueryBestSize: return(SProcXvQueryBestSize(client)); + case xv_QueryPortAttributes: return(SProcXvQueryPortAttributes(client)); + case xv_PutImage: return(SProcXvPutImage(client)); +#ifdef MITSHM + case xv_ShmPutImage: return(SProcXvShmPutImage(client)); +#endif + case xv_QueryImageAttributes: return(SProcXvQueryImageAttributes(client)); + case xv_ListImageFormats: return(SProcXvListImageFormats(client)); + default: + if (stuff->data < xvNumRequests) + { + SendErrorToClient(client, XvReqCode, stuff->data, 0, + BadImplementation); + return(BadImplementation); + } + else + { + SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); + return(BadRequest); + } + } +} + +static int +ProcXvQueryExtension(ClientPtr client) +{ + xvQueryExtensionReply rep; + /* REQUEST(xvQueryExtensionReq); */ + REQUEST_SIZE_MATCH(xvQueryExtensionReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.version = XvVersion; + rep.revision = XvRevision; + + _WriteQueryExtensionReply(client, &rep); + + return Success; + +} + +static int +ProcXvQueryAdaptors(ClientPtr client) +{ + xvFormat format; + xvAdaptorInfo ainfo; + xvQueryAdaptorsReply rep; + int totalSize; + int na; + XvAdaptorPtr pa; + int nf; + XvFormatPtr pf; + WindowPtr pWin; + ScreenPtr pScreen; + XvScreenPtr pxvs; + + REQUEST(xvQueryAdaptorsReq); + REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); + + if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) )) + { + client->errorValue = stuff->window; + return (BadWindow); + } + + pScreen = pWin->drawable.pScreen; + pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr; + + if (!pxvs) + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_adaptors = 0; + rep.length = 0; + + _WriteQueryAdaptorsReply(client, &rep); + + return Success; + } + + (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_adaptors = pxvs->nAdaptors; + + /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */ + + totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo; + + /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */ + + na = pxvs->nAdaptors; + pa = pxvs->pAdaptors; + while (na--) + { + totalSize += (strlen(pa->name) + 3) & ~3; + totalSize += pa->nFormats * sz_xvFormat; + pa++; + } + + rep.length = totalSize >> 2; + + _WriteQueryAdaptorsReply(client, &rep); + + na = pxvs->nAdaptors; + pa = pxvs->pAdaptors; + while (na--) + { + + ainfo.base_id = pa->base_id; + ainfo.num_ports = pa->nPorts; + ainfo.type = pa->type; + ainfo.name_size = strlen(pa->name); + ainfo.num_formats = pa->nFormats; + + _WriteAdaptorInfo(client, &ainfo); + + WriteToClient(client, ainfo.name_size, pa->name); + + nf = pa->nFormats; + pf = pa->pFormats; + while (nf--) + { + format.depth = pf->depth; + format.visual = pf->visual; + _WriteFormat(client, &format); + pf++; + } + + pa++; + + } + + return (client->noClientException); + +} + +static int +ProcXvQueryEncodings(ClientPtr client) +{ + xvEncodingInfo einfo; + xvQueryEncodingsReply rep; + int totalSize; + XvPortPtr pPort; + int ne; + XvEncodingPtr pe; + int status; + + REQUEST(xvQueryEncodingsReq); + REQUEST_SIZE_MATCH(xvQueryEncodingsReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_encodings = pPort->pAdaptor->nEncodings; + + /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */ + + ne = pPort->pAdaptor->nEncodings; + pe = pPort->pAdaptor->pEncodings; + totalSize = ne * sz_xvEncodingInfo; + while (ne--) + { + totalSize += (strlen(pe->name) + 3) & ~3; + pe++; + } + + rep.length = totalSize >> 2; + + _WriteQueryEncodingsReply(client, &rep); + + ne = pPort->pAdaptor->nEncodings; + pe = pPort->pAdaptor->pEncodings; + while (ne--) + { + einfo.encoding = pe->id; + einfo.name_size = strlen(pe->name); + einfo.width = pe->width; + einfo.height = pe->height; + einfo.rate.numerator = pe->rate.numerator; + einfo.rate.denominator = pe->rate.denominator; + _WriteEncodingInfo(client, &einfo); + WriteToClient(client, einfo.name_size, pe->name); + pe++; + } + + return (client->noClientException); + +} + +static int +ProcXvPutVideo(ClientPtr client) +{ + register DrawablePtr pDraw; + XvPortPtr pPort; + register GCPtr pGC; + int status; + + REQUEST(xvPutVideoReq); + REQUEST_SIZE_MATCH(xvPutVideoReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!(pPort->pAdaptor->type & XvInputMask) || + !(pPort->pAdaptor->type & XvVideoMask)) + { + client->errorValue = stuff->port; + return (BadMatch); + } + + status = XVCALL(diMatchPort)(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XVCALL(diPutVideo)(client, pDraw, pPort, pGC, + stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, + stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); + +} + +static int +ProcXvPutStill(ClientPtr client) +{ + register DrawablePtr pDraw; + XvPortPtr pPort; + register GCPtr pGC; + int status; + + REQUEST(xvPutStillReq); + REQUEST_SIZE_MATCH(xvPutStillReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!(pPort->pAdaptor->type & XvInputMask) || + !(pPort->pAdaptor->type & XvStillMask)) + { + client->errorValue = stuff->port; + return (BadMatch); + } + + status = XVCALL(diMatchPort)(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XVCALL(diPutStill)(client, pDraw, pPort, pGC, + stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, + stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); + +} + + +static int +ProcXvGetVideo(ClientPtr client) +{ + register DrawablePtr pDraw; + XvPortPtr pPort; + register GCPtr pGC; + int status; + + REQUEST(xvGetVideoReq); + REQUEST_SIZE_MATCH(xvGetVideoReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!(pPort->pAdaptor->type & XvOutputMask) || + !(pPort->pAdaptor->type & XvVideoMask)) + { + client->errorValue = stuff->port; + return (BadMatch); + } + + status = XVCALL(diMatchPort)(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XVCALL(diGetVideo)(client, pDraw, pPort, pGC, + stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, + stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); + +} + + +static int +ProcXvGetStill(ClientPtr client) +{ + register DrawablePtr pDraw; + XvPortPtr pPort; + register GCPtr pGC; + int status; + + REQUEST(xvGetStillReq); + REQUEST_SIZE_MATCH(xvGetStillReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!(pPort->pAdaptor->type & XvOutputMask) || + !(pPort->pAdaptor->type & XvStillMask)) + { + client->errorValue = stuff->port; + return (BadMatch); + } + + status = XVCALL(diMatchPort)(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XVCALL(diGetStill)(client, pDraw, pPort, pGC, + stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, + stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); + +} + +static int +ProcXvSelectVideoNotify(ClientPtr client) +{ + register DrawablePtr pDraw; + REQUEST(xvSelectVideoNotifyReq); + REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); + + if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) )) + { + client->errorValue = stuff->drawable; + return (BadWindow); + } + + return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff); + +} + +static int +ProcXvSelectPortNotify(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvSelectPortNotifyReq); + REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff); + +} + +static int +ProcXvGrabPort(ClientPtr client) +{ + int result, status; + XvPortPtr pPort; + xvGrabPortReply rep; + REQUEST(xvGrabPortReq); + REQUEST_SIZE_MATCH(xvGrabPortReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result); + + if (status != Success) + { + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.result = result; + + _WriteGrabPortReply(client, &rep); + + return Success; + +} + +static int +ProcXvUngrabPort(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvGrabPortReq); + REQUEST_SIZE_MATCH(xvGrabPortReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + return XVCALL(diUngrabPort)(client, pPort, stuff->time); + +} + + +static int +ProcXvStopVideo(ClientPtr client) +{ + int status; + register DrawablePtr pDraw; + XvPortPtr pPort; + REQUEST(xvStopVideoReq); + REQUEST_SIZE_MATCH(xvStopVideoReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) )) + { + client->errorValue = stuff->drawable; + return (BadDrawable); + } + + return XVCALL(diStopVideo)(client, pPort, pDraw); + +} + +static int +ProcXvSetPortAttribute(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvSetPortAttributeReq); + REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!ValidAtom(stuff->attribute)) + { + client->errorValue = stuff->attribute; + return(BadAtom); + } + + status = XVCALL(diSetPortAttribute)(client, pPort, + stuff->attribute, stuff->value); + + if (status == BadMatch) + client->errorValue = stuff->attribute; + else + client->errorValue = stuff->value; + + return status; +} + +static int +ProcXvGetPortAttribute(ClientPtr client) +{ + INT32 value; + int status; + XvPortPtr pPort; + xvGetPortAttributeReply rep; + REQUEST(xvGetPortAttributeReq); + REQUEST_SIZE_MATCH(xvGetPortAttributeReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!ValidAtom(stuff->attribute)) + { + client->errorValue = stuff->attribute; + return(BadAtom); + } + + status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value); + if (status != Success) + { + client->errorValue = stuff->attribute; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.value = value; + + _WriteGetPortAttributeReply(client, &rep); + + return Success; +} + +static int +ProcXvQueryBestSize(ClientPtr client) +{ + int status; + unsigned int actual_width, actual_height; + XvPortPtr pPort; + xvQueryBestSizeReply rep; + REQUEST(xvQueryBestSizeReq); + REQUEST_SIZE_MATCH(xvQueryBestSizeReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion, + stuff->vid_w, stuff->vid_h, + stuff->drw_w, stuff->drw_h, + &actual_width, &actual_height); + + rep.actual_width = actual_width; + rep.actual_height = actual_height; + + _WriteQueryBestSizeReply(client, &rep); + + return Success; +} + + +static int +ProcXvQueryPortAttributes(ClientPtr client) +{ + int status, size, i; + XvPortPtr pPort; + XvAttributePtr pAtt; + xvQueryPortAttributesReply rep; + xvAttributeInfo Info; + REQUEST(xvQueryPortAttributesReq); + REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_attributes = pPort->pAdaptor->nAttributes; + rep.text_size = 0; + + for(i = 0, pAtt = pPort->pAdaptor->pAttributes; + i < rep.num_attributes; i++, pAtt++) + { + rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L; + } + + rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size; + rep.length >>= 2; + + _WriteQueryPortAttributesReply(client, &rep); + + for(i = 0, pAtt = pPort->pAdaptor->pAttributes; + i < rep.num_attributes; i++, pAtt++) + { + size = strlen(pAtt->name) + 1; /* pass the NULL */ + Info.flags = pAtt->flags; + Info.min = pAtt->min_value; + Info.max = pAtt->max_value; + Info.size = (size + 3) & ~3L; + + _WriteAttributeInfo(client, &Info); + + WriteToClient(client, size, pAtt->name); + } + + return Success; +} + + + +static int +ProcXvPutImage(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + XvImagePtr pImage = NULL; + GCPtr pGC; + int status, i, size; + CARD16 width, height; + + REQUEST(xvPutImageReq); + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!(pPort->pAdaptor->type & XvImageMask) || + !(pPort->pAdaptor->type & XvInputMask)) + { + client->errorValue = stuff->port; + return (BadMatch); + } + + status = XVCALL(diMatchPort)(pPort, pDraw); + if (status != Success) + { + return status; + } + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + + if(!pImage) + return BadMatch; + + width = stuff->width; + height = stuff->height; + size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, + pPort, pImage, &width, &height, NULL, NULL); + size += sizeof(xvPutImageReq); + size = (size + 3) >> 2; + + if((width < stuff->width) || (height < stuff->height)) + return BadValue; + + if(client->req_len < size) + return BadLength; + + return XVCALL(diPutImage)(client, pDraw, pPort, pGC, + stuff->src_x, stuff->src_y, + stuff->src_w, stuff->src_h, + stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h, + pImage, (unsigned char*)(&stuff[1]), FALSE, + stuff->width, stuff->height); +} + +#ifdef MITSHM +/* redefined here since it's not in any header file */ +typedef struct _ShmDesc { + struct _ShmDesc *next; + int shmid; + int refcnt; + char *addr; + Bool writable; + unsigned long size; +} ShmDescRec, *ShmDescPtr; + +extern RESTYPE ShmSegType; +extern int BadShmSegCode; +extern int ShmCompletionCode; + +static int +ProcXvShmPutImage(ClientPtr client) +{ + ShmDescPtr shmdesc; + DrawablePtr pDraw; + XvPortPtr pPort; + XvImagePtr pImage = NULL; + GCPtr pGC; + int status, size_needed, i; + CARD16 width, height; + + REQUEST(xvShmPutImageReq); + REQUEST_SIZE_MATCH(xvShmPutImageReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return (status); + } + + if (!(pPort->pAdaptor->type & XvImageMask) || + !(pPort->pAdaptor->type & XvInputMask)) + { + client->errorValue = stuff->port; + return (BadMatch); + } + + status = XVCALL(diMatchPort)(pPort, pDraw); + if (status != Success) + { + return status; + } + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + + if(!pImage) + return BadMatch; + + if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) + { + client->errorValue = stuff->shmseg; + return BadShmSegCode; + } + + width = stuff->width; + height = stuff->height; + size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, + pPort, pImage, &width, &height, NULL, NULL); + if((size_needed + stuff->offset) > shmdesc->size) + return BadAccess; + + if((width < stuff->width) || (height < stuff->height)) + return BadValue; + + status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, + stuff->src_x, stuff->src_y, + stuff->src_w, stuff->src_h, + stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h, pImage, + (unsigned char *)shmdesc->addr + stuff->offset, + stuff->send_event, stuff->width, stuff->height); + + if((status == Success) && stuff->send_event) { + xShmCompletionEvent ev; + + ev.type = ShmCompletionCode; + ev.drawable = stuff->drawable; + ev.sequenceNumber = client->sequence; + ev.minorEvent = xv_ShmPutImage; + ev.majorEvent = XvReqCode; + ev.shmseg = stuff->shmseg; + ev.offset = stuff->offset; + WriteEventsToClient(client, 1, (xEvent *) &ev); + } + + return status; +} +#endif + +#ifdef XvMCExtension +XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id); +#endif + +static int +ProcXvQueryImageAttributes(ClientPtr client) +{ + xvQueryImageAttributesReply rep; + int size, num_planes, i; + CARD16 width, height; + XvImagePtr pImage = NULL; + XvPortPtr pPort; + int *offsets; + int *pitches; + REQUEST(xvQueryImageAttributesReq); + + REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + +#ifdef XvMCExtension + if(!pImage) + pImage = XvMCFindXvImage(pPort, stuff->id); +#endif + + if(!pImage) + return BadMatch; + + num_planes = pImage->num_planes; + + if(!(offsets = xalloc(num_planes << 3))) + return BadAlloc; + pitches = offsets + num_planes; + + width = stuff->width; + height = stuff->height; + + size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage, + &width, &height, offsets, pitches); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = num_planes << 1; + rep.num_planes = num_planes; + rep.width = width; + rep.height = height; + rep.data_size = size; + + _WriteQueryImageAttributesReply(client, &rep); + if(client->swapped) + SwapLongs((CARD32*)offsets, rep.length); + WriteToClient(client, rep.length << 2, (char*)offsets); + + xfree(offsets); + + return Success; +} + +static int +ProcXvListImageFormats(ClientPtr client) +{ + XvPortPtr pPort; + XvImagePtr pImage; + int i; + xvListImageFormatsReply rep; + xvImageFormatInfo info; + REQUEST(xvListImageFormatsReq); + + REQUEST_SIZE_MATCH(xvListImageFormatsReq); + + if(!(pPort = LOOKUP_PORT(stuff->port, client) )) + { + client->errorValue = stuff->port; + return (_XvBadPort); + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_formats = pPort->pAdaptor->nImages; + rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2; + + _WriteListImageFormatsReply(client, &rep); + + pImage = pPort->pAdaptor->pImages; + + for(i = 0; i < rep.num_formats; i++, pImage++) { + info.id = pImage->id; + info.type = pImage->type; + info.byte_order = pImage->byte_order; + memcpy(&info.guid, pImage->guid, 16); + info.bpp = pImage->bits_per_pixel; + info.num_planes = pImage->num_planes; + info.depth = pImage->depth; + info.red_mask = pImage->red_mask; + info.green_mask = pImage->green_mask; + info.blue_mask = pImage->blue_mask; + info.format = pImage->format; + info.y_sample_bits = pImage->y_sample_bits; + info.u_sample_bits = pImage->u_sample_bits; + info.v_sample_bits = pImage->v_sample_bits; + info.horz_y_period = pImage->horz_y_period; + info.horz_u_period = pImage->horz_u_period; + info.horz_v_period = pImage->horz_v_period; + info.vert_y_period = pImage->vert_y_period; + info.vert_u_period = pImage->vert_u_period; + info.vert_v_period = pImage->vert_v_period; + memcpy(&info.comp_order, pImage->component_order, 32); + info.scanline_order = pImage->scanline_order; + _WriteImageFormatInfo(client, &info); + } + + return Success; +} + + + +/* Swapped Procs */ + +static int +SProcXvQueryExtension(ClientPtr client) +{ + register char n; + REQUEST(xvQueryExtensionReq); + swaps(&stuff->length, n); + return ProcXvQueryExtension(client); +} + +static int +SProcXvQueryAdaptors(ClientPtr client) +{ + register char n; + REQUEST(xvQueryAdaptorsReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return ProcXvQueryAdaptors(client); +} + +static int +SProcXvQueryEncodings(ClientPtr client) +{ + register char n; + REQUEST(xvQueryEncodingsReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return ProcXvQueryEncodings(client); +} + +static int +SProcXvGrabPort(ClientPtr client) +{ + register char n; + REQUEST(xvGrabPortReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->time, n); + return ProcXvGrabPort(client); +} + +static int +SProcXvUngrabPort(ClientPtr client) +{ + register char n; + REQUEST(xvUngrabPortReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->time, n); + return ProcXvUngrabPort(client); +} + +static int +SProcXvPutVideo(ClientPtr client) +{ + register char n; + REQUEST(xvPutVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return ProcXvPutVideo(client); +} + +static int +SProcXvPutStill(ClientPtr client) +{ + register char n; + REQUEST(xvPutStillReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return ProcXvPutStill(client); +} + +static int +SProcXvGetVideo(ClientPtr client) +{ + register char n; + REQUEST(xvGetVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return ProcXvGetVideo(client); +} + +static int +SProcXvGetStill(ClientPtr client) +{ + register char n; + REQUEST(xvGetStillReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return ProcXvGetStill(client); +} + +static int +SProcXvPutImage(ClientPtr client) +{ + register char n; + REQUEST(xvPutImageReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swapl(&stuff->id, n); + swaps(&stuff->src_x, n); + swaps(&stuff->src_y, n); + swaps(&stuff->src_w, n); + swaps(&stuff->src_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return ProcXvPutImage(client); +} + +#ifdef MITSHM +static int +SProcXvShmPutImage(ClientPtr client) +{ + register char n; + REQUEST(xvShmPutImageReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->id, n); + swaps(&stuff->src_x, n); + swaps(&stuff->src_y, n); + swaps(&stuff->src_w, n); + swaps(&stuff->src_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + swaps(&stuff->offset, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return ProcXvShmPutImage(client); +} +#endif + + +static int +SProcXvSelectVideoNotify(ClientPtr client) +{ + register char n; + REQUEST(xvSelectVideoNotifyReq); + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + return ProcXvSelectVideoNotify(client); +} + +static int +SProcXvSelectPortNotify(ClientPtr client) +{ + register char n; + REQUEST(xvSelectPortNotifyReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return ProcXvSelectPortNotify(client); +} + +static int +SProcXvStopVideo(ClientPtr client) +{ + register char n; + REQUEST(xvStopVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + return ProcXvStopVideo(client); +} + +static int +SProcXvSetPortAttribute(ClientPtr client) +{ + register char n; + REQUEST(xvSetPortAttributeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->attribute, n); + return ProcXvSetPortAttribute(client); +} + +static int +SProcXvGetPortAttribute(ClientPtr client) +{ + register char n; + REQUEST(xvGetPortAttributeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->attribute, n); + return ProcXvGetPortAttribute(client); +} + +static int +SProcXvQueryBestSize(ClientPtr client) +{ + register char n; + REQUEST(xvQueryBestSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return ProcXvQueryBestSize(client); +} + +static int +SProcXvQueryPortAttributes(ClientPtr client) +{ + register char n; + REQUEST(xvQueryPortAttributesReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return ProcXvQueryPortAttributes(client); +} + +static int +SProcXvQueryImageAttributes(ClientPtr client) +{ + register char n; + REQUEST(xvQueryImageAttributesReq); + swaps(&stuff->length, n); + swapl(&stuff->id, n); + swaps(&stuff->width, n); + swaps(&stuff->width, n); + return ProcXvQueryImageAttributes(client); +} + +static int +SProcXvListImageFormats(ClientPtr client) +{ + register char n; + REQUEST(xvListImageFormatsReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return ProcXvListImageFormats(client); +} + + +static int +SWriteQueryExtensionReply( + ClientPtr client, + xvQueryExtensionReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->version, n); + swaps(&rep->revision, n); + + (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)&rep); + + return Success; +} + +static int +SWriteQueryAdaptorsReply( + ClientPtr client, + xvQueryAdaptorsReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_adaptors, n); + + (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)&rep); + + return Success; +} + +static int +SWriteQueryEncodingsReply( + ClientPtr client, + xvQueryEncodingsReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_encodings, n); + + (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)&rep); + + return Success; +} + +static int +SWriteAdaptorInfo( + ClientPtr client, + xvAdaptorInfo *pAdaptor +){ + register char n; + + swapl(&pAdaptor->base_id, n); + swaps(&pAdaptor->name_size, n); + swaps(&pAdaptor->num_ports, n); + swaps(&pAdaptor->num_formats, n); + + (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor); + + return Success; +} + +static int +SWriteEncodingInfo( + ClientPtr client, + xvEncodingInfo *pEncoding +){ + register char n; + + swapl(&pEncoding->encoding, n); + swaps(&pEncoding->name_size, n); + swaps(&pEncoding->width, n); + swaps(&pEncoding->height, n); + swapl(&pEncoding->rate.numerator, n); + swapl(&pEncoding->rate.denominator, n); + (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding); + + return Success; +} + +static int +SWriteFormat( + ClientPtr client, + xvFormat *pFormat +){ + register char n; + + swapl(&pFormat->visual, n); + (void)WriteToClient(client, sz_xvFormat, (char *)pFormat); + + return Success; +} + +static int +SWriteAttributeInfo( + ClientPtr client, + xvAttributeInfo *pAtt +){ + register char n; + + swapl(&pAtt->flags, n); + swapl(&pAtt->size, n); + swapl(&pAtt->min, n); + swapl(&pAtt->max, n); + (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt); + + return Success; +} + +static int +SWriteImageFormatInfo( + ClientPtr client, + xvImageFormatInfo *pImage +){ + register char n; + + swapl(&pImage->id, n); + swapl(&pImage->red_mask, n); + swapl(&pImage->green_mask, n); + swapl(&pImage->blue_mask, n); + swapl(&pImage->y_sample_bits, n); + swapl(&pImage->u_sample_bits, n); + swapl(&pImage->v_sample_bits, n); + swapl(&pImage->horz_y_period, n); + swapl(&pImage->horz_u_period, n); + swapl(&pImage->horz_v_period, n); + swapl(&pImage->vert_y_period, n); + swapl(&pImage->vert_u_period, n); + swapl(&pImage->vert_v_period, n); + + (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage); + + return Success; +} + + + +static int +SWriteGrabPortReply( + ClientPtr client, + xvGrabPortReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + + (void)WriteToClient(client, sz_xvGrabPortReply, (char *)&rep); + + return Success; +} + +static int +SWriteGetPortAttributeReply( + ClientPtr client, + xvGetPortAttributeReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->value, n); + + (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)&rep); + + return Success; +} + +static int +SWriteQueryBestSizeReply( + ClientPtr client, + xvQueryBestSizeReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->actual_width, n); + swaps(&rep->actual_height, n); + + (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)&rep); + + return Success; +} + +static int +SWriteQueryPortAttributesReply( + ClientPtr client, + xvQueryPortAttributesReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_attributes, n); + swapl(&rep->text_size, n); + + (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)&rep); + + return Success; +} + +static int +SWriteQueryImageAttributesReply( + ClientPtr client, + xvQueryImageAttributesReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_planes, n); + swapl(&rep->data_size, n); + swaps(&rep->width, n); + swaps(&rep->height, n); + + (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)&rep); + + return Success; +} + + +static int +SWriteListImageFormatsReply( + ClientPtr client, + xvListImageFormatsReply *rep +){ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_formats, n); + + (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep); + + return Success; +} + + +#ifdef PANORAMIX + + + + +static int +XineramaXvStopVideo(ClientPtr client) +{ + int result = Success, i; + PanoramiXRes *draw, *port; + REQUEST(xvStopVideoReq); + REQUEST_SIZE_MATCH(xvStopVideoReq); + + if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( + client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess))) + return BadDrawable; + + if(!(port = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->port, XvXRTPort, SecurityReadAccess))) + return _XvBadPort; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + result = ProcXvStopVideo(client); + } + } + + return result; +} + +static int +XineramaXvSetPortAttribute(ClientPtr client) +{ + REQUEST(xvSetPortAttributeReq); + PanoramiXRes *port; + int result = Success, i; + + REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + + if(!(port = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->port, XvXRTPort, SecurityReadAccess))) + return _XvBadPort; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->port = port->info[i].id; + result = ProcXvSetPortAttribute(client); + } + } + return result; +} + + +#ifdef MITSHM +static int +XineramaXvShmPutImage(ClientPtr client) +{ + REQUEST(xvShmPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool send_event = stuff->send_event; + Bool isRoot; + int result = Success, i, x, y; + + REQUEST_SIZE_MATCH(xvShmPutImageReq); + + if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( + client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess))) + return BadDrawable; + + if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->gc, XRT_GC, SecurityReadAccess))) + return BadGC; + + if(!(port = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->port, XvXRTPort, SecurityReadAccess))) + return _XvBadPort; + + isRoot = (draw->type == XRT_WINDOW) && + (stuff->drawable == WindowTable[0]->drawable.id); + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= panoramiXdataPtr[i].x; + stuff->drw_y -= panoramiXdataPtr[i].y; + } + stuff->send_event = (send_event && !i) ? 1 : 0; + + result = ProcXvShmPutImage(client); + } + } + return result; +} +#endif + +static int +XineramaXvPutImage(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result = Success, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( + client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess))) + return BadDrawable; + + if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->gc, XRT_GC, SecurityReadAccess))) + return BadGC; + + if(!(port = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->port, XvXRTPort, SecurityReadAccess))) + return _XvBadPort; + + isRoot = (draw->type == XRT_WINDOW) && + (stuff->drawable == WindowTable[0]->drawable.id); + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= panoramiXdataPtr[i].x; + stuff->drw_y -= panoramiXdataPtr[i].y; + } + + result = ProcXvPutImage(client); + } + } + return result; +} + +static int +XineramaXvPutVideo(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result = Success, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutVideoReq); + + if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( + client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess))) + return BadDrawable; + + if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->gc, XRT_GC, SecurityReadAccess))) + return BadGC; + + if(!(port = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->port, XvXRTPort, SecurityReadAccess))) + return _XvBadPort; + + isRoot = (draw->type == XRT_WINDOW) && + (stuff->drawable == WindowTable[0]->drawable.id); + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= panoramiXdataPtr[i].x; + stuff->drw_y -= panoramiXdataPtr[i].y; + } + + result = ProcXvPutVideo(client); + } + } + return result; +} + +static int +XineramaXvPutStill(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result = Success, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( + client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess))) + return BadDrawable; + + if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->gc, XRT_GC, SecurityReadAccess))) + return BadGC; + + if(!(port = (PanoramiXRes *)SecurityLookupIDByType( + client, stuff->port, XvXRTPort, SecurityReadAccess))) + return _XvBadPort; + + isRoot = (draw->type == XRT_WINDOW) && + (stuff->drawable == WindowTable[0]->drawable.id); + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= panoramiXdataPtr[i].x; + stuff->drw_y -= panoramiXdataPtr[i].y; + } + + result = ProcXvPutStill(client); + } + } + return result; +} + + +void XineramifyXv(void) +{ + ScreenPtr pScreen, screen0 = screenInfo.screens[0]; + XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr; + XvAdaptorPtr refAdapt, pAdapt; + XvAttributePtr pAttr; + XvScreenPtr xvsp; + Bool isOverlay, hasOverlay; + PanoramiXRes *port; + XvAdaptorPtr MatchingAdaptors[MAXSCREENS]; + int i, j, k, l; + + XvXRTPort = CreateNewResourceType(XineramaDeleteResource); + + if(!xvsp0) return; + + for(i = 0; i < xvsp0->nAdaptors; i++) { + refAdapt = xvsp0->pAdaptors + i; + + bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS); + + MatchingAdaptors[0] = refAdapt; + + if(!(refAdapt->type & XvInputMask)) continue; + + isOverlay = FALSE; + for(j = 0; j < refAdapt->nAttributes; j++) { + pAttr = refAdapt->pAttributes + j; + if(!strcmp(pAttr->name, "XV_COLORKEY")) { + isOverlay = TRUE; + break; + } + } + + for(j = 1; j < PanoramiXNumScreens; j++) { + pScreen = screenInfo.screens[j]; + xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr; + + /* Do not try to go on if xv is not supported on this screen */ + if (xvsp==NULL) continue ; + + /* if the adaptor has the same name it's a perfect match */ + for(k = 0; k < xvsp->nAdaptors; k++) { + pAdapt = xvsp->pAdaptors + k; + if(!strcmp(refAdapt->name, pAdapt->name)) { + MatchingAdaptors[j] = pAdapt; + break; + } + } + if(MatchingAdaptors[j]) continue; /* found it */ + + /* otherwise we only look for XvImage adaptors */ + if(!(refAdapt->type & XvImageMask)) continue; + if(refAdapt->nImages <= 0) continue; + + /* prefer overlay/overlay non-overlay/non-overlay pairing */ + for(k = 0; k < xvsp->nAdaptors; k++) { + pAdapt = xvsp->pAdaptors + k; + if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) { + hasOverlay = FALSE; + for(l = 0; l < pAdapt->nAttributes; l++) { + if(!strcmp(pAdapt->name, "XV_COLORKEY")) { + hasOverlay = TRUE; + break; + } + } + if(isOverlay && hasOverlay) { + MatchingAdaptors[j] = pAdapt; + break; + } + else if(!isOverlay && !hasOverlay) { + MatchingAdaptors[j] = pAdapt; + break; + } + } + } + + if(MatchingAdaptors[j]) continue; /* found it */ + + /* but we'll take any XvImage pairing if we can get it */ + + for(k = 0; k < xvsp->nAdaptors; k++) { + pAdapt = xvsp->pAdaptors + k; + if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) { + MatchingAdaptors[j] = pAdapt; + break; + } + } + } + + /* now create a resource for each port */ + for(j = 0; j < refAdapt->nPorts; j++) { + if(!(port = xalloc(sizeof(PanoramiXRes)))) + break; + port->info[0].id = MatchingAdaptors[0]->base_id + j; + AddResource(port->info[0].id, XvXRTPort, port); + + for(k = 1; k < PanoramiXNumScreens; k++) { + if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) + port->info[k].id = MatchingAdaptors[k]->base_id + j; + else + port->info[k].id = 0; + } + } + } +} + +#endif |