xvmain.c revision 05b261ec
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#include "xvdisp.h" 10605b261ecSmrg#endif 10705b261ecSmrg 10805b261ecSmrgint XvScreenIndex = -1; 10905b261ecSmrgunsigned long XvExtensionGeneration = 0; 11005b261ecSmrgunsigned long XvScreenGeneration = 0; 11105b261ecSmrgunsigned long XvResourceGeneration = 0; 11205b261ecSmrg 11305b261ecSmrgint XvReqCode; 11405b261ecSmrgint XvEventBase; 11505b261ecSmrgint XvErrorBase; 11605b261ecSmrg 11705b261ecSmrgunsigned long XvRTPort; 11805b261ecSmrgunsigned long XvRTEncoding; 11905b261ecSmrgunsigned long XvRTGrab; 12005b261ecSmrgunsigned long XvRTVideoNotify; 12105b261ecSmrgunsigned long XvRTVideoNotifyList; 12205b261ecSmrgunsigned long XvRTPortNotify; 12305b261ecSmrg 12405b261ecSmrg 12505b261ecSmrg 12605b261ecSmrg/* EXTERNAL */ 12705b261ecSmrg 12805b261ecSmrgextern XID clientErrorValue; 12905b261ecSmrg 13005b261ecSmrgstatic void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); 13105b261ecSmrgstatic void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); 13205b261ecSmrgstatic Bool CreateResourceTypes(void); 13305b261ecSmrg 13405b261ecSmrgstatic Bool XvCloseScreen(int, ScreenPtr); 13505b261ecSmrgstatic Bool XvDestroyPixmap(PixmapPtr); 13605b261ecSmrgstatic Bool XvDestroyWindow(WindowPtr); 13705b261ecSmrgstatic void XvResetProc(ExtensionEntry*); 13805b261ecSmrgstatic int XvdiDestroyGrab(pointer, XID); 13905b261ecSmrgstatic int XvdiDestroyEncoding(pointer, XID); 14005b261ecSmrgstatic int XvdiDestroyVideoNotify(pointer, XID); 14105b261ecSmrgstatic int XvdiDestroyPortNotify(pointer, XID); 14205b261ecSmrgstatic int XvdiDestroyVideoNotifyList(pointer, XID); 14305b261ecSmrgstatic int XvdiDestroyPort(pointer, XID); 14405b261ecSmrgstatic int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int); 14505b261ecSmrg 14605b261ecSmrg 14705b261ecSmrg 14805b261ecSmrg 14905b261ecSmrg/* 15005b261ecSmrg** XvExtensionInit 15105b261ecSmrg** 15205b261ecSmrg** 15305b261ecSmrg*/ 15405b261ecSmrg 15505b261ecSmrgvoid 15605b261ecSmrgXvExtensionInit(void) 15705b261ecSmrg{ 15805b261ecSmrg ExtensionEntry *extEntry; 15905b261ecSmrg 16005b261ecSmrg /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN 16105b261ecSmrg INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */ 16205b261ecSmrg if (XvScreenGeneration != serverGeneration) 16305b261ecSmrg { 16405b261ecSmrg if (!CreateResourceTypes()) 16505b261ecSmrg { 16605b261ecSmrg ErrorF("XvExtensionInit: Unable to allocate resource types\n"); 16705b261ecSmrg return; 16805b261ecSmrg } 16905b261ecSmrg XvScreenIndex = AllocateScreenPrivateIndex (); 17005b261ecSmrg if (XvScreenIndex < 0) 17105b261ecSmrg { 17205b261ecSmrg ErrorF("XvExtensionInit: Unable to allocate screen private index\n"); 17305b261ecSmrg return; 17405b261ecSmrg } 17505b261ecSmrg#ifdef PANORAMIX 17605b261ecSmrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 17705b261ecSmrg#endif 17805b261ecSmrg XvScreenGeneration = serverGeneration; 17905b261ecSmrg } 18005b261ecSmrg 18105b261ecSmrg if (XvExtensionGeneration != serverGeneration) 18205b261ecSmrg { 18305b261ecSmrg XvExtensionGeneration = serverGeneration; 18405b261ecSmrg 18505b261ecSmrg extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, 18605b261ecSmrg ProcXvDispatch, SProcXvDispatch, 18705b261ecSmrg XvResetProc, StandardMinorOpcode); 18805b261ecSmrg if (!extEntry) 18905b261ecSmrg { 19005b261ecSmrg FatalError("XvExtensionInit: AddExtensions failed\n"); 19105b261ecSmrg } 19205b261ecSmrg 19305b261ecSmrg XvReqCode = extEntry->base; 19405b261ecSmrg XvEventBase = extEntry->eventBase; 19505b261ecSmrg XvErrorBase = extEntry->errorBase; 19605b261ecSmrg 19705b261ecSmrg EventSwapVector[XvEventBase+XvVideoNotify] = 19805b261ecSmrg (EventSwapPtr)WriteSwappedVideoNotifyEvent; 19905b261ecSmrg EventSwapVector[XvEventBase+XvPortNotify] = 20005b261ecSmrg (EventSwapPtr)WriteSwappedPortNotifyEvent; 20105b261ecSmrg 20205b261ecSmrg (void)MakeAtom(XvName, strlen(XvName), xTrue); 20305b261ecSmrg 20405b261ecSmrg } 20505b261ecSmrg} 20605b261ecSmrg 20705b261ecSmrgstatic Bool 20805b261ecSmrgCreateResourceTypes(void) 20905b261ecSmrg 21005b261ecSmrg{ 21105b261ecSmrg 21205b261ecSmrg if (XvResourceGeneration == serverGeneration) return TRUE; 21305b261ecSmrg 21405b261ecSmrg XvResourceGeneration = serverGeneration; 21505b261ecSmrg 21605b261ecSmrg if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort))) 21705b261ecSmrg { 21805b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate port resource.\n"); 21905b261ecSmrg return FALSE; 22005b261ecSmrg } 22105b261ecSmrg 22205b261ecSmrg if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab))) 22305b261ecSmrg { 22405b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate grab resource.\n"); 22505b261ecSmrg return FALSE; 22605b261ecSmrg } 22705b261ecSmrg 22805b261ecSmrg if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding))) 22905b261ecSmrg { 23005b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n"); 23105b261ecSmrg return FALSE; 23205b261ecSmrg } 23305b261ecSmrg 23405b261ecSmrg if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify))) 23505b261ecSmrg { 23605b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n"); 23705b261ecSmrg return FALSE; 23805b261ecSmrg } 23905b261ecSmrg 24005b261ecSmrg if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList))) 24105b261ecSmrg { 24205b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n"); 24305b261ecSmrg return FALSE; 24405b261ecSmrg } 24505b261ecSmrg 24605b261ecSmrg if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify))) 24705b261ecSmrg { 24805b261ecSmrg ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n"); 24905b261ecSmrg return FALSE; 25005b261ecSmrg } 25105b261ecSmrg 25205b261ecSmrg return TRUE; 25305b261ecSmrg 25405b261ecSmrg} 25505b261ecSmrg 25605b261ecSmrg_X_EXPORT int 25705b261ecSmrgXvScreenInit(ScreenPtr pScreen) 25805b261ecSmrg{ 25905b261ecSmrg XvScreenPtr pxvs; 26005b261ecSmrg 26105b261ecSmrg if (XvScreenGeneration != serverGeneration) 26205b261ecSmrg { 26305b261ecSmrg if (!CreateResourceTypes()) 26405b261ecSmrg { 26505b261ecSmrg ErrorF("XvScreenInit: Unable to allocate resource types\n"); 26605b261ecSmrg return BadAlloc; 26705b261ecSmrg } 26805b261ecSmrg XvScreenIndex = AllocateScreenPrivateIndex (); 26905b261ecSmrg if (XvScreenIndex < 0) 27005b261ecSmrg { 27105b261ecSmrg ErrorF("XvScreenInit: Unable to allocate screen private index\n"); 27205b261ecSmrg return BadAlloc; 27305b261ecSmrg } 27405b261ecSmrg#ifdef PANORAMIX 27505b261ecSmrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 27605b261ecSmrg#endif 27705b261ecSmrg XvScreenGeneration = serverGeneration; 27805b261ecSmrg } 27905b261ecSmrg 28005b261ecSmrg if (pScreen->devPrivates[XvScreenIndex].ptr) 28105b261ecSmrg { 28205b261ecSmrg ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n"); 28305b261ecSmrg } 28405b261ecSmrg 28505b261ecSmrg /* ALLOCATE SCREEN PRIVATE RECORD */ 28605b261ecSmrg 28705b261ecSmrg pxvs = (XvScreenPtr) xalloc (sizeof (XvScreenRec)); 28805b261ecSmrg if (!pxvs) 28905b261ecSmrg { 29005b261ecSmrg ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); 29105b261ecSmrg return BadAlloc; 29205b261ecSmrg } 29305b261ecSmrg 29405b261ecSmrg pScreen->devPrivates[XvScreenIndex].ptr = (pointer)pxvs; 29505b261ecSmrg 29605b261ecSmrg 29705b261ecSmrg pxvs->DestroyPixmap = pScreen->DestroyPixmap; 29805b261ecSmrg pxvs->DestroyWindow = pScreen->DestroyWindow; 29905b261ecSmrg pxvs->CloseScreen = pScreen->CloseScreen; 30005b261ecSmrg 30105b261ecSmrg pScreen->DestroyPixmap = XvDestroyPixmap; 30205b261ecSmrg pScreen->DestroyWindow = XvDestroyWindow; 30305b261ecSmrg pScreen->CloseScreen = XvCloseScreen; 30405b261ecSmrg 30505b261ecSmrg return Success; 30605b261ecSmrg} 30705b261ecSmrg 30805b261ecSmrgstatic Bool 30905b261ecSmrgXvCloseScreen( 31005b261ecSmrg int ii, 31105b261ecSmrg ScreenPtr pScreen 31205b261ecSmrg){ 31305b261ecSmrg 31405b261ecSmrg XvScreenPtr pxvs; 31505b261ecSmrg 31605b261ecSmrg pxvs = (XvScreenPtr) pScreen->devPrivates[XvScreenIndex].ptr; 31705b261ecSmrg 31805b261ecSmrg pScreen->DestroyPixmap = pxvs->DestroyPixmap; 31905b261ecSmrg pScreen->DestroyWindow = pxvs->DestroyWindow; 32005b261ecSmrg pScreen->CloseScreen = pxvs->CloseScreen; 32105b261ecSmrg 32205b261ecSmrg (* pxvs->ddCloseScreen)(ii, pScreen); 32305b261ecSmrg 32405b261ecSmrg xfree(pxvs); 32505b261ecSmrg 32605b261ecSmrg pScreen->devPrivates[XvScreenIndex].ptr = (pointer)NULL; 32705b261ecSmrg 32805b261ecSmrg return (*pScreen->CloseScreen)(ii, pScreen); 32905b261ecSmrg 33005b261ecSmrg} 33105b261ecSmrg 33205b261ecSmrgstatic void 33305b261ecSmrgXvResetProc(ExtensionEntry* extEntry) 33405b261ecSmrg{ 33505b261ecSmrg} 33605b261ecSmrg 33705b261ecSmrg_X_EXPORT int 33805b261ecSmrgXvGetScreenIndex(void) 33905b261ecSmrg{ 34005b261ecSmrg return XvScreenIndex; 34105b261ecSmrg} 34205b261ecSmrg 34305b261ecSmrg_X_EXPORT unsigned long 34405b261ecSmrgXvGetRTPort(void) 34505b261ecSmrg{ 34605b261ecSmrg return XvRTPort; 34705b261ecSmrg} 34805b261ecSmrg 34905b261ecSmrgstatic Bool 35005b261ecSmrgXvDestroyPixmap(PixmapPtr pPix) 35105b261ecSmrg{ 35205b261ecSmrg Bool status; 35305b261ecSmrg ScreenPtr pScreen; 35405b261ecSmrg XvScreenPtr pxvs; 35505b261ecSmrg XvAdaptorPtr pa; 35605b261ecSmrg int na; 35705b261ecSmrg XvPortPtr pp; 35805b261ecSmrg int np; 35905b261ecSmrg 36005b261ecSmrg pScreen = pPix->drawable.pScreen; 36105b261ecSmrg 36205b261ecSmrg SCREEN_PROLOGUE(pScreen, DestroyPixmap); 36305b261ecSmrg 36405b261ecSmrg pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr; 36505b261ecSmrg 36605b261ecSmrg /* CHECK TO SEE IF THIS PORT IS IN USE */ 36705b261ecSmrg 36805b261ecSmrg pa = pxvs->pAdaptors; 36905b261ecSmrg na = pxvs->nAdaptors; 37005b261ecSmrg while (na--) 37105b261ecSmrg { 37205b261ecSmrg np = pa->nPorts; 37305b261ecSmrg pp = pa->pPorts; 37405b261ecSmrg 37505b261ecSmrg while (np--) 37605b261ecSmrg { 37705b261ecSmrg if (pp->pDraw == (DrawablePtr)pPix) 37805b261ecSmrg { 37905b261ecSmrg XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); 38005b261ecSmrg 38105b261ecSmrg (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp, 38205b261ecSmrg pp->pDraw); 38305b261ecSmrg 38405b261ecSmrg pp->pDraw = (DrawablePtr)NULL; 38505b261ecSmrg pp->client = (ClientPtr)NULL; 38605b261ecSmrg pp->time = currentTime; 38705b261ecSmrg } 38805b261ecSmrg pp++; 38905b261ecSmrg } 39005b261ecSmrg pa++; 39105b261ecSmrg } 39205b261ecSmrg 39305b261ecSmrg status = (* pScreen->DestroyPixmap)(pPix); 39405b261ecSmrg 39505b261ecSmrg SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap); 39605b261ecSmrg 39705b261ecSmrg return status; 39805b261ecSmrg 39905b261ecSmrg} 40005b261ecSmrg 40105b261ecSmrgstatic Bool 40205b261ecSmrgXvDestroyWindow(WindowPtr pWin) 40305b261ecSmrg{ 40405b261ecSmrg Bool status; 40505b261ecSmrg ScreenPtr pScreen; 40605b261ecSmrg XvScreenPtr pxvs; 40705b261ecSmrg XvAdaptorPtr pa; 40805b261ecSmrg int na; 40905b261ecSmrg XvPortPtr pp; 41005b261ecSmrg int np; 41105b261ecSmrg 41205b261ecSmrg pScreen = pWin->drawable.pScreen; 41305b261ecSmrg 41405b261ecSmrg SCREEN_PROLOGUE(pScreen, DestroyWindow); 41505b261ecSmrg 41605b261ecSmrg pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr; 41705b261ecSmrg 41805b261ecSmrg /* CHECK TO SEE IF THIS PORT IS IN USE */ 41905b261ecSmrg 42005b261ecSmrg pa = pxvs->pAdaptors; 42105b261ecSmrg na = pxvs->nAdaptors; 42205b261ecSmrg while (na--) 42305b261ecSmrg { 42405b261ecSmrg np = pa->nPorts; 42505b261ecSmrg pp = pa->pPorts; 42605b261ecSmrg 42705b261ecSmrg while (np--) 42805b261ecSmrg { 42905b261ecSmrg if (pp->pDraw == (DrawablePtr)pWin) 43005b261ecSmrg { 43105b261ecSmrg XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); 43205b261ecSmrg 43305b261ecSmrg (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp, 43405b261ecSmrg pp->pDraw); 43505b261ecSmrg 43605b261ecSmrg pp->pDraw = (DrawablePtr)NULL; 43705b261ecSmrg pp->client = (ClientPtr)NULL; 43805b261ecSmrg pp->time = currentTime; 43905b261ecSmrg } 44005b261ecSmrg pp++; 44105b261ecSmrg } 44205b261ecSmrg pa++; 44305b261ecSmrg } 44405b261ecSmrg 44505b261ecSmrg 44605b261ecSmrg status = (* pScreen->DestroyWindow)(pWin); 44705b261ecSmrg 44805b261ecSmrg SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow); 44905b261ecSmrg 45005b261ecSmrg return status; 45105b261ecSmrg 45205b261ecSmrg} 45305b261ecSmrg 45405b261ecSmrg/* The XvdiVideoStopped procedure is a hook for the device dependent layer. 45505b261ecSmrg It provides a way for the dd layer to inform the di layer that video has 45605b261ecSmrg stopped in a port for reasons that the di layer had no control over; note 45705b261ecSmrg that it doesn't call back into the dd layer */ 45805b261ecSmrg 45905b261ecSmrgint 46005b261ecSmrgXvdiVideoStopped(XvPortPtr pPort, int reason) 46105b261ecSmrg{ 46205b261ecSmrg 46305b261ecSmrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 46405b261ecSmrg 46505b261ecSmrg if (!pPort->pDraw) return Success; 46605b261ecSmrg 46705b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, reason); 46805b261ecSmrg 46905b261ecSmrg pPort->pDraw = (DrawablePtr)NULL; 47005b261ecSmrg pPort->client = (ClientPtr)NULL; 47105b261ecSmrg pPort->time = currentTime; 47205b261ecSmrg 47305b261ecSmrg return Success; 47405b261ecSmrg 47505b261ecSmrg} 47605b261ecSmrg 47705b261ecSmrgstatic int 47805b261ecSmrgXvdiDestroyPort(pointer pPort, XID id) 47905b261ecSmrg{ 48005b261ecSmrg return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort); 48105b261ecSmrg} 48205b261ecSmrg 48305b261ecSmrgstatic int 48405b261ecSmrgXvdiDestroyGrab(pointer pGrab, XID id) 48505b261ecSmrg{ 48605b261ecSmrg ((XvGrabPtr)pGrab)->client = (ClientPtr)NULL; 48705b261ecSmrg return Success; 48805b261ecSmrg} 48905b261ecSmrg 49005b261ecSmrgstatic int 49105b261ecSmrgXvdiDestroyVideoNotify(pointer pn, XID id) 49205b261ecSmrg{ 49305b261ecSmrg /* JUST CLEAR OUT THE client POINTER FIELD */ 49405b261ecSmrg 49505b261ecSmrg ((XvVideoNotifyPtr)pn)->client = (ClientPtr)NULL; 49605b261ecSmrg return Success; 49705b261ecSmrg} 49805b261ecSmrg 49905b261ecSmrgstatic int 50005b261ecSmrgXvdiDestroyPortNotify(pointer pn, XID id) 50105b261ecSmrg{ 50205b261ecSmrg /* JUST CLEAR OUT THE client POINTER FIELD */ 50305b261ecSmrg 50405b261ecSmrg ((XvPortNotifyPtr)pn)->client = (ClientPtr)NULL; 50505b261ecSmrg return Success; 50605b261ecSmrg} 50705b261ecSmrg 50805b261ecSmrgstatic int 50905b261ecSmrgXvdiDestroyVideoNotifyList(pointer pn, XID id) 51005b261ecSmrg{ 51105b261ecSmrg XvVideoNotifyPtr npn,cpn; 51205b261ecSmrg 51305b261ecSmrg /* ACTUALLY DESTROY THE NOTITY LIST */ 51405b261ecSmrg 51505b261ecSmrg cpn = (XvVideoNotifyPtr)pn; 51605b261ecSmrg 51705b261ecSmrg while (cpn) 51805b261ecSmrg { 51905b261ecSmrg npn = cpn->next; 52005b261ecSmrg if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify); 52105b261ecSmrg xfree(cpn); 52205b261ecSmrg cpn = npn; 52305b261ecSmrg } 52405b261ecSmrg return Success; 52505b261ecSmrg} 52605b261ecSmrg 52705b261ecSmrgstatic int 52805b261ecSmrgXvdiDestroyEncoding(pointer value, XID id) 52905b261ecSmrg{ 53005b261ecSmrg return Success; 53105b261ecSmrg} 53205b261ecSmrg 53305b261ecSmrgstatic int 53405b261ecSmrgXvdiSendVideoNotify(pPort, pDraw, reason) 53505b261ecSmrg 53605b261ecSmrgXvPortPtr pPort; 53705b261ecSmrgDrawablePtr pDraw; 53805b261ecSmrgint reason; 53905b261ecSmrg 54005b261ecSmrg{ 54105b261ecSmrg xvEvent event; 54205b261ecSmrg XvVideoNotifyPtr pn; 54305b261ecSmrg 54405b261ecSmrg pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList); 54505b261ecSmrg 54605b261ecSmrg while (pn) 54705b261ecSmrg { 54805b261ecSmrg if (pn->client) 54905b261ecSmrg { 55005b261ecSmrg event.u.u.type = XvEventBase + XvVideoNotify; 55105b261ecSmrg event.u.u.sequenceNumber = pn->client->sequence; 55205b261ecSmrg event.u.videoNotify.time = currentTime.milliseconds; 55305b261ecSmrg event.u.videoNotify.drawable = pDraw->id; 55405b261ecSmrg event.u.videoNotify.port = pPort->id; 55505b261ecSmrg event.u.videoNotify.reason = reason; 55605b261ecSmrg (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask, 55705b261ecSmrg NoEventMask, NullGrab); 55805b261ecSmrg } 55905b261ecSmrg pn = pn->next; 56005b261ecSmrg } 56105b261ecSmrg 56205b261ecSmrg return Success; 56305b261ecSmrg 56405b261ecSmrg} 56505b261ecSmrg 56605b261ecSmrg 56705b261ecSmrgint 56805b261ecSmrgXvdiSendPortNotify( 56905b261ecSmrg XvPortPtr pPort, 57005b261ecSmrg Atom attribute, 57105b261ecSmrg INT32 value 57205b261ecSmrg){ 57305b261ecSmrg xvEvent event; 57405b261ecSmrg XvPortNotifyPtr pn; 57505b261ecSmrg 57605b261ecSmrg pn = pPort->pNotify; 57705b261ecSmrg 57805b261ecSmrg while (pn) 57905b261ecSmrg { 58005b261ecSmrg if (pn->client) 58105b261ecSmrg { 58205b261ecSmrg event.u.u.type = XvEventBase + XvPortNotify; 58305b261ecSmrg event.u.u.sequenceNumber = pn->client->sequence; 58405b261ecSmrg event.u.portNotify.time = currentTime.milliseconds; 58505b261ecSmrg event.u.portNotify.port = pPort->id; 58605b261ecSmrg event.u.portNotify.attribute = attribute; 58705b261ecSmrg event.u.portNotify.value = value; 58805b261ecSmrg (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask, 58905b261ecSmrg NoEventMask, NullGrab); 59005b261ecSmrg } 59105b261ecSmrg pn = pn->next; 59205b261ecSmrg } 59305b261ecSmrg 59405b261ecSmrg return Success; 59505b261ecSmrg 59605b261ecSmrg} 59705b261ecSmrg 59805b261ecSmrg 59905b261ecSmrg#define CHECK_SIZE(dw, dh, sw, sh) { \ 60005b261ecSmrg if(!dw || !dh || !sw || !sh) return Success; \ 60105b261ecSmrg /* The region code will break these if they are too large */ \ 60205b261ecSmrg if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \ 60305b261ecSmrg return BadValue; \ 60405b261ecSmrg} 60505b261ecSmrg 60605b261ecSmrg 60705b261ecSmrgint 60805b261ecSmrgXvdiPutVideo( 60905b261ecSmrg ClientPtr client, 61005b261ecSmrg DrawablePtr pDraw, 61105b261ecSmrg XvPortPtr pPort, 61205b261ecSmrg GCPtr pGC, 61305b261ecSmrg INT16 vid_x, INT16 vid_y, 61405b261ecSmrg CARD16 vid_w, CARD16 vid_h, 61505b261ecSmrg INT16 drw_x, INT16 drw_y, 61605b261ecSmrg CARD16 drw_w, CARD16 drw_h 61705b261ecSmrg){ 61805b261ecSmrg DrawablePtr pOldDraw; 61905b261ecSmrg 62005b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 62105b261ecSmrg 62205b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 62305b261ecSmrg 62405b261ecSmrg UpdateCurrentTime(); 62505b261ecSmrg 62605b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 62705b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 62805b261ecSmrg 62905b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 63005b261ecSmrg { 63105b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 63205b261ecSmrg return Success; 63305b261ecSmrg } 63405b261ecSmrg 63505b261ecSmrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 63605b261ecSmrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 63705b261ecSmrg 63805b261ecSmrg pOldDraw = pPort->pDraw; 63905b261ecSmrg if ((pOldDraw) && (pOldDraw != pDraw)) 64005b261ecSmrg { 64105b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 64205b261ecSmrg } 64305b261ecSmrg 64405b261ecSmrg (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC, 64505b261ecSmrg vid_x, vid_y, vid_w, vid_h, 64605b261ecSmrg drw_x, drw_y, drw_w, drw_h); 64705b261ecSmrg 64805b261ecSmrg if ((pPort->pDraw) && (pOldDraw != pDraw)) 64905b261ecSmrg { 65005b261ecSmrg pPort->client = client; 65105b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 65205b261ecSmrg } 65305b261ecSmrg 65405b261ecSmrg pPort->time = currentTime; 65505b261ecSmrg 65605b261ecSmrg return (Success); 65705b261ecSmrg 65805b261ecSmrg} 65905b261ecSmrg 66005b261ecSmrgint 66105b261ecSmrgXvdiPutStill( 66205b261ecSmrg ClientPtr client, 66305b261ecSmrg DrawablePtr pDraw, 66405b261ecSmrg XvPortPtr pPort, 66505b261ecSmrg GCPtr pGC, 66605b261ecSmrg INT16 vid_x, INT16 vid_y, 66705b261ecSmrg CARD16 vid_w, CARD16 vid_h, 66805b261ecSmrg INT16 drw_x, INT16 drw_y, 66905b261ecSmrg CARD16 drw_w, CARD16 drw_h 67005b261ecSmrg){ 67105b261ecSmrg int status; 67205b261ecSmrg 67305b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 67405b261ecSmrg 67505b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 67605b261ecSmrg 67705b261ecSmrg UpdateCurrentTime(); 67805b261ecSmrg 67905b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 68005b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 68105b261ecSmrg 68205b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 68305b261ecSmrg { 68405b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 68505b261ecSmrg return Success; 68605b261ecSmrg } 68705b261ecSmrg 68805b261ecSmrg pPort->time = currentTime; 68905b261ecSmrg 69005b261ecSmrg status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC, 69105b261ecSmrg vid_x, vid_y, vid_w, vid_h, 69205b261ecSmrg drw_x, drw_y, drw_w, drw_h); 69305b261ecSmrg 69405b261ecSmrg return status; 69505b261ecSmrg 69605b261ecSmrg} 69705b261ecSmrg 69805b261ecSmrgint 69905b261ecSmrgXvdiPutImage( 70005b261ecSmrg ClientPtr client, 70105b261ecSmrg DrawablePtr pDraw, 70205b261ecSmrg XvPortPtr pPort, 70305b261ecSmrg GCPtr pGC, 70405b261ecSmrg INT16 src_x, INT16 src_y, 70505b261ecSmrg CARD16 src_w, CARD16 src_h, 70605b261ecSmrg INT16 drw_x, INT16 drw_y, 70705b261ecSmrg CARD16 drw_w, CARD16 drw_h, 70805b261ecSmrg XvImagePtr image, 70905b261ecSmrg unsigned char* data, 71005b261ecSmrg Bool sync, 71105b261ecSmrg CARD16 width, CARD16 height 71205b261ecSmrg){ 71305b261ecSmrg CHECK_SIZE(drw_w, drw_h, src_w, src_h); 71405b261ecSmrg 71505b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 71605b261ecSmrg 71705b261ecSmrg UpdateCurrentTime(); 71805b261ecSmrg 71905b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 72005b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 72105b261ecSmrg 72205b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 72305b261ecSmrg { 72405b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 72505b261ecSmrg return Success; 72605b261ecSmrg } 72705b261ecSmrg 72805b261ecSmrg pPort->time = currentTime; 72905b261ecSmrg 73005b261ecSmrg return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC, 73105b261ecSmrg src_x, src_y, src_w, src_h, 73205b261ecSmrg drw_x, drw_y, drw_w, drw_h, 73305b261ecSmrg image, data, sync, width, height); 73405b261ecSmrg} 73505b261ecSmrg 73605b261ecSmrg 73705b261ecSmrgint 73805b261ecSmrgXvdiGetVideo( 73905b261ecSmrg ClientPtr client, 74005b261ecSmrg DrawablePtr pDraw, 74105b261ecSmrg XvPortPtr pPort, 74205b261ecSmrg GCPtr pGC, 74305b261ecSmrg INT16 vid_x, INT16 vid_y, 74405b261ecSmrg CARD16 vid_w, CARD16 vid_h, 74505b261ecSmrg INT16 drw_x, INT16 drw_y, 74605b261ecSmrg CARD16 drw_w, CARD16 drw_h 74705b261ecSmrg){ 74805b261ecSmrg DrawablePtr pOldDraw; 74905b261ecSmrg 75005b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 75105b261ecSmrg 75205b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 75305b261ecSmrg 75405b261ecSmrg UpdateCurrentTime(); 75505b261ecSmrg 75605b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 75705b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 75805b261ecSmrg 75905b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 76005b261ecSmrg { 76105b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 76205b261ecSmrg return Success; 76305b261ecSmrg } 76405b261ecSmrg 76505b261ecSmrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 76605b261ecSmrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 76705b261ecSmrg 76805b261ecSmrg pOldDraw = pPort->pDraw; 76905b261ecSmrg if ((pOldDraw) && (pOldDraw != pDraw)) 77005b261ecSmrg { 77105b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 77205b261ecSmrg } 77305b261ecSmrg 77405b261ecSmrg (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC, 77505b261ecSmrg vid_x, vid_y, vid_w, vid_h, 77605b261ecSmrg drw_x, drw_y, drw_w, drw_h); 77705b261ecSmrg 77805b261ecSmrg if ((pPort->pDraw) && (pOldDraw != pDraw)) 77905b261ecSmrg { 78005b261ecSmrg pPort->client = client; 78105b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 78205b261ecSmrg } 78305b261ecSmrg 78405b261ecSmrg pPort->time = currentTime; 78505b261ecSmrg 78605b261ecSmrg return (Success); 78705b261ecSmrg 78805b261ecSmrg} 78905b261ecSmrg 79005b261ecSmrgint 79105b261ecSmrgXvdiGetStill( 79205b261ecSmrg ClientPtr client, 79305b261ecSmrg DrawablePtr pDraw, 79405b261ecSmrg XvPortPtr pPort, 79505b261ecSmrg GCPtr pGC, 79605b261ecSmrg INT16 vid_x, INT16 vid_y, 79705b261ecSmrg CARD16 vid_w, CARD16 vid_h, 79805b261ecSmrg INT16 drw_x, INT16 drw_y, 79905b261ecSmrg CARD16 drw_w, CARD16 drw_h 80005b261ecSmrg){ 80105b261ecSmrg int status; 80205b261ecSmrg 80305b261ecSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 80405b261ecSmrg 80505b261ecSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 80605b261ecSmrg 80705b261ecSmrg UpdateCurrentTime(); 80805b261ecSmrg 80905b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 81005b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 81105b261ecSmrg 81205b261ecSmrg if (pPort->grab.client && (pPort->grab.client != client)) 81305b261ecSmrg { 81405b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 81505b261ecSmrg return Success; 81605b261ecSmrg } 81705b261ecSmrg 81805b261ecSmrg status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC, 81905b261ecSmrg vid_x, vid_y, vid_w, vid_h, 82005b261ecSmrg drw_x, drw_y, drw_w, drw_h); 82105b261ecSmrg 82205b261ecSmrg pPort->time = currentTime; 82305b261ecSmrg 82405b261ecSmrg return status; 82505b261ecSmrg 82605b261ecSmrg} 82705b261ecSmrg 82805b261ecSmrgint 82905b261ecSmrgXvdiGrabPort( 83005b261ecSmrg ClientPtr client, 83105b261ecSmrg XvPortPtr pPort, 83205b261ecSmrg Time ctime, 83305b261ecSmrg int *p_result 83405b261ecSmrg){ 83505b261ecSmrg unsigned long id; 83605b261ecSmrg TimeStamp time; 83705b261ecSmrg 83805b261ecSmrg UpdateCurrentTime(); 83905b261ecSmrg time = ClientTimeToServerTime(ctime); 84005b261ecSmrg 84105b261ecSmrg if (pPort->grab.client && (client != pPort->grab.client)) 84205b261ecSmrg { 84305b261ecSmrg *p_result = XvAlreadyGrabbed; 84405b261ecSmrg return Success; 84505b261ecSmrg } 84605b261ecSmrg 84705b261ecSmrg if ((CompareTimeStamps(time, currentTime) == LATER) || 84805b261ecSmrg (CompareTimeStamps(time, pPort->time) == EARLIER)) 84905b261ecSmrg { 85005b261ecSmrg *p_result = XvInvalidTime; 85105b261ecSmrg return Success; 85205b261ecSmrg } 85305b261ecSmrg 85405b261ecSmrg if (client == pPort->grab.client) 85505b261ecSmrg { 85605b261ecSmrg *p_result = Success; 85705b261ecSmrg return Success; 85805b261ecSmrg } 85905b261ecSmrg 86005b261ecSmrg id = FakeClientID(client->index); 86105b261ecSmrg 86205b261ecSmrg if (!AddResource(id, XvRTGrab, &pPort->grab)) 86305b261ecSmrg { 86405b261ecSmrg return BadAlloc; 86505b261ecSmrg } 86605b261ecSmrg 86705b261ecSmrg /* IF THERE IS ACTIVE VIDEO THEN STOP IT */ 86805b261ecSmrg 86905b261ecSmrg if ((pPort->pDraw) && (client != pPort->client)) 87005b261ecSmrg { 87105b261ecSmrg XVCALL(diStopVideo)((ClientPtr)NULL, pPort, pPort->pDraw); 87205b261ecSmrg } 87305b261ecSmrg 87405b261ecSmrg pPort->grab.client = client; 87505b261ecSmrg pPort->grab.id = id; 87605b261ecSmrg 87705b261ecSmrg pPort->time = currentTime; 87805b261ecSmrg 87905b261ecSmrg *p_result = Success; 88005b261ecSmrg 88105b261ecSmrg return Success; 88205b261ecSmrg 88305b261ecSmrg} 88405b261ecSmrg 88505b261ecSmrgint 88605b261ecSmrgXvdiUngrabPort( 88705b261ecSmrg ClientPtr client, 88805b261ecSmrg XvPortPtr pPort, 88905b261ecSmrg Time ctime 89005b261ecSmrg){ 89105b261ecSmrg TimeStamp time; 89205b261ecSmrg 89305b261ecSmrg UpdateCurrentTime(); 89405b261ecSmrg time = ClientTimeToServerTime(ctime); 89505b261ecSmrg 89605b261ecSmrg if ((!pPort->grab.client) || (client != pPort->grab.client)) 89705b261ecSmrg { 89805b261ecSmrg return Success; 89905b261ecSmrg } 90005b261ecSmrg 90105b261ecSmrg if ((CompareTimeStamps(time, currentTime) == LATER) || 90205b261ecSmrg (CompareTimeStamps(time, pPort->time) == EARLIER)) 90305b261ecSmrg { 90405b261ecSmrg return Success; 90505b261ecSmrg } 90605b261ecSmrg 90705b261ecSmrg /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */ 90805b261ecSmrg 90905b261ecSmrg FreeResource(pPort->grab.id, XvRTGrab); 91005b261ecSmrg pPort->grab.client = (ClientPtr)NULL; 91105b261ecSmrg 91205b261ecSmrg pPort->time = currentTime; 91305b261ecSmrg 91405b261ecSmrg return Success; 91505b261ecSmrg 91605b261ecSmrg} 91705b261ecSmrg 91805b261ecSmrg 91905b261ecSmrgint 92005b261ecSmrgXvdiSelectVideoNotify( 92105b261ecSmrg ClientPtr client, 92205b261ecSmrg DrawablePtr pDraw, 92305b261ecSmrg BOOL onoff 92405b261ecSmrg){ 92505b261ecSmrg XvVideoNotifyPtr pn,tpn,fpn; 92605b261ecSmrg 92705b261ecSmrg /* FIND VideoNotify LIST */ 92805b261ecSmrg 92905b261ecSmrg pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList); 93005b261ecSmrg 93105b261ecSmrg /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */ 93205b261ecSmrg 93305b261ecSmrg if (!onoff && !pn) return Success; 93405b261ecSmrg 93505b261ecSmrg /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST 93605b261ecSmrg WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */ 93705b261ecSmrg 93805b261ecSmrg if (!pn) 93905b261ecSmrg { 94005b261ecSmrg if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec)))) 94105b261ecSmrg return BadAlloc; 94205b261ecSmrg tpn->next = (XvVideoNotifyPtr)NULL; 94305b261ecSmrg if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) 94405b261ecSmrg { 94505b261ecSmrg xfree(tpn); 94605b261ecSmrg return BadAlloc; 94705b261ecSmrg } 94805b261ecSmrg } 94905b261ecSmrg else 95005b261ecSmrg { 95105b261ecSmrg /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ 95205b261ecSmrg 95305b261ecSmrg fpn = (XvVideoNotifyPtr)NULL; 95405b261ecSmrg tpn = pn; 95505b261ecSmrg while (tpn) 95605b261ecSmrg { 95705b261ecSmrg if (tpn->client == client) 95805b261ecSmrg { 95905b261ecSmrg if (!onoff) tpn->client = (ClientPtr)NULL; 96005b261ecSmrg return Success; 96105b261ecSmrg } 96205b261ecSmrg if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */ 96305b261ecSmrg tpn = tpn->next; 96405b261ecSmrg } 96505b261ecSmrg 96605b261ecSmrg /* IF TUNNING OFF, THEN JUST RETURN */ 96705b261ecSmrg 96805b261ecSmrg if (!onoff) return Success; 96905b261ecSmrg 97005b261ecSmrg /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */ 97105b261ecSmrg 97205b261ecSmrg if (fpn) 97305b261ecSmrg { 97405b261ecSmrg tpn = fpn; 97505b261ecSmrg } 97605b261ecSmrg else 97705b261ecSmrg { 97805b261ecSmrg if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec)))) 97905b261ecSmrg return BadAlloc; 98005b261ecSmrg tpn->next = pn->next; 98105b261ecSmrg pn->next = tpn; 98205b261ecSmrg } 98305b261ecSmrg } 98405b261ecSmrg 98505b261ecSmrg /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */ 98605b261ecSmrg /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */ 98705b261ecSmrg 98805b261ecSmrg tpn->client = (ClientPtr)NULL; 98905b261ecSmrg tpn->id = FakeClientID(client->index); 99005b261ecSmrg AddResource(tpn->id, XvRTVideoNotify, tpn); 99105b261ecSmrg 99205b261ecSmrg tpn->client = client; 99305b261ecSmrg return Success; 99405b261ecSmrg 99505b261ecSmrg} 99605b261ecSmrg 99705b261ecSmrgint 99805b261ecSmrgXvdiSelectPortNotify( 99905b261ecSmrg ClientPtr client, 100005b261ecSmrg XvPortPtr pPort, 100105b261ecSmrg BOOL onoff 100205b261ecSmrg){ 100305b261ecSmrg XvPortNotifyPtr pn,tpn; 100405b261ecSmrg 100505b261ecSmrg /* SEE IF CLIENT IS ALREADY IN LIST */ 100605b261ecSmrg 100705b261ecSmrg tpn = (XvPortNotifyPtr)NULL; 100805b261ecSmrg pn = pPort->pNotify; 100905b261ecSmrg while (pn) 101005b261ecSmrg { 101105b261ecSmrg if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */ 101205b261ecSmrg if (pn->client == client) break; 101305b261ecSmrg pn = pn->next; 101405b261ecSmrg } 101505b261ecSmrg 101605b261ecSmrg /* IS THE CLIENT ALREADY ON THE LIST? */ 101705b261ecSmrg 101805b261ecSmrg if (pn) 101905b261ecSmrg { 102005b261ecSmrg /* REMOVE IT? */ 102105b261ecSmrg 102205b261ecSmrg if (!onoff) 102305b261ecSmrg { 102405b261ecSmrg pn->client = (ClientPtr)NULL; 102505b261ecSmrg FreeResource(pn->id, XvRTPortNotify); 102605b261ecSmrg } 102705b261ecSmrg 102805b261ecSmrg return Success; 102905b261ecSmrg } 103005b261ecSmrg 103105b261ecSmrg /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE 103205b261ecSmrg CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */ 103305b261ecSmrg 103405b261ecSmrg if (!tpn) 103505b261ecSmrg { 103605b261ecSmrg if (!(tpn = (XvPortNotifyPtr)xalloc(sizeof(XvPortNotifyRec)))) 103705b261ecSmrg return BadAlloc; 103805b261ecSmrg tpn->next = pPort->pNotify; 103905b261ecSmrg pPort->pNotify = tpn; 104005b261ecSmrg } 104105b261ecSmrg 104205b261ecSmrg tpn->client = client; 104305b261ecSmrg tpn->id = FakeClientID(client->index); 104405b261ecSmrg AddResource(tpn->id, XvRTPortNotify, tpn); 104505b261ecSmrg 104605b261ecSmrg return Success; 104705b261ecSmrg 104805b261ecSmrg} 104905b261ecSmrg 105005b261ecSmrgint 105105b261ecSmrgXvdiStopVideo( 105205b261ecSmrg ClientPtr client, 105305b261ecSmrg XvPortPtr pPort, 105405b261ecSmrg DrawablePtr pDraw 105505b261ecSmrg){ 105605b261ecSmrg int status; 105705b261ecSmrg 105805b261ecSmrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 105905b261ecSmrg 106005b261ecSmrg if (!pPort->pDraw || (pPort->pDraw != pDraw)) 106105b261ecSmrg { 106205b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 106305b261ecSmrg return Success; 106405b261ecSmrg } 106505b261ecSmrg 106605b261ecSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 106705b261ecSmrg INFORM CLIENT OF ITS FAILURE */ 106805b261ecSmrg 106905b261ecSmrg if ((client) && (pPort->grab.client) && (pPort->grab.client != client)) 107005b261ecSmrg { 107105b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 107205b261ecSmrg return Success; 107305b261ecSmrg } 107405b261ecSmrg 107505b261ecSmrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 107605b261ecSmrg 107705b261ecSmrg status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw); 107805b261ecSmrg 107905b261ecSmrg pPort->pDraw = (DrawablePtr)NULL; 108005b261ecSmrg pPort->client = (ClientPtr)client; 108105b261ecSmrg pPort->time = currentTime; 108205b261ecSmrg 108305b261ecSmrg return status; 108405b261ecSmrg 108505b261ecSmrg} 108605b261ecSmrg 108705b261ecSmrgint 108805b261ecSmrgXvdiPreemptVideo( 108905b261ecSmrg ClientPtr client, 109005b261ecSmrg XvPortPtr pPort, 109105b261ecSmrg DrawablePtr pDraw 109205b261ecSmrg){ 109305b261ecSmrg int status; 109405b261ecSmrg 109505b261ecSmrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 109605b261ecSmrg 109705b261ecSmrg if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success; 109805b261ecSmrg 109905b261ecSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 110005b261ecSmrg 110105b261ecSmrg status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw); 110205b261ecSmrg 110305b261ecSmrg pPort->pDraw = (DrawablePtr)NULL; 110405b261ecSmrg pPort->client = (ClientPtr)client; 110505b261ecSmrg pPort->time = currentTime; 110605b261ecSmrg 110705b261ecSmrg return status; 110805b261ecSmrg 110905b261ecSmrg} 111005b261ecSmrg 111105b261ecSmrgint 111205b261ecSmrgXvdiMatchPort( 111305b261ecSmrg XvPortPtr pPort, 111405b261ecSmrg DrawablePtr pDraw 111505b261ecSmrg){ 111605b261ecSmrg 111705b261ecSmrg XvAdaptorPtr pa; 111805b261ecSmrg XvFormatPtr pf; 111905b261ecSmrg int nf; 112005b261ecSmrg 112105b261ecSmrg pa = pPort->pAdaptor; 112205b261ecSmrg 112305b261ecSmrg if (pa->pScreen != pDraw->pScreen) return BadMatch; 112405b261ecSmrg 112505b261ecSmrg nf = pa->nFormats; 112605b261ecSmrg pf = pa->pFormats; 112705b261ecSmrg 112805b261ecSmrg while (nf--) 112905b261ecSmrg { 113005b261ecSmrg if ((pf->depth == pDraw->depth) 113105b261ecSmrg#if 0 113205b261ecSmrg && ((pDraw->type == DRAWABLE_PIXMAP) || 113305b261ecSmrg (wVisual(((WindowPtr)pDraw)) == pf->visual)) 113405b261ecSmrg#endif 113505b261ecSmrg ) 113605b261ecSmrg return Success; 113705b261ecSmrg pf++; 113805b261ecSmrg } 113905b261ecSmrg 114005b261ecSmrg return BadMatch; 114105b261ecSmrg 114205b261ecSmrg} 114305b261ecSmrg 114405b261ecSmrgint 114505b261ecSmrgXvdiSetPortAttribute( 114605b261ecSmrg ClientPtr client, 114705b261ecSmrg XvPortPtr pPort, 114805b261ecSmrg Atom attribute, 114905b261ecSmrg INT32 value 115005b261ecSmrg){ 115105b261ecSmrg 115205b261ecSmrg XvdiSendPortNotify(pPort, attribute, value); 115305b261ecSmrg 115405b261ecSmrg return 115505b261ecSmrg (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value); 115605b261ecSmrg 115705b261ecSmrg} 115805b261ecSmrg 115905b261ecSmrgint 116005b261ecSmrgXvdiGetPortAttribute( 116105b261ecSmrg ClientPtr client, 116205b261ecSmrg XvPortPtr pPort, 116305b261ecSmrg Atom attribute, 116405b261ecSmrg INT32 *p_value 116505b261ecSmrg){ 116605b261ecSmrg 116705b261ecSmrg return 116805b261ecSmrg (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value); 116905b261ecSmrg 117005b261ecSmrg} 117105b261ecSmrg 117205b261ecSmrgstatic void 117305b261ecSmrgWriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to) 117405b261ecSmrg 117505b261ecSmrg{ 117605b261ecSmrg 117705b261ecSmrg to->u.u.type = from->u.u.type; 117805b261ecSmrg to->u.u.detail = from->u.u.detail; 117905b261ecSmrg cpswaps(from->u.videoNotify.sequenceNumber, 118005b261ecSmrg to->u.videoNotify.sequenceNumber); 118105b261ecSmrg cpswapl(from->u.videoNotify.time, to->u.videoNotify.time); 118205b261ecSmrg cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable); 118305b261ecSmrg cpswapl(from->u.videoNotify.port, to->u.videoNotify.port); 118405b261ecSmrg 118505b261ecSmrg} 118605b261ecSmrg 118705b261ecSmrgstatic void 118805b261ecSmrgWriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to) 118905b261ecSmrg 119005b261ecSmrg{ 119105b261ecSmrg 119205b261ecSmrg to->u.u.type = from->u.u.type; 119305b261ecSmrg to->u.u.detail = from->u.u.detail; 119405b261ecSmrg cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber); 119505b261ecSmrg cpswapl(from->u.portNotify.time, to->u.portNotify.time); 119605b261ecSmrg cpswapl(from->u.portNotify.port, to->u.portNotify.port); 119705b261ecSmrg cpswapl(from->u.portNotify.value, to->u.portNotify.value); 119805b261ecSmrg 119905b261ecSmrg} 1200