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