xvmain.c revision 4642e01f
105b261ecSmrg/*********************************************************** 205b261ecSmrgCopyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, 305b261ecSmrgand the Massachusetts Institute of Technology, Cambridge, Massachusetts. 405b261ecSmrg 505b261ecSmrg All Rights Reserved 605b261ecSmrg 705b261ecSmrgPermission to use, copy, modify, and distribute this software and its 805b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 905b261ecSmrgprovided that the above copyright notice appear in all copies and that 1005b261ecSmrgboth that copyright notice and this permission notice appear in 1105b261ecSmrgsupporting documentation, and that the names of Digital or MIT not be 1205b261ecSmrgused in advertising or publicity pertaining to distribution of the 1305b261ecSmrgsoftware without specific, written prior permission. 1405b261ecSmrg 1505b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 1605b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 1705b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 1805b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 1905b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 2005b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 2105b261ecSmrgSOFTWARE. 2205b261ecSmrg 2305b261ecSmrg******************************************************************/ 2405b261ecSmrg 2505b261ecSmrg/* 2605b261ecSmrg** File: 2705b261ecSmrg** 2805b261ecSmrg** xvmain.c --- Xv server extension main device independent module. 2905b261ecSmrg** 3005b261ecSmrg** Author: 3105b261ecSmrg** 3205b261ecSmrg** David Carver (Digital Workstation Engineering/Project Athena) 3305b261ecSmrg** 3405b261ecSmrg** Revisions: 3505b261ecSmrg** 3605b261ecSmrg** 04.09.91 Carver 3705b261ecSmrg** - change: stop video always generates an event even when video 3805b261ecSmrg** wasn't active 3905b261ecSmrg** 4005b261ecSmrg** 29.08.91 Carver 4105b261ecSmrg** - change: unrealizing windows no longer preempts video 4205b261ecSmrg** 4305b261ecSmrg** 11.06.91 Carver 4405b261ecSmrg** - changed SetPortControl to SetPortAttribute 4505b261ecSmrg** - changed GetPortControl to GetPortAttribute 4605b261ecSmrg** - changed QueryBestSize 4705b261ecSmrg** 4805b261ecSmrg** 28.05.91 Carver 4905b261ecSmrg** - fixed Put and Get requests to not preempt operations to same drawable 5005b261ecSmrg** 5105b261ecSmrg** 15.05.91 Carver 5205b261ecSmrg** - version 2.0 upgrade 5305b261ecSmrg** 5405b261ecSmrg** 19.03.91 Carver 5505b261ecSmrg** - fixed Put and Get requests to honor grabbed ports. 5605b261ecSmrg** - fixed Video requests to update di structure with new drawable, and 5705b261ecSmrg** client after calling ddx. 5805b261ecSmrg** 5905b261ecSmrg** 24.01.91 Carver 6005b261ecSmrg** - version 1.4 upgrade 6105b261ecSmrg** 6205b261ecSmrg** Notes: 6305b261ecSmrg** 6405b261ecSmrg** Port structures reference client structures in a two different 6505b261ecSmrg** ways: when grabs, or video is active. Each reference is encoded 6605b261ecSmrg** as fake client resources and thus when the client is goes away so 6705b261ecSmrg** does the reference (it is zeroed). No other action is taken, so 6805b261ecSmrg** video doesn't necessarily stop. It probably will as a result of 6905b261ecSmrg** other resources going away, but if a client starts video using 7005b261ecSmrg** none of its own resources, then the video will continue to play 7105b261ecSmrg** after the client disappears. 7205b261ecSmrg** 7305b261ecSmrg** 7405b261ecSmrg*/ 7505b261ecSmrg 7605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 7705b261ecSmrg#include <dix-config.h> 7805b261ecSmrg#endif 7905b261ecSmrg 8005b261ecSmrg#include <string.h> 8105b261ecSmrg 8205b261ecSmrg#include <X11/X.h> 8305b261ecSmrg#include <X11/Xproto.h> 8405b261ecSmrg#include "misc.h" 8505b261ecSmrg#include "os.h" 8605b261ecSmrg#include "scrnintstr.h" 8705b261ecSmrg#include "windowstr.h" 8805b261ecSmrg#include "pixmapstr.h" 8905b261ecSmrg#include "gc.h" 9005b261ecSmrg#include "extnsionst.h" 9105b261ecSmrg#include "dixstruct.h" 9205b261ecSmrg#include "resource.h" 9305b261ecSmrg#include "opaque.h" 9405b261ecSmrg#include "input.h" 9505b261ecSmrg 9605b261ecSmrg#define GLOBAL 9705b261ecSmrg 9805b261ecSmrg#include <X11/extensions/Xv.h> 9905b261ecSmrg#include <X11/extensions/Xvproto.h> 10005b261ecSmrg#include "xvdix.h" 10105b261ecSmrg 10205b261ecSmrg#ifdef PANORAMIX 10305b261ecSmrg#include "panoramiX.h" 10405b261ecSmrg#include "panoramiXsrv.h" 10505b261ecSmrg#endif 1064642e01fSmrg#include "xvdisp.h" 10705b261ecSmrg 1084642e01fSmrgstatic int XvScreenKeyIndex; 1094642e01fSmrgstatic DevPrivateKey XvScreenKey = &XvScreenKeyIndex; 11005b261ecSmrgunsigned long XvExtensionGeneration = 0; 11105b261ecSmrgunsigned long XvScreenGeneration = 0; 11205b261ecSmrgunsigned long XvResourceGeneration = 0; 11305b261ecSmrg 11405b261ecSmrgint XvReqCode; 11505b261ecSmrgint XvEventBase; 11605b261ecSmrgint XvErrorBase; 11705b261ecSmrg 11805b261ecSmrgunsigned long XvRTPort; 11905b261ecSmrgunsigned long XvRTEncoding; 12005b261ecSmrgunsigned long XvRTGrab; 12105b261ecSmrgunsigned long XvRTVideoNotify; 12205b261ecSmrgunsigned long XvRTVideoNotifyList; 12305b261ecSmrgunsigned long XvRTPortNotify; 12405b261ecSmrg 12505b261ecSmrg 12605b261ecSmrg 12705b261ecSmrg/* EXTERNAL */ 12805b261ecSmrg 12905b261ecSmrgextern XID clientErrorValue; 13005b261ecSmrg 13105b261ecSmrgstatic void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); 13205b261ecSmrgstatic void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); 13305b261ecSmrgstatic Bool CreateResourceTypes(void); 13405b261ecSmrg 13505b261ecSmrgstatic Bool XvCloseScreen(int, ScreenPtr); 13605b261ecSmrgstatic Bool XvDestroyPixmap(PixmapPtr); 13705b261ecSmrgstatic Bool XvDestroyWindow(WindowPtr); 13805b261ecSmrgstatic void XvResetProc(ExtensionEntry*); 13905b261ecSmrgstatic int XvdiDestroyGrab(pointer, XID); 14005b261ecSmrgstatic int XvdiDestroyEncoding(pointer, XID); 14105b261ecSmrgstatic int XvdiDestroyVideoNotify(pointer, XID); 14205b261ecSmrgstatic int XvdiDestroyPortNotify(pointer, XID); 14305b261ecSmrgstatic int XvdiDestroyVideoNotifyList(pointer, XID); 14405b261ecSmrgstatic int XvdiDestroyPort(pointer, XID); 14505b261ecSmrgstatic int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int); 14605b261ecSmrg 14705b261ecSmrg 14805b261ecSmrg 14905b261ecSmrg 15005b261ecSmrg/* 15105b261ecSmrg** XvExtensionInit 15205b261ecSmrg** 15305b261ecSmrg** 15405b261ecSmrg*/ 15505b261ecSmrg 15605b261ecSmrgvoid 15705b261ecSmrgXvExtensionInit(void) 15805b261ecSmrg{ 15905b261ecSmrg ExtensionEntry *extEntry; 16005b261ecSmrg 16105b261ecSmrg /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN 16205b261ecSmrg INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */ 16305b261ecSmrg if (XvScreenGeneration != serverGeneration) 16405b261ecSmrg { 16505b261ecSmrg if (!CreateResourceTypes()) 16605b261ecSmrg { 16705b261ecSmrg ErrorF("XvExtensionInit: Unable to allocate resource types\n"); 16805b261ecSmrg return; 16905b261ecSmrg } 17005b261ecSmrg#ifdef PANORAMIX 17105b261ecSmrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 17205b261ecSmrg#endif 17305b261ecSmrg XvScreenGeneration = serverGeneration; 17405b261ecSmrg } 17505b261ecSmrg 17605b261ecSmrg if (XvExtensionGeneration != serverGeneration) 17705b261ecSmrg { 17805b261ecSmrg XvExtensionGeneration = serverGeneration; 17905b261ecSmrg 18005b261ecSmrg extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, 18105b261ecSmrg ProcXvDispatch, SProcXvDispatch, 18205b261ecSmrg XvResetProc, StandardMinorOpcode); 18305b261ecSmrg if (!extEntry) 18405b261ecSmrg { 18505b261ecSmrg FatalError("XvExtensionInit: AddExtensions failed\n"); 18605b261ecSmrg } 18705b261ecSmrg 18805b261ecSmrg XvReqCode = extEntry->base; 18905b261ecSmrg XvEventBase = extEntry->eventBase; 19005b261ecSmrg XvErrorBase = extEntry->errorBase; 19105b261ecSmrg 19205b261ecSmrg EventSwapVector[XvEventBase+XvVideoNotify] = 19305b261ecSmrg (EventSwapPtr)WriteSwappedVideoNotifyEvent; 19405b261ecSmrg EventSwapVector[XvEventBase+XvPortNotify] = 19505b261ecSmrg (EventSwapPtr)WriteSwappedPortNotifyEvent; 19605b261ecSmrg 19705b261ecSmrg (void)MakeAtom(XvName, strlen(XvName), xTrue); 19805b261ecSmrg 19905b261ecSmrg } 20005b261ecSmrg} 20105b261ecSmrg 20205b261ecSmrgstatic Bool 20305b261ecSmrgCreateResourceTypes(void) 20405b261ecSmrg 20505b261ecSmrg{ 20605b261ecSmrg 20705b261ecSmrg if (XvResourceGeneration == serverGeneration) return TRUE; 20805b261ecSmrg 20905b261ecSmrg XvResourceGeneration = serverGeneration; 21005b261ecSmrg 21105b261ecSmrg if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort))) 21205b261ecSmrg { 21305b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate port resource.\n"); 21405b261ecSmrg return FALSE; 21505b261ecSmrg } 21605b261ecSmrg 21705b261ecSmrg if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab))) 21805b261ecSmrg { 21905b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate grab resource.\n"); 22005b261ecSmrg return FALSE; 22105b261ecSmrg } 22205b261ecSmrg 22305b261ecSmrg if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding))) 22405b261ecSmrg { 22505b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n"); 22605b261ecSmrg return FALSE; 22705b261ecSmrg } 22805b261ecSmrg 22905b261ecSmrg if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify))) 23005b261ecSmrg { 23105b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n"); 23205b261ecSmrg return FALSE; 23305b261ecSmrg } 23405b261ecSmrg 23505b261ecSmrg if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList))) 23605b261ecSmrg { 23705b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n"); 23805b261ecSmrg return FALSE; 23905b261ecSmrg } 24005b261ecSmrg 24105b261ecSmrg if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify))) 24205b261ecSmrg { 24305b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n"); 24405b261ecSmrg return FALSE; 24505b261ecSmrg } 24605b261ecSmrg 24705b261ecSmrg return TRUE; 24805b261ecSmrg 24905b261ecSmrg} 25005b261ecSmrg 25105b261ecSmrg_X_EXPORT int 25205b261ecSmrgXvScreenInit(ScreenPtr pScreen) 25305b261ecSmrg{ 25405b261ecSmrg XvScreenPtr pxvs; 25505b261ecSmrg 25605b261ecSmrg if (XvScreenGeneration != serverGeneration) 25705b261ecSmrg { 25805b261ecSmrg if (!CreateResourceTypes()) 25905b261ecSmrg { 26005b261ecSmrg ErrorF("XvScreenInit: Unable to allocate resource types\n"); 26105b261ecSmrg return BadAlloc; 26205b261ecSmrg } 26305b261ecSmrg#ifdef PANORAMIX 26405b261ecSmrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 26505b261ecSmrg#endif 26605b261ecSmrg XvScreenGeneration = serverGeneration; 26705b261ecSmrg } 26805b261ecSmrg 2694642e01fSmrg if (dixLookupPrivate(&pScreen->devPrivates, XvScreenKey)) 27005b261ecSmrg { 27105b261ecSmrg ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n"); 27205b261ecSmrg } 27305b261ecSmrg 27405b261ecSmrg /* ALLOCATE SCREEN PRIVATE RECORD */ 27505b261ecSmrg 27605b261ecSmrg pxvs = (XvScreenPtr) xalloc (sizeof (XvScreenRec)); 27705b261ecSmrg if (!pxvs) 27805b261ecSmrg { 27905b261ecSmrg ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); 28005b261ecSmrg return BadAlloc; 28105b261ecSmrg } 28205b261ecSmrg 2834642e01fSmrg dixSetPrivate(&pScreen->devPrivates, XvScreenKey, pxvs); 28405b261ecSmrg 28505b261ecSmrg 28605b261ecSmrg pxvs->DestroyPixmap = pScreen->DestroyPixmap; 28705b261ecSmrg pxvs->DestroyWindow = pScreen->DestroyWindow; 28805b261ecSmrg pxvs->CloseScreen = pScreen->CloseScreen; 28905b261ecSmrg 29005b261ecSmrg pScreen->DestroyPixmap = XvDestroyPixmap; 29105b261ecSmrg pScreen->DestroyWindow = XvDestroyWindow; 29205b261ecSmrg pScreen->CloseScreen = XvCloseScreen; 29305b261ecSmrg 29405b261ecSmrg return Success; 29505b261ecSmrg} 29605b261ecSmrg 29705b261ecSmrgstatic Bool 29805b261ecSmrgXvCloseScreen( 29905b261ecSmrg int ii, 30005b261ecSmrg ScreenPtr pScreen 30105b261ecSmrg){ 30205b261ecSmrg 30305b261ecSmrg XvScreenPtr pxvs; 30405b261ecSmrg 3054642e01fSmrg pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 30605b261ecSmrg 30705b261ecSmrg pScreen->DestroyPixmap = pxvs->DestroyPixmap; 30805b261ecSmrg pScreen->DestroyWindow = pxvs->DestroyWindow; 30905b261ecSmrg pScreen->CloseScreen = pxvs->CloseScreen; 31005b261ecSmrg 31105b261ecSmrg (* pxvs->ddCloseScreen)(ii, pScreen); 31205b261ecSmrg 31305b261ecSmrg xfree(pxvs); 31405b261ecSmrg 3154642e01fSmrg dixSetPrivate(&pScreen->devPrivates, XvScreenKey, NULL); 31605b261ecSmrg 31705b261ecSmrg return (*pScreen->CloseScreen)(ii, pScreen); 31805b261ecSmrg} 31905b261ecSmrg 32005b261ecSmrgstatic void 32105b261ecSmrgXvResetProc(ExtensionEntry* extEntry) 32205b261ecSmrg{ 3234642e01fSmrg XvResetProcVector(); 32405b261ecSmrg} 32505b261ecSmrg 3264642e01fSmrg_X_EXPORT DevPrivateKey 3274642e01fSmrgXvGetScreenKey(void) 32805b261ecSmrg{ 3294642e01fSmrg return XvScreenKey; 33005b261ecSmrg} 33105b261ecSmrg 33205b261ecSmrg_X_EXPORT unsigned long 33305b261ecSmrgXvGetRTPort(void) 33405b261ecSmrg{ 33505b261ecSmrg return XvRTPort; 33605b261ecSmrg} 33705b261ecSmrg 33805b261ecSmrgstatic Bool 33905b261ecSmrgXvDestroyPixmap(PixmapPtr pPix) 34005b261ecSmrg{ 34105b261ecSmrg Bool status; 34205b261ecSmrg ScreenPtr pScreen; 34305b261ecSmrg XvScreenPtr pxvs; 34405b261ecSmrg XvAdaptorPtr pa; 34505b261ecSmrg int na; 34605b261ecSmrg XvPortPtr pp; 34705b261ecSmrg int np; 34805b261ecSmrg 34905b261ecSmrg pScreen = pPix->drawable.pScreen; 35005b261ecSmrg 35105b261ecSmrg SCREEN_PROLOGUE(pScreen, DestroyPixmap); 35205b261ecSmrg 3534642e01fSmrg pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 35405b261ecSmrg 35505b261ecSmrg /* CHECK TO SEE IF THIS PORT IS IN USE */ 35605b261ecSmrg 35705b261ecSmrg pa = pxvs->pAdaptors; 35805b261ecSmrg na = pxvs->nAdaptors; 35905b261ecSmrg while (na--) 36005b261ecSmrg { 36105b261ecSmrg np = pa->nPorts; 36205b261ecSmrg pp = pa->pPorts; 36305b261ecSmrg 36405b261ecSmrg while (np--) 36505b261ecSmrg { 36605b261ecSmrg if (pp->pDraw == (DrawablePtr)pPix) 36705b261ecSmrg { 36805b261ecSmrg XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); 36905b261ecSmrg 37005b261ecSmrg (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp, 37105b261ecSmrg pp->pDraw); 37205b261ecSmrg 37305b261ecSmrg pp->pDraw = (DrawablePtr)NULL; 37405b261ecSmrg pp->client = (ClientPtr)NULL; 37505b261ecSmrg pp->time = currentTime; 37605b261ecSmrg } 37705b261ecSmrg pp++; 37805b261ecSmrg } 37905b261ecSmrg pa++; 38005b261ecSmrg } 38105b261ecSmrg 38205b261ecSmrg status = (* pScreen->DestroyPixmap)(pPix); 38305b261ecSmrg 38405b261ecSmrg SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap); 38505b261ecSmrg 38605b261ecSmrg return status; 38705b261ecSmrg 38805b261ecSmrg} 38905b261ecSmrg 39005b261ecSmrgstatic Bool 39105b261ecSmrgXvDestroyWindow(WindowPtr pWin) 39205b261ecSmrg{ 39305b261ecSmrg Bool status; 39405b261ecSmrg ScreenPtr pScreen; 39505b261ecSmrg XvScreenPtr pxvs; 39605b261ecSmrg XvAdaptorPtr pa; 39705b261ecSmrg int na; 39805b261ecSmrg XvPortPtr pp; 39905b261ecSmrg int np; 40005b261ecSmrg 40105b261ecSmrg pScreen = pWin->drawable.pScreen; 40205b261ecSmrg 40305b261ecSmrg SCREEN_PROLOGUE(pScreen, DestroyWindow); 40405b261ecSmrg 4054642e01fSmrg pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 40605b261ecSmrg 40705b261ecSmrg /* CHECK TO SEE IF THIS PORT IS IN USE */ 40805b261ecSmrg 40905b261ecSmrg pa = pxvs->pAdaptors; 41005b261ecSmrg na = pxvs->nAdaptors; 41105b261ecSmrg while (na--) 41205b261ecSmrg { 41305b261ecSmrg np = pa->nPorts; 41405b261ecSmrg pp = pa->pPorts; 41505b261ecSmrg 41605b261ecSmrg while (np--) 41705b261ecSmrg { 41805b261ecSmrg if (pp->pDraw == (DrawablePtr)pWin) 41905b261ecSmrg { 42005b261ecSmrg XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); 42105b261ecSmrg 42205b261ecSmrg (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp, 42305b261ecSmrg pp->pDraw); 42405b261ecSmrg 42505b261ecSmrg pp->pDraw = (DrawablePtr)NULL; 42605b261ecSmrg pp->client = (ClientPtr)NULL; 42705b261ecSmrg pp->time = currentTime; 42805b261ecSmrg } 42905b261ecSmrg pp++; 43005b261ecSmrg } 43105b261ecSmrg pa++; 43205b261ecSmrg } 43305b261ecSmrg 43405b261ecSmrg 43505b261ecSmrg status = (* pScreen->DestroyWindow)(pWin); 43605b261ecSmrg 43705b261ecSmrg SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow); 43805b261ecSmrg 43905b261ecSmrg return status; 44005b261ecSmrg 44105b261ecSmrg} 44205b261ecSmrg 44305b261ecSmrg/* The XvdiVideoStopped procedure is a hook for the device dependent layer. 44405b261ecSmrg It provides a way for the dd layer to inform the di layer that video has 44505b261ecSmrg stopped in a port for reasons that the di layer had no control over; note 44605b261ecSmrg that it doesn't call back into the dd layer */ 44705b261ecSmrg 44805b261ecSmrgint 44905b261ecSmrgXvdiVideoStopped(XvPortPtr pPort, int reason) 45005b261ecSmrg{ 45105b261ecSmrg 45205b261ecSmrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 45305b261ecSmrg 45405b261ecSmrg if (!pPort->pDraw) return Success; 45505b261ecSmrg 45605b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, reason); 45705b261ecSmrg 45805b261ecSmrg pPort->pDraw = (DrawablePtr)NULL; 45905b261ecSmrg pPort->client = (ClientPtr)NULL; 46005b261ecSmrg pPort->time = currentTime; 46105b261ecSmrg 46205b261ecSmrg return Success; 46305b261ecSmrg 46405b261ecSmrg} 46505b261ecSmrg 46605b261ecSmrgstatic int 46705b261ecSmrgXvdiDestroyPort(pointer pPort, XID id) 46805b261ecSmrg{ 46905b261ecSmrg return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort); 47005b261ecSmrg} 47105b261ecSmrg 47205b261ecSmrgstatic int 47305b261ecSmrgXvdiDestroyGrab(pointer pGrab, XID id) 47405b261ecSmrg{ 47505b261ecSmrg ((XvGrabPtr)pGrab)->client = (ClientPtr)NULL; 47605b261ecSmrg return Success; 47705b261ecSmrg} 47805b261ecSmrg 47905b261ecSmrgstatic int 48005b261ecSmrgXvdiDestroyVideoNotify(pointer pn, XID id) 48105b261ecSmrg{ 48205b261ecSmrg /* JUST CLEAR OUT THE client POINTER FIELD */ 48305b261ecSmrg 48405b261ecSmrg ((XvVideoNotifyPtr)pn)->client = (ClientPtr)NULL; 48505b261ecSmrg return Success; 48605b261ecSmrg} 48705b261ecSmrg 48805b261ecSmrgstatic int 48905b261ecSmrgXvdiDestroyPortNotify(pointer pn, XID id) 49005b261ecSmrg{ 49105b261ecSmrg /* JUST CLEAR OUT THE client POINTER FIELD */ 49205b261ecSmrg 49305b261ecSmrg ((XvPortNotifyPtr)pn)->client = (ClientPtr)NULL; 49405b261ecSmrg return Success; 49505b261ecSmrg} 49605b261ecSmrg 49705b261ecSmrgstatic int 49805b261ecSmrgXvdiDestroyVideoNotifyList(pointer pn, XID id) 49905b261ecSmrg{ 50005b261ecSmrg XvVideoNotifyPtr npn,cpn; 50105b261ecSmrg 50205b261ecSmrg /* ACTUALLY DESTROY THE NOTITY LIST */ 50305b261ecSmrg 50405b261ecSmrg cpn = (XvVideoNotifyPtr)pn; 50505b261ecSmrg 50605b261ecSmrg while (cpn) 50705b261ecSmrg { 50805b261ecSmrg npn = cpn->next; 50905b261ecSmrg if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify); 51005b261ecSmrg xfree(cpn); 51105b261ecSmrg cpn = npn; 51205b261ecSmrg } 51305b261ecSmrg return Success; 51405b261ecSmrg} 51505b261ecSmrg 51605b261ecSmrgstatic int 51705b261ecSmrgXvdiDestroyEncoding(pointer value, XID id) 51805b261ecSmrg{ 51905b261ecSmrg return Success; 52005b261ecSmrg} 52105b261ecSmrg 52205b261ecSmrgstatic int 52305b261ecSmrgXvdiSendVideoNotify(pPort, pDraw, reason) 52405b261ecSmrg 52505b261ecSmrgXvPortPtr pPort; 52605b261ecSmrgDrawablePtr pDraw; 52705b261ecSmrgint reason; 52805b261ecSmrg 52905b261ecSmrg{ 53005b261ecSmrg xvEvent event; 53105b261ecSmrg XvVideoNotifyPtr pn; 53205b261ecSmrg 53305b261ecSmrg pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList); 53405b261ecSmrg 53505b261ecSmrg while (pn) 53605b261ecSmrg { 53705b261ecSmrg if (pn->client) 53805b261ecSmrg { 53905b261ecSmrg event.u.u.type = XvEventBase + XvVideoNotify; 54005b261ecSmrg event.u.u.sequenceNumber = pn->client->sequence; 54105b261ecSmrg event.u.videoNotify.time = currentTime.milliseconds; 54205b261ecSmrg event.u.videoNotify.drawable = pDraw->id; 54305b261ecSmrg event.u.videoNotify.port = pPort->id; 54405b261ecSmrg event.u.videoNotify.reason = reason; 5454642e01fSmrg TryClientEvents(pn->client, NULL, (xEventPtr)&event, 1, 5464642e01fSmrg NoEventMask, NoEventMask, NullGrab); 54705b261ecSmrg } 54805b261ecSmrg pn = pn->next; 54905b261ecSmrg } 55005b261ecSmrg 55105b261ecSmrg return Success; 55205b261ecSmrg 55305b261ecSmrg} 55405b261ecSmrg 55505b261ecSmrg 55605b261ecSmrgint 55705b261ecSmrgXvdiSendPortNotify( 55805b261ecSmrg XvPortPtr pPort, 55905b261ecSmrg Atom attribute, 56005b261ecSmrg INT32 value 56105b261ecSmrg){ 56205b261ecSmrg xvEvent event; 56305b261ecSmrg XvPortNotifyPtr pn; 56405b261ecSmrg 56505b261ecSmrg pn = pPort->pNotify; 56605b261ecSmrg 56705b261ecSmrg while (pn) 56805b261ecSmrg { 56905b261ecSmrg if (pn->client) 57005b261ecSmrg { 57105b261ecSmrg event.u.u.type = XvEventBase + XvPortNotify; 57205b261ecSmrg event.u.u.sequenceNumber = pn->client->sequence; 57305b261ecSmrg event.u.portNotify.time = currentTime.milliseconds; 57405b261ecSmrg event.u.portNotify.port = pPort->id; 57505b261ecSmrg event.u.portNotify.attribute = attribute; 57605b261ecSmrg event.u.portNotify.value = value; 5774642e01fSmrg TryClientEvents(pn->client, NULL, (xEventPtr)&event, 1, 5784642e01fSmrg NoEventMask, NoEventMask, NullGrab); 57905b261ecSmrg } 58005b261ecSmrg pn = pn->next; 58105b261ecSmrg } 58205b261ecSmrg 58305b261ecSmrg return Success; 58405b261ecSmrg 58505b261ecSmrg} 58605b261ecSmrg 58705b261ecSmrg 58805b261ecSmrg#define CHECK_SIZE(dw, dh, sw, sh) { \ 58905b261ecSmrg if(!dw || !dh || !sw || !sh) return Success; \ 59005b261ecSmrg /* The region code will break these if they are too large */ \ 59105b261ecSmrg if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \ 59205b261ecSmrg return BadValue; \ 59305b261ecSmrg} 59405b261ecSmrg 59505b261ecSmrg 59605b261ecSmrgint 59705b261ecSmrgXvdiPutVideo( 59805b261ecSmrg ClientPtr client, 59905b261ecSmrg DrawablePtr pDraw, 60005b261ecSmrg XvPortPtr pPort, 60105b261ecSmrg GCPtr pGC, 60205b261ecSmrg INT16 vid_x, INT16 vid_y, 60305b261ecSmrg CARD16 vid_w, CARD16 vid_h, 60405b261ecSmrg INT16 drw_x, INT16 drw_y, 60505b261ecSmrg CARD16 drw_w, CARD16 drw_h 60605b261ecSmrg){ 60705b261ecSmrg DrawablePtr pOldDraw; 60805b261ecSmrg 60905b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 61005b261ecSmrg 61105b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 61205b261ecSmrg 61305b261ecSmrg UpdateCurrentTime(); 61405b261ecSmrg 61505b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 61605b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 61705b261ecSmrg 61805b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 61905b261ecSmrg { 62005b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 62105b261ecSmrg return Success; 62205b261ecSmrg } 62305b261ecSmrg 62405b261ecSmrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 62505b261ecSmrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 62605b261ecSmrg 62705b261ecSmrg pOldDraw = pPort->pDraw; 62805b261ecSmrg if ((pOldDraw) && (pOldDraw != pDraw)) 62905b261ecSmrg { 63005b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 63105b261ecSmrg } 63205b261ecSmrg 63305b261ecSmrg (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC, 63405b261ecSmrg vid_x, vid_y, vid_w, vid_h, 63505b261ecSmrg drw_x, drw_y, drw_w, drw_h); 63605b261ecSmrg 63705b261ecSmrg if ((pPort->pDraw) && (pOldDraw != pDraw)) 63805b261ecSmrg { 63905b261ecSmrg pPort->client = client; 64005b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 64105b261ecSmrg } 64205b261ecSmrg 64305b261ecSmrg pPort->time = currentTime; 64405b261ecSmrg 64505b261ecSmrg return (Success); 64605b261ecSmrg 64705b261ecSmrg} 64805b261ecSmrg 64905b261ecSmrgint 65005b261ecSmrgXvdiPutStill( 65105b261ecSmrg ClientPtr client, 65205b261ecSmrg DrawablePtr pDraw, 65305b261ecSmrg XvPortPtr pPort, 65405b261ecSmrg GCPtr pGC, 65505b261ecSmrg INT16 vid_x, INT16 vid_y, 65605b261ecSmrg CARD16 vid_w, CARD16 vid_h, 65705b261ecSmrg INT16 drw_x, INT16 drw_y, 65805b261ecSmrg CARD16 drw_w, CARD16 drw_h 65905b261ecSmrg){ 66005b261ecSmrg int status; 66105b261ecSmrg 66205b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 66305b261ecSmrg 66405b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 66505b261ecSmrg 66605b261ecSmrg UpdateCurrentTime(); 66705b261ecSmrg 66805b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 66905b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 67005b261ecSmrg 67105b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 67205b261ecSmrg { 67305b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 67405b261ecSmrg return Success; 67505b261ecSmrg } 67605b261ecSmrg 67705b261ecSmrg pPort->time = currentTime; 67805b261ecSmrg 67905b261ecSmrg status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC, 68005b261ecSmrg vid_x, vid_y, vid_w, vid_h, 68105b261ecSmrg drw_x, drw_y, drw_w, drw_h); 68205b261ecSmrg 68305b261ecSmrg return status; 68405b261ecSmrg 68505b261ecSmrg} 68605b261ecSmrg 68705b261ecSmrgint 68805b261ecSmrgXvdiPutImage( 68905b261ecSmrg ClientPtr client, 69005b261ecSmrg DrawablePtr pDraw, 69105b261ecSmrg XvPortPtr pPort, 69205b261ecSmrg GCPtr pGC, 69305b261ecSmrg INT16 src_x, INT16 src_y, 69405b261ecSmrg CARD16 src_w, CARD16 src_h, 69505b261ecSmrg INT16 drw_x, INT16 drw_y, 69605b261ecSmrg CARD16 drw_w, CARD16 drw_h, 69705b261ecSmrg XvImagePtr image, 69805b261ecSmrg unsigned char* data, 69905b261ecSmrg Bool sync, 70005b261ecSmrg CARD16 width, CARD16 height 70105b261ecSmrg){ 70205b261ecSmrg CHECK_SIZE(drw_w, drw_h, src_w, src_h); 70305b261ecSmrg 70405b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 70505b261ecSmrg 70605b261ecSmrg UpdateCurrentTime(); 70705b261ecSmrg 70805b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 70905b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 71005b261ecSmrg 71105b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 71205b261ecSmrg { 71305b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 71405b261ecSmrg return Success; 71505b261ecSmrg } 71605b261ecSmrg 71705b261ecSmrg pPort->time = currentTime; 71805b261ecSmrg 71905b261ecSmrg return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC, 72005b261ecSmrg src_x, src_y, src_w, src_h, 72105b261ecSmrg drw_x, drw_y, drw_w, drw_h, 72205b261ecSmrg image, data, sync, width, height); 72305b261ecSmrg} 72405b261ecSmrg 72505b261ecSmrg 72605b261ecSmrgint 72705b261ecSmrgXvdiGetVideo( 72805b261ecSmrg ClientPtr client, 72905b261ecSmrg DrawablePtr pDraw, 73005b261ecSmrg XvPortPtr pPort, 73105b261ecSmrg GCPtr pGC, 73205b261ecSmrg INT16 vid_x, INT16 vid_y, 73305b261ecSmrg CARD16 vid_w, CARD16 vid_h, 73405b261ecSmrg INT16 drw_x, INT16 drw_y, 73505b261ecSmrg CARD16 drw_w, CARD16 drw_h 73605b261ecSmrg){ 73705b261ecSmrg DrawablePtr pOldDraw; 73805b261ecSmrg 73905b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 74005b261ecSmrg 74105b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 74205b261ecSmrg 74305b261ecSmrg UpdateCurrentTime(); 74405b261ecSmrg 74505b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 74605b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 74705b261ecSmrg 74805b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 74905b261ecSmrg { 75005b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 75105b261ecSmrg return Success; 75205b261ecSmrg } 75305b261ecSmrg 75405b261ecSmrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 75505b261ecSmrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 75605b261ecSmrg 75705b261ecSmrg pOldDraw = pPort->pDraw; 75805b261ecSmrg if ((pOldDraw) && (pOldDraw != pDraw)) 75905b261ecSmrg { 76005b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 76105b261ecSmrg } 76205b261ecSmrg 76305b261ecSmrg (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC, 76405b261ecSmrg vid_x, vid_y, vid_w, vid_h, 76505b261ecSmrg drw_x, drw_y, drw_w, drw_h); 76605b261ecSmrg 76705b261ecSmrg if ((pPort->pDraw) && (pOldDraw != pDraw)) 76805b261ecSmrg { 76905b261ecSmrg pPort->client = client; 77005b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 77105b261ecSmrg } 77205b261ecSmrg 77305b261ecSmrg pPort->time = currentTime; 77405b261ecSmrg 77505b261ecSmrg return (Success); 77605b261ecSmrg 77705b261ecSmrg} 77805b261ecSmrg 77905b261ecSmrgint 78005b261ecSmrgXvdiGetStill( 78105b261ecSmrg ClientPtr client, 78205b261ecSmrg DrawablePtr pDraw, 78305b261ecSmrg XvPortPtr pPort, 78405b261ecSmrg GCPtr pGC, 78505b261ecSmrg INT16 vid_x, INT16 vid_y, 78605b261ecSmrg CARD16 vid_w, CARD16 vid_h, 78705b261ecSmrg INT16 drw_x, INT16 drw_y, 78805b261ecSmrg CARD16 drw_w, CARD16 drw_h 78905b261ecSmrg){ 79005b261ecSmrg int status; 79105b261ecSmrg 79205b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 79305b261ecSmrg 79405b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 79505b261ecSmrg 79605b261ecSmrg UpdateCurrentTime(); 79705b261ecSmrg 79805b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 79905b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 80005b261ecSmrg 80105b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 80205b261ecSmrg { 80305b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 80405b261ecSmrg return Success; 80505b261ecSmrg } 80605b261ecSmrg 80705b261ecSmrg status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC, 80805b261ecSmrg vid_x, vid_y, vid_w, vid_h, 80905b261ecSmrg drw_x, drw_y, drw_w, drw_h); 81005b261ecSmrg 81105b261ecSmrg pPort->time = currentTime; 81205b261ecSmrg 81305b261ecSmrg return status; 81405b261ecSmrg 81505b261ecSmrg} 81605b261ecSmrg 81705b261ecSmrgint 81805b261ecSmrgXvdiGrabPort( 81905b261ecSmrg ClientPtr client, 82005b261ecSmrg XvPortPtr pPort, 82105b261ecSmrg Time ctime, 82205b261ecSmrg int *p_result 82305b261ecSmrg){ 82405b261ecSmrg unsigned long id; 82505b261ecSmrg TimeStamp time; 82605b261ecSmrg 82705b261ecSmrg UpdateCurrentTime(); 82805b261ecSmrg time = ClientTimeToServerTime(ctime); 82905b261ecSmrg 83005b261ecSmrg if (pPort->grab.client && (client != pPort->grab.client)) 83105b261ecSmrg { 83205b261ecSmrg *p_result = XvAlreadyGrabbed; 83305b261ecSmrg return Success; 83405b261ecSmrg } 83505b261ecSmrg 83605b261ecSmrg if ((CompareTimeStamps(time, currentTime) == LATER) || 83705b261ecSmrg (CompareTimeStamps(time, pPort->time) == EARLIER)) 83805b261ecSmrg { 83905b261ecSmrg *p_result = XvInvalidTime; 84005b261ecSmrg return Success; 84105b261ecSmrg } 84205b261ecSmrg 84305b261ecSmrg if (client == pPort->grab.client) 84405b261ecSmrg { 84505b261ecSmrg *p_result = Success; 84605b261ecSmrg return Success; 84705b261ecSmrg } 84805b261ecSmrg 84905b261ecSmrg id = FakeClientID(client->index); 85005b261ecSmrg 85105b261ecSmrg if (!AddResource(id, XvRTGrab, &pPort->grab)) 85205b261ecSmrg { 85305b261ecSmrg return BadAlloc; 85405b261ecSmrg } 85505b261ecSmrg 85605b261ecSmrg /* IF THERE IS ACTIVE VIDEO THEN STOP IT */ 85705b261ecSmrg 85805b261ecSmrg if ((pPort->pDraw) && (client != pPort->client)) 85905b261ecSmrg { 86005b261ecSmrg XVCALL(diStopVideo)((ClientPtr)NULL, pPort, pPort->pDraw); 86105b261ecSmrg } 86205b261ecSmrg 86305b261ecSmrg pPort->grab.client = client; 86405b261ecSmrg pPort->grab.id = id; 86505b261ecSmrg 86605b261ecSmrg pPort->time = currentTime; 86705b261ecSmrg 86805b261ecSmrg *p_result = Success; 86905b261ecSmrg 87005b261ecSmrg return Success; 87105b261ecSmrg 87205b261ecSmrg} 87305b261ecSmrg 87405b261ecSmrgint 87505b261ecSmrgXvdiUngrabPort( 87605b261ecSmrg ClientPtr client, 87705b261ecSmrg XvPortPtr pPort, 87805b261ecSmrg Time ctime 87905b261ecSmrg){ 88005b261ecSmrg TimeStamp time; 88105b261ecSmrg 88205b261ecSmrg UpdateCurrentTime(); 88305b261ecSmrg time = ClientTimeToServerTime(ctime); 88405b261ecSmrg 88505b261ecSmrg if ((!pPort->grab.client) || (client != pPort->grab.client)) 88605b261ecSmrg { 88705b261ecSmrg return Success; 88805b261ecSmrg } 88905b261ecSmrg 89005b261ecSmrg if ((CompareTimeStamps(time, currentTime) == LATER) || 89105b261ecSmrg (CompareTimeStamps(time, pPort->time) == EARLIER)) 89205b261ecSmrg { 89305b261ecSmrg return Success; 89405b261ecSmrg } 89505b261ecSmrg 89605b261ecSmrg /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */ 89705b261ecSmrg 89805b261ecSmrg FreeResource(pPort->grab.id, XvRTGrab); 89905b261ecSmrg pPort->grab.client = (ClientPtr)NULL; 90005b261ecSmrg 90105b261ecSmrg pPort->time = currentTime; 90205b261ecSmrg 90305b261ecSmrg return Success; 90405b261ecSmrg 90505b261ecSmrg} 90605b261ecSmrg 90705b261ecSmrg 90805b261ecSmrgint 90905b261ecSmrgXvdiSelectVideoNotify( 91005b261ecSmrg ClientPtr client, 91105b261ecSmrg DrawablePtr pDraw, 91205b261ecSmrg BOOL onoff 91305b261ecSmrg){ 91405b261ecSmrg XvVideoNotifyPtr pn,tpn,fpn; 91505b261ecSmrg 91605b261ecSmrg /* FIND VideoNotify LIST */ 91705b261ecSmrg 91805b261ecSmrg pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList); 91905b261ecSmrg 92005b261ecSmrg /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */ 92105b261ecSmrg 92205b261ecSmrg if (!onoff && !pn) return Success; 92305b261ecSmrg 92405b261ecSmrg /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST 92505b261ecSmrg WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */ 92605b261ecSmrg 92705b261ecSmrg if (!pn) 92805b261ecSmrg { 92905b261ecSmrg if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec)))) 93005b261ecSmrg return BadAlloc; 93105b261ecSmrg tpn->next = (XvVideoNotifyPtr)NULL; 93205b261ecSmrg if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) 93305b261ecSmrg { 93405b261ecSmrg xfree(tpn); 93505b261ecSmrg return BadAlloc; 93605b261ecSmrg } 93705b261ecSmrg } 93805b261ecSmrg else 93905b261ecSmrg { 94005b261ecSmrg /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ 94105b261ecSmrg 94205b261ecSmrg fpn = (XvVideoNotifyPtr)NULL; 94305b261ecSmrg tpn = pn; 94405b261ecSmrg while (tpn) 94505b261ecSmrg { 94605b261ecSmrg if (tpn->client == client) 94705b261ecSmrg { 94805b261ecSmrg if (!onoff) tpn->client = (ClientPtr)NULL; 94905b261ecSmrg return Success; 95005b261ecSmrg } 95105b261ecSmrg if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */ 95205b261ecSmrg tpn = tpn->next; 95305b261ecSmrg } 95405b261ecSmrg 95505b261ecSmrg /* IF TUNNING OFF, THEN JUST RETURN */ 95605b261ecSmrg 95705b261ecSmrg if (!onoff) return Success; 95805b261ecSmrg 95905b261ecSmrg /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */ 96005b261ecSmrg 96105b261ecSmrg if (fpn) 96205b261ecSmrg { 96305b261ecSmrg tpn = fpn; 96405b261ecSmrg } 96505b261ecSmrg else 96605b261ecSmrg { 96705b261ecSmrg if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec)))) 96805b261ecSmrg return BadAlloc; 96905b261ecSmrg tpn->next = pn->next; 97005b261ecSmrg pn->next = tpn; 97105b261ecSmrg } 97205b261ecSmrg } 97305b261ecSmrg 97405b261ecSmrg /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */ 97505b261ecSmrg /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */ 97605b261ecSmrg 97705b261ecSmrg tpn->client = (ClientPtr)NULL; 97805b261ecSmrg tpn->id = FakeClientID(client->index); 97905b261ecSmrg AddResource(tpn->id, XvRTVideoNotify, tpn); 98005b261ecSmrg 98105b261ecSmrg tpn->client = client; 98205b261ecSmrg return Success; 98305b261ecSmrg 98405b261ecSmrg} 98505b261ecSmrg 98605b261ecSmrgint 98705b261ecSmrgXvdiSelectPortNotify( 98805b261ecSmrg ClientPtr client, 98905b261ecSmrg XvPortPtr pPort, 99005b261ecSmrg BOOL onoff 99105b261ecSmrg){ 99205b261ecSmrg XvPortNotifyPtr pn,tpn; 99305b261ecSmrg 99405b261ecSmrg /* SEE IF CLIENT IS ALREADY IN LIST */ 99505b261ecSmrg 99605b261ecSmrg tpn = (XvPortNotifyPtr)NULL; 99705b261ecSmrg pn = pPort->pNotify; 99805b261ecSmrg while (pn) 99905b261ecSmrg { 100005b261ecSmrg if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */ 100105b261ecSmrg if (pn->client == client) break; 100205b261ecSmrg pn = pn->next; 100305b261ecSmrg } 100405b261ecSmrg 100505b261ecSmrg /* IS THE CLIENT ALREADY ON THE LIST? */ 100605b261ecSmrg 100705b261ecSmrg if (pn) 100805b261ecSmrg { 100905b261ecSmrg /* REMOVE IT? */ 101005b261ecSmrg 101105b261ecSmrg if (!onoff) 101205b261ecSmrg { 101305b261ecSmrg pn->client = (ClientPtr)NULL; 101405b261ecSmrg FreeResource(pn->id, XvRTPortNotify); 101505b261ecSmrg } 101605b261ecSmrg 101705b261ecSmrg return Success; 101805b261ecSmrg } 101905b261ecSmrg 102005b261ecSmrg /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE 102105b261ecSmrg CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */ 102205b261ecSmrg 102305b261ecSmrg if (!tpn) 102405b261ecSmrg { 102505b261ecSmrg if (!(tpn = (XvPortNotifyPtr)xalloc(sizeof(XvPortNotifyRec)))) 102605b261ecSmrg return BadAlloc; 102705b261ecSmrg tpn->next = pPort->pNotify; 102805b261ecSmrg pPort->pNotify = tpn; 102905b261ecSmrg } 103005b261ecSmrg 103105b261ecSmrg tpn->client = client; 103205b261ecSmrg tpn->id = FakeClientID(client->index); 103305b261ecSmrg AddResource(tpn->id, XvRTPortNotify, tpn); 103405b261ecSmrg 103505b261ecSmrg return Success; 103605b261ecSmrg 103705b261ecSmrg} 103805b261ecSmrg 103905b261ecSmrgint 104005b261ecSmrgXvdiStopVideo( 104105b261ecSmrg ClientPtr client, 104205b261ecSmrg XvPortPtr pPort, 104305b261ecSmrg DrawablePtr pDraw 104405b261ecSmrg){ 104505b261ecSmrg int status; 104605b261ecSmrg 104705b261ecSmrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 104805b261ecSmrg 104905b261ecSmrg if (!pPort->pDraw || (pPort->pDraw != pDraw)) 105005b261ecSmrg { 105105b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 105205b261ecSmrg return Success; 105305b261ecSmrg } 105405b261ecSmrg 105505b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 105605b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 105705b261ecSmrg 105805b261ecSmrg if ((client) && (pPort->grab.client) && (pPort->grab.client != client)) 105905b261ecSmrg { 106005b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 106105b261ecSmrg return Success; 106205b261ecSmrg } 106305b261ecSmrg 106405b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 106505b261ecSmrg 106605b261ecSmrg status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw); 106705b261ecSmrg 106805b261ecSmrg pPort->pDraw = (DrawablePtr)NULL; 106905b261ecSmrg pPort->client = (ClientPtr)client; 107005b261ecSmrg pPort->time = currentTime; 107105b261ecSmrg 107205b261ecSmrg return status; 107305b261ecSmrg 107405b261ecSmrg} 107505b261ecSmrg 107605b261ecSmrgint 107705b261ecSmrgXvdiPreemptVideo( 107805b261ecSmrg ClientPtr client, 107905b261ecSmrg XvPortPtr pPort, 108005b261ecSmrg DrawablePtr pDraw 108105b261ecSmrg){ 108205b261ecSmrg int status; 108305b261ecSmrg 108405b261ecSmrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 108505b261ecSmrg 108605b261ecSmrg if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success; 108705b261ecSmrg 108805b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 108905b261ecSmrg 109005b261ecSmrg status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw); 109105b261ecSmrg 109205b261ecSmrg pPort->pDraw = (DrawablePtr)NULL; 109305b261ecSmrg pPort->client = (ClientPtr)client; 109405b261ecSmrg pPort->time = currentTime; 109505b261ecSmrg 109605b261ecSmrg return status; 109705b261ecSmrg 109805b261ecSmrg} 109905b261ecSmrg 110005b261ecSmrgint 110105b261ecSmrgXvdiMatchPort( 110205b261ecSmrg XvPortPtr pPort, 110305b261ecSmrg DrawablePtr pDraw 110405b261ecSmrg){ 110505b261ecSmrg 110605b261ecSmrg XvAdaptorPtr pa; 110705b261ecSmrg XvFormatPtr pf; 110805b261ecSmrg int nf; 110905b261ecSmrg 111005b261ecSmrg pa = pPort->pAdaptor; 111105b261ecSmrg 111205b261ecSmrg if (pa->pScreen != pDraw->pScreen) return BadMatch; 111305b261ecSmrg 111405b261ecSmrg nf = pa->nFormats; 111505b261ecSmrg pf = pa->pFormats; 111605b261ecSmrg 111705b261ecSmrg while (nf--) 111805b261ecSmrg { 111905b261ecSmrg if ((pf->depth == pDraw->depth) 112005b261ecSmrg#if 0 112105b261ecSmrg && ((pDraw->type == DRAWABLE_PIXMAP) || 112205b261ecSmrg (wVisual(((WindowPtr)pDraw)) == pf->visual)) 112305b261ecSmrg#endif 112405b261ecSmrg ) 112505b261ecSmrg return Success; 112605b261ecSmrg pf++; 112705b261ecSmrg } 112805b261ecSmrg 112905b261ecSmrg return BadMatch; 113005b261ecSmrg 113105b261ecSmrg} 113205b261ecSmrg 113305b261ecSmrgint 113405b261ecSmrgXvdiSetPortAttribute( 113505b261ecSmrg ClientPtr client, 113605b261ecSmrg XvPortPtr pPort, 113705b261ecSmrg Atom attribute, 113805b261ecSmrg INT32 value 113905b261ecSmrg){ 114005b261ecSmrg 114105b261ecSmrg XvdiSendPortNotify(pPort, attribute, value); 114205b261ecSmrg 114305b261ecSmrg return 114405b261ecSmrg (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value); 114505b261ecSmrg 114605b261ecSmrg} 114705b261ecSmrg 114805b261ecSmrgint 114905b261ecSmrgXvdiGetPortAttribute( 115005b261ecSmrg ClientPtr client, 115105b261ecSmrg XvPortPtr pPort, 115205b261ecSmrg Atom attribute, 115305b261ecSmrg INT32 *p_value 115405b261ecSmrg){ 115505b261ecSmrg 115605b261ecSmrg return 115705b261ecSmrg (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value); 115805b261ecSmrg 115905b261ecSmrg} 116005b261ecSmrg 116105b261ecSmrgstatic void 116205b261ecSmrgWriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to) 116305b261ecSmrg 116405b261ecSmrg{ 116505b261ecSmrg 116605b261ecSmrg to->u.u.type = from->u.u.type; 116705b261ecSmrg to->u.u.detail = from->u.u.detail; 116805b261ecSmrg cpswaps(from->u.videoNotify.sequenceNumber, 116905b261ecSmrg to->u.videoNotify.sequenceNumber); 117005b261ecSmrg cpswapl(from->u.videoNotify.time, to->u.videoNotify.time); 117105b261ecSmrg cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable); 117205b261ecSmrg cpswapl(from->u.videoNotify.port, to->u.videoNotify.port); 117305b261ecSmrg 117405b261ecSmrg} 117505b261ecSmrg 117605b261ecSmrgstatic void 117705b261ecSmrgWriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to) 117805b261ecSmrg 117905b261ecSmrg{ 118005b261ecSmrg 118105b261ecSmrg to->u.u.type = from->u.u.type; 118205b261ecSmrg to->u.u.detail = from->u.u.detail; 118305b261ecSmrg cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber); 118405b261ecSmrg cpswapl(from->u.portNotify.time, to->u.portNotify.time); 118505b261ecSmrg cpswapl(from->u.portNotify.port, to->u.portNotify.port); 118605b261ecSmrg cpswapl(from->u.portNotify.value, to->u.portNotify.value); 118705b261ecSmrg 118805b261ecSmrg} 1189