105b261ecSmrg/*********************************************************** 205b261ecSmrgCopyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, 305b261ecSmrgand the Massachusetts Institute of Technology, Cambridge, Massachusetts. 405b261ecSmrg 505b261ecSmrg All Rights Reserved 605b261ecSmrg 735c4bbdfSmrgPermission to use, copy, modify, and distribute this software and its 835c4bbdfSmrgdocumentation for any purpose and without fee is hereby granted, 905b261ecSmrgprovided that the above copyright notice appear in all copies and that 1035c4bbdfSmrgboth 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 1335c4bbdfSmrgsoftware 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/* 2635c4bbdfSmrg** File: 2705b261ecSmrg** 2805b261ecSmrg** xvmain.c --- Xv server extension main device independent module. 2935c4bbdfSmrg** 3035c4bbdfSmrg** 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 6135c4bbdfSmrg** 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" 8935c4bbdfSmrg#include "gcstruct.h" 9005b261ecSmrg#include "extnsionst.h" 9135c4bbdfSmrg#include "extinit.h" 9205b261ecSmrg#include "dixstruct.h" 9305b261ecSmrg#include "resource.h" 9405b261ecSmrg#include "opaque.h" 9505b261ecSmrg#include "input.h" 9605b261ecSmrg 9705b261ecSmrg#define GLOBAL 9805b261ecSmrg 9905b261ecSmrg#include <X11/extensions/Xv.h> 10005b261ecSmrg#include <X11/extensions/Xvproto.h> 10105b261ecSmrg#include "xvdix.h" 10205b261ecSmrg 10305b261ecSmrg#ifdef PANORAMIX 10405b261ecSmrg#include "panoramiX.h" 10505b261ecSmrg#include "panoramiXsrv.h" 10605b261ecSmrg#endif 1074642e01fSmrg#include "xvdisp.h" 10805b261ecSmrg 1096747b715Smrgstatic DevPrivateKeyRec XvScreenKeyRec; 11035c4bbdfSmrg 1116747b715Smrg#define XvScreenKey (&XvScreenKeyRec) 11205b261ecSmrgunsigned long XvExtensionGeneration = 0; 11305b261ecSmrgunsigned long XvScreenGeneration = 0; 11405b261ecSmrgunsigned long XvResourceGeneration = 0; 11505b261ecSmrg 11605b261ecSmrgint XvReqCode; 11705b261ecSmrgint XvEventBase; 11805b261ecSmrgint XvErrorBase; 11905b261ecSmrg 12035c4bbdfSmrgRESTYPE XvRTPort; 12135c4bbdfSmrgRESTYPE XvRTEncoding; 12235c4bbdfSmrgRESTYPE XvRTGrab; 12335c4bbdfSmrgRESTYPE XvRTVideoNotify; 12435c4bbdfSmrgRESTYPE XvRTVideoNotifyList; 12535c4bbdfSmrgRESTYPE XvRTPortNotify; 12605b261ecSmrg 12705b261ecSmrg/* EXTERNAL */ 12805b261ecSmrg 12905b261ecSmrgstatic void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); 13005b261ecSmrgstatic void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); 13105b261ecSmrgstatic Bool CreateResourceTypes(void); 13205b261ecSmrg 13335c4bbdfSmrgstatic Bool XvCloseScreen(ScreenPtr); 13405b261ecSmrgstatic Bool XvDestroyPixmap(PixmapPtr); 13505b261ecSmrgstatic Bool XvDestroyWindow(WindowPtr); 13635c4bbdfSmrgstatic void XvResetProc(ExtensionEntry *); 13735c4bbdfSmrgstatic int XvdiDestroyGrab(void *, XID); 13835c4bbdfSmrgstatic int XvdiDestroyEncoding(void *, XID); 13935c4bbdfSmrgstatic int XvdiDestroyVideoNotify(void *, XID); 14035c4bbdfSmrgstatic int XvdiDestroyPortNotify(void *, XID); 14135c4bbdfSmrgstatic int XvdiDestroyVideoNotifyList(void *, XID); 14235c4bbdfSmrgstatic int XvdiDestroyPort(void *, XID); 14305b261ecSmrgstatic int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int); 14405b261ecSmrg 14505b261ecSmrg/* 14605b261ecSmrg** XvExtensionInit 14705b261ecSmrg** 14805b261ecSmrg** 14905b261ecSmrg*/ 15005b261ecSmrg 1516747b715Smrgvoid 15205b261ecSmrgXvExtensionInit(void) 15305b261ecSmrg{ 15435c4bbdfSmrg ExtensionEntry *extEntry; 15535c4bbdfSmrg 15635c4bbdfSmrg if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) 15735c4bbdfSmrg return; 15835c4bbdfSmrg 15935c4bbdfSmrg /* Look to see if any screens were initialized; if not then 16035c4bbdfSmrg init global variables so the extension can function */ 16135c4bbdfSmrg if (XvScreenGeneration != serverGeneration) { 16235c4bbdfSmrg if (!CreateResourceTypes()) { 16335c4bbdfSmrg ErrorF("XvExtensionInit: Unable to allocate resource types\n"); 16435c4bbdfSmrg return; 16535c4bbdfSmrg } 16605b261ecSmrg#ifdef PANORAMIX 16705b261ecSmrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 16805b261ecSmrg#endif 16935c4bbdfSmrg XvScreenGeneration = serverGeneration; 17005b261ecSmrg } 17105b261ecSmrg 17235c4bbdfSmrg if (XvExtensionGeneration != serverGeneration) { 17335c4bbdfSmrg XvExtensionGeneration = serverGeneration; 17405b261ecSmrg 17535c4bbdfSmrg extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, 17635c4bbdfSmrg ProcXvDispatch, SProcXvDispatch, 17735c4bbdfSmrg XvResetProc, StandardMinorOpcode); 17835c4bbdfSmrg if (!extEntry) { 17935c4bbdfSmrg FatalError("XvExtensionInit: AddExtensions failed\n"); 18035c4bbdfSmrg } 18105b261ecSmrg 18235c4bbdfSmrg XvReqCode = extEntry->base; 18335c4bbdfSmrg XvEventBase = extEntry->eventBase; 18435c4bbdfSmrg XvErrorBase = extEntry->errorBase; 18505b261ecSmrg 18635c4bbdfSmrg EventSwapVector[XvEventBase + XvVideoNotify] = 18735c4bbdfSmrg (EventSwapPtr) WriteSwappedVideoNotifyEvent; 18835c4bbdfSmrg EventSwapVector[XvEventBase + XvPortNotify] = 18935c4bbdfSmrg (EventSwapPtr) WriteSwappedPortNotifyEvent; 19005b261ecSmrg 19135c4bbdfSmrg SetResourceTypeErrorValue(XvRTPort, _XvBadPort); 19235c4bbdfSmrg (void) MakeAtom(XvName, strlen(XvName), xTrue); 19305b261ecSmrg 19405b261ecSmrg } 19505b261ecSmrg} 19605b261ecSmrg 19705b261ecSmrgstatic Bool 19805b261ecSmrgCreateResourceTypes(void) 19905b261ecSmrg{ 20005b261ecSmrg 20135c4bbdfSmrg if (XvResourceGeneration == serverGeneration) 20235c4bbdfSmrg return TRUE; 20335c4bbdfSmrg 20435c4bbdfSmrg XvResourceGeneration = serverGeneration; 20505b261ecSmrg 20635c4bbdfSmrg if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort, "XvRTPort"))) { 20735c4bbdfSmrg ErrorF("CreateResourceTypes: failed to allocate port resource.\n"); 20835c4bbdfSmrg return FALSE; 20905b261ecSmrg } 2106747b715Smrg 21135c4bbdfSmrg if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab, "XvRTGrab"))) { 21235c4bbdfSmrg ErrorF("CreateResourceTypes: failed to allocate grab resource.\n"); 21335c4bbdfSmrg return FALSE; 21405b261ecSmrg } 2156747b715Smrg 21635c4bbdfSmrg if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding, 21735c4bbdfSmrg "XvRTEncoding"))) { 21835c4bbdfSmrg ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n"); 21935c4bbdfSmrg return FALSE; 22005b261ecSmrg } 2216747b715Smrg 22235c4bbdfSmrg if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify, 22335c4bbdfSmrg "XvRTVideoNotify"))) { 22435c4bbdfSmrg ErrorF 22535c4bbdfSmrg ("CreateResourceTypes: failed to allocate video notify resource.\n"); 22635c4bbdfSmrg return FALSE; 22705b261ecSmrg } 2286747b715Smrg 22935c4bbdfSmrg if (! 23035c4bbdfSmrg (XvRTVideoNotifyList = 23135c4bbdfSmrg CreateNewResourceType(XvdiDestroyVideoNotifyList, 23235c4bbdfSmrg "XvRTVideoNotifyList"))) { 23335c4bbdfSmrg ErrorF 23435c4bbdfSmrg ("CreateResourceTypes: failed to allocate video notify list resource.\n"); 23535c4bbdfSmrg return FALSE; 23605b261ecSmrg } 23705b261ecSmrg 23835c4bbdfSmrg if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify, 23935c4bbdfSmrg "XvRTPortNotify"))) { 24035c4bbdfSmrg ErrorF 24135c4bbdfSmrg ("CreateResourceTypes: failed to allocate port notify resource.\n"); 24235c4bbdfSmrg return FALSE; 24305b261ecSmrg } 24405b261ecSmrg 24535c4bbdfSmrg return TRUE; 24605b261ecSmrg 24705b261ecSmrg} 24805b261ecSmrg 2496747b715Smrgint 25005b261ecSmrgXvScreenInit(ScreenPtr pScreen) 25105b261ecSmrg{ 25235c4bbdfSmrg XvScreenPtr pxvs; 25335c4bbdfSmrg 25435c4bbdfSmrg if (XvScreenGeneration != serverGeneration) { 25535c4bbdfSmrg if (!CreateResourceTypes()) { 25635c4bbdfSmrg ErrorF("XvScreenInit: Unable to allocate resource types\n"); 25735c4bbdfSmrg return BadAlloc; 25835c4bbdfSmrg } 25905b261ecSmrg#ifdef PANORAMIX 26005b261ecSmrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 26105b261ecSmrg#endif 26235c4bbdfSmrg XvScreenGeneration = serverGeneration; 26305b261ecSmrg } 26405b261ecSmrg 26535c4bbdfSmrg if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) 26635c4bbdfSmrg return BadAlloc; 2676747b715Smrg 26835c4bbdfSmrg if (dixLookupPrivate(&pScreen->devPrivates, XvScreenKey)) { 26935c4bbdfSmrg ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n"); 27005b261ecSmrg } 27105b261ecSmrg 27235c4bbdfSmrg /* ALLOCATE SCREEN PRIVATE RECORD */ 27335c4bbdfSmrg 27435c4bbdfSmrg pxvs = malloc(sizeof(XvScreenRec)); 27535c4bbdfSmrg if (!pxvs) { 27635c4bbdfSmrg ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); 27735c4bbdfSmrg return BadAlloc; 27805b261ecSmrg } 27905b261ecSmrg 28035c4bbdfSmrg dixSetPrivate(&pScreen->devPrivates, XvScreenKey, pxvs); 28135c4bbdfSmrg 28235c4bbdfSmrg pxvs->DestroyPixmap = pScreen->DestroyPixmap; 28335c4bbdfSmrg pxvs->DestroyWindow = pScreen->DestroyWindow; 28435c4bbdfSmrg pxvs->CloseScreen = pScreen->CloseScreen; 28535c4bbdfSmrg 28635c4bbdfSmrg pScreen->DestroyPixmap = XvDestroyPixmap; 28735c4bbdfSmrg pScreen->DestroyWindow = XvDestroyWindow; 28835c4bbdfSmrg pScreen->CloseScreen = XvCloseScreen; 28935c4bbdfSmrg 29035c4bbdfSmrg return Success; 29105b261ecSmrg} 29205b261ecSmrg 29305b261ecSmrgstatic Bool 29435c4bbdfSmrgXvCloseScreen(ScreenPtr pScreen) 29535c4bbdfSmrg{ 29605b261ecSmrg 29735c4bbdfSmrg XvScreenPtr pxvs; 29805b261ecSmrg 29935c4bbdfSmrg pxvs = (XvScreenPtr) dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 30005b261ecSmrg 30135c4bbdfSmrg pScreen->DestroyPixmap = pxvs->DestroyPixmap; 30235c4bbdfSmrg pScreen->DestroyWindow = pxvs->DestroyWindow; 30335c4bbdfSmrg pScreen->CloseScreen = pxvs->CloseScreen; 30405b261ecSmrg 30535c4bbdfSmrg free(pxvs); 30605b261ecSmrg 30735c4bbdfSmrg dixSetPrivate(&pScreen->devPrivates, XvScreenKey, NULL); 30805b261ecSmrg 30935c4bbdfSmrg return (*pScreen->CloseScreen) (pScreen); 31005b261ecSmrg} 31105b261ecSmrg 31205b261ecSmrgstatic void 31335c4bbdfSmrgXvResetProc(ExtensionEntry * extEntry) 31405b261ecSmrg{ 3154642e01fSmrg XvResetProcVector(); 31605b261ecSmrg} 31705b261ecSmrg 3186747b715SmrgDevPrivateKey 3194642e01fSmrgXvGetScreenKey(void) 32005b261ecSmrg{ 3214642e01fSmrg return XvScreenKey; 32205b261ecSmrg} 32305b261ecSmrg 3246747b715Smrgunsigned long 32505b261ecSmrgXvGetRTPort(void) 32605b261ecSmrg{ 32735c4bbdfSmrg return XvRTPort; 32805b261ecSmrg} 32905b261ecSmrg 33035c4bbdfSmrgstatic void 33135c4bbdfSmrgXvStopAdaptors(DrawablePtr pDrawable) 33205b261ecSmrg{ 33335c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 33435c4bbdfSmrg XvScreenPtr pxvs = dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 33535c4bbdfSmrg XvAdaptorPtr pa = pxvs->pAdaptors; 33635c4bbdfSmrg int na = pxvs->nAdaptors; 33735c4bbdfSmrg 33835c4bbdfSmrg /* CHECK TO SEE IF THIS PORT IS IN USE */ 33935c4bbdfSmrg while (na--) { 34035c4bbdfSmrg XvPortPtr pp = pa->pPorts; 34135c4bbdfSmrg int np = pa->nPorts; 34235c4bbdfSmrg 34335c4bbdfSmrg while (np--) { 34435c4bbdfSmrg if (pp->pDraw == pDrawable) { 34535c4bbdfSmrg XvdiSendVideoNotify(pp, pDrawable, XvPreempted); 34635c4bbdfSmrg 34735c4bbdfSmrg (void) (*pp->pAdaptor->ddStopVideo) (pp, pDrawable); 34835c4bbdfSmrg 34935c4bbdfSmrg pp->pDraw = NULL; 35035c4bbdfSmrg pp->client = NULL; 35135c4bbdfSmrg pp->time = currentTime; 35235c4bbdfSmrg } 35335c4bbdfSmrg pp++; 35435c4bbdfSmrg } 35535c4bbdfSmrg pa++; 35605b261ecSmrg } 35705b261ecSmrg} 35805b261ecSmrg 35905b261ecSmrgstatic Bool 36035c4bbdfSmrgXvDestroyPixmap(PixmapPtr pPix) 36105b261ecSmrg{ 36235c4bbdfSmrg ScreenPtr pScreen = pPix->drawable.pScreen; 36335c4bbdfSmrg Bool status; 36405b261ecSmrg 36535c4bbdfSmrg if (pPix->refcnt == 1) 36635c4bbdfSmrg XvStopAdaptors(&pPix->drawable); 36705b261ecSmrg 36835c4bbdfSmrg SCREEN_PROLOGUE(pScreen, DestroyPixmap); 36935c4bbdfSmrg status = (*pScreen->DestroyPixmap) (pPix); 37035c4bbdfSmrg SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap); 37105b261ecSmrg 37235c4bbdfSmrg return status; 37305b261ecSmrg 37405b261ecSmrg} 37505b261ecSmrg 37635c4bbdfSmrgstatic Bool 37735c4bbdfSmrgXvDestroyWindow(WindowPtr pWin) 37805b261ecSmrg{ 37935c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 38035c4bbdfSmrg Bool status; 38105b261ecSmrg 38235c4bbdfSmrg XvStopAdaptors(&pWin->drawable); 38305b261ecSmrg 38435c4bbdfSmrg SCREEN_PROLOGUE(pScreen, DestroyWindow); 38535c4bbdfSmrg status = (*pScreen->DestroyWindow) (pWin); 38635c4bbdfSmrg SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow); 38705b261ecSmrg 38835c4bbdfSmrg return status; 38905b261ecSmrg 39005b261ecSmrg} 39105b261ecSmrg 39235c4bbdfSmrgstatic int 39335c4bbdfSmrgXvdiDestroyPort(void *pPort, XID id) 39405b261ecSmrg{ 39535c4bbdfSmrg return Success; 39605b261ecSmrg} 39705b261ecSmrg 39805b261ecSmrgstatic int 39935c4bbdfSmrgXvdiDestroyGrab(void *pGrab, XID id) 40005b261ecSmrg{ 40135c4bbdfSmrg ((XvGrabPtr) pGrab)->client = NULL; 40235c4bbdfSmrg return Success; 40305b261ecSmrg} 40405b261ecSmrg 40505b261ecSmrgstatic int 40635c4bbdfSmrgXvdiDestroyVideoNotify(void *pn, XID id) 40705b261ecSmrg{ 40835c4bbdfSmrg /* JUST CLEAR OUT THE client POINTER FIELD */ 40905b261ecSmrg 41035c4bbdfSmrg ((XvVideoNotifyPtr) pn)->client = NULL; 41135c4bbdfSmrg return Success; 41205b261ecSmrg} 41305b261ecSmrg 41405b261ecSmrgstatic int 41535c4bbdfSmrgXvdiDestroyPortNotify(void *pn, XID id) 41605b261ecSmrg{ 41735c4bbdfSmrg /* JUST CLEAR OUT THE client POINTER FIELD */ 41805b261ecSmrg 41935c4bbdfSmrg ((XvPortNotifyPtr) pn)->client = NULL; 42035c4bbdfSmrg return Success; 42105b261ecSmrg} 42205b261ecSmrg 42305b261ecSmrgstatic int 42435c4bbdfSmrgXvdiDestroyVideoNotifyList(void *pn, XID id) 42505b261ecSmrg{ 42635c4bbdfSmrg XvVideoNotifyPtr npn, cpn; 42705b261ecSmrg 428ed6184dfSmrg /* ACTUALLY DESTROY THE NOTIFY LIST */ 42905b261ecSmrg 43035c4bbdfSmrg cpn = (XvVideoNotifyPtr) pn; 43105b261ecSmrg 43235c4bbdfSmrg while (cpn) { 43335c4bbdfSmrg npn = cpn->next; 43435c4bbdfSmrg if (cpn->client) 43535c4bbdfSmrg FreeResource(cpn->id, XvRTVideoNotify); 43635c4bbdfSmrg free(cpn); 43735c4bbdfSmrg cpn = npn; 43805b261ecSmrg } 43935c4bbdfSmrg return Success; 44005b261ecSmrg} 44105b261ecSmrg 44205b261ecSmrgstatic int 44335c4bbdfSmrgXvdiDestroyEncoding(void *value, XID id) 44405b261ecSmrg{ 44535c4bbdfSmrg return Success; 44605b261ecSmrg} 44705b261ecSmrg 44805b261ecSmrgstatic int 4496747b715SmrgXvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason) 45005b261ecSmrg{ 45135c4bbdfSmrg XvVideoNotifyPtr pn; 45235c4bbdfSmrg 45335c4bbdfSmrg dixLookupResourceByType((void **) &pn, pDraw->id, XvRTVideoNotifyList, 45435c4bbdfSmrg serverClient, DixReadAccess); 45535c4bbdfSmrg 45635c4bbdfSmrg while (pn) { 45735c4bbdfSmrg xvEvent event = { 45835c4bbdfSmrg .u.videoNotify.reason = reason, 45935c4bbdfSmrg .u.videoNotify.time = currentTime.milliseconds, 46035c4bbdfSmrg .u.videoNotify.drawable = pDraw->id, 46135c4bbdfSmrg .u.videoNotify.port = pPort->id 46235c4bbdfSmrg }; 46335c4bbdfSmrg event.u.u.type = XvEventBase + XvVideoNotify; 46435c4bbdfSmrg WriteEventsToClient(pn->client, 1, (xEventPtr) &event); 46535c4bbdfSmrg pn = pn->next; 46605b261ecSmrg } 46705b261ecSmrg 46835c4bbdfSmrg return Success; 46905b261ecSmrg 47005b261ecSmrg} 47105b261ecSmrg 47205b261ecSmrgint 47335c4bbdfSmrgXvdiSendPortNotify(XvPortPtr pPort, Atom attribute, INT32 value) 47435c4bbdfSmrg{ 47535c4bbdfSmrg XvPortNotifyPtr pn; 47635c4bbdfSmrg 47735c4bbdfSmrg pn = pPort->pNotify; 47835c4bbdfSmrg 47935c4bbdfSmrg while (pn) { 48035c4bbdfSmrg xvEvent event = { 48135c4bbdfSmrg .u.portNotify.time = currentTime.milliseconds, 48235c4bbdfSmrg .u.portNotify.port = pPort->id, 48335c4bbdfSmrg .u.portNotify.attribute = attribute, 48435c4bbdfSmrg .u.portNotify.value = value 48535c4bbdfSmrg }; 48635c4bbdfSmrg event.u.u.type = XvEventBase + XvPortNotify; 48735c4bbdfSmrg WriteEventsToClient(pn->client, 1, (xEventPtr) &event); 48835c4bbdfSmrg pn = pn->next; 48905b261ecSmrg } 49005b261ecSmrg 49135c4bbdfSmrg return Success; 49205b261ecSmrg 49305b261ecSmrg} 49405b261ecSmrg 49505b261ecSmrg#define CHECK_SIZE(dw, dh, sw, sh) { \ 49605b261ecSmrg if(!dw || !dh || !sw || !sh) return Success; \ 49705b261ecSmrg /* The region code will break these if they are too large */ \ 49805b261ecSmrg if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \ 49905b261ecSmrg return BadValue; \ 50005b261ecSmrg} 50105b261ecSmrg 50205b261ecSmrgint 50335c4bbdfSmrgXvdiPutVideo(ClientPtr client, 50435c4bbdfSmrg DrawablePtr pDraw, 50535c4bbdfSmrg XvPortPtr pPort, 50635c4bbdfSmrg GCPtr pGC, 50735c4bbdfSmrg INT16 vid_x, INT16 vid_y, 50835c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 50935c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 51035c4bbdfSmrg{ 51135c4bbdfSmrg DrawablePtr pOldDraw; 51235c4bbdfSmrg 51335c4bbdfSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 51435c4bbdfSmrg 51535c4bbdfSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 51635c4bbdfSmrg 51735c4bbdfSmrg UpdateCurrentTime(); 51835c4bbdfSmrg 51935c4bbdfSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 52035c4bbdfSmrg INFORM CLIENT OF ITS FAILURE */ 52135c4bbdfSmrg 52235c4bbdfSmrg if (pPort->grab.client && (pPort->grab.client != client)) { 52335c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 52435c4bbdfSmrg return Success; 52505b261ecSmrg } 52605b261ecSmrg 52735c4bbdfSmrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 52835c4bbdfSmrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 52905b261ecSmrg 53035c4bbdfSmrg pOldDraw = pPort->pDraw; 53135c4bbdfSmrg if ((pOldDraw) && (pOldDraw != pDraw)) { 53235c4bbdfSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 53305b261ecSmrg } 53405b261ecSmrg 53535c4bbdfSmrg (void) (*pPort->pAdaptor->ddPutVideo) (pDraw, pPort, pGC, 53635c4bbdfSmrg vid_x, vid_y, vid_w, vid_h, 53735c4bbdfSmrg drw_x, drw_y, drw_w, drw_h); 53805b261ecSmrg 53935c4bbdfSmrg if ((pPort->pDraw) && (pOldDraw != pDraw)) { 54035c4bbdfSmrg pPort->client = client; 54135c4bbdfSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 54205b261ecSmrg } 54305b261ecSmrg 54435c4bbdfSmrg pPort->time = currentTime; 54505b261ecSmrg 54635c4bbdfSmrg return Success; 54705b261ecSmrg 54805b261ecSmrg} 54905b261ecSmrg 55005b261ecSmrgint 55135c4bbdfSmrgXvdiPutStill(ClientPtr client, 55235c4bbdfSmrg DrawablePtr pDraw, 55335c4bbdfSmrg XvPortPtr pPort, 55435c4bbdfSmrg GCPtr pGC, 55535c4bbdfSmrg INT16 vid_x, INT16 vid_y, 55635c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 55735c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 55835c4bbdfSmrg{ 55935c4bbdfSmrg int status; 56035c4bbdfSmrg 56135c4bbdfSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 56235c4bbdfSmrg 56335c4bbdfSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 56435c4bbdfSmrg 56535c4bbdfSmrg UpdateCurrentTime(); 56635c4bbdfSmrg 56735c4bbdfSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 56835c4bbdfSmrg INFORM CLIENT OF ITS FAILURE */ 56935c4bbdfSmrg 57035c4bbdfSmrg if (pPort->grab.client && (pPort->grab.client != client)) { 57135c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 57235c4bbdfSmrg return Success; 57305b261ecSmrg } 57405b261ecSmrg 57535c4bbdfSmrg pPort->time = currentTime; 57605b261ecSmrg 57735c4bbdfSmrg status = (*pPort->pAdaptor->ddPutStill) (pDraw, pPort, pGC, 57835c4bbdfSmrg vid_x, vid_y, vid_w, vid_h, 57935c4bbdfSmrg drw_x, drw_y, drw_w, drw_h); 58005b261ecSmrg 58135c4bbdfSmrg return status; 58205b261ecSmrg 58305b261ecSmrg} 58405b261ecSmrg 58505b261ecSmrgint 58635c4bbdfSmrgXvdiPutImage(ClientPtr client, 58735c4bbdfSmrg DrawablePtr pDraw, 58835c4bbdfSmrg XvPortPtr pPort, 58935c4bbdfSmrg GCPtr pGC, 59035c4bbdfSmrg INT16 src_x, INT16 src_y, 59135c4bbdfSmrg CARD16 src_w, CARD16 src_h, 59235c4bbdfSmrg INT16 drw_x, INT16 drw_y, 59335c4bbdfSmrg CARD16 drw_w, CARD16 drw_h, 59435c4bbdfSmrg XvImagePtr image, 59535c4bbdfSmrg unsigned char *data, Bool sync, CARD16 width, CARD16 height) 59635c4bbdfSmrg{ 59735c4bbdfSmrg CHECK_SIZE(drw_w, drw_h, src_w, src_h); 59835c4bbdfSmrg 59935c4bbdfSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 60035c4bbdfSmrg 60135c4bbdfSmrg UpdateCurrentTime(); 60235c4bbdfSmrg 60335c4bbdfSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 60435c4bbdfSmrg INFORM CLIENT OF ITS FAILURE */ 60535c4bbdfSmrg 60635c4bbdfSmrg if (pPort->grab.client && (pPort->grab.client != client)) { 60735c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 60835c4bbdfSmrg return Success; 60905b261ecSmrg } 61005b261ecSmrg 61135c4bbdfSmrg pPort->time = currentTime; 61205b261ecSmrg 61335c4bbdfSmrg return (*pPort->pAdaptor->ddPutImage) (pDraw, pPort, pGC, 61435c4bbdfSmrg src_x, src_y, src_w, src_h, 61535c4bbdfSmrg drw_x, drw_y, drw_w, drw_h, 61635c4bbdfSmrg image, data, sync, width, height); 61705b261ecSmrg} 61805b261ecSmrg 61905b261ecSmrgint 62035c4bbdfSmrgXvdiGetVideo(ClientPtr client, 62135c4bbdfSmrg DrawablePtr pDraw, 62235c4bbdfSmrg XvPortPtr pPort, 62335c4bbdfSmrg GCPtr pGC, 62435c4bbdfSmrg INT16 vid_x, INT16 vid_y, 62535c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 62635c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 62735c4bbdfSmrg{ 62835c4bbdfSmrg DrawablePtr pOldDraw; 62935c4bbdfSmrg 63035c4bbdfSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 63135c4bbdfSmrg 63235c4bbdfSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 63335c4bbdfSmrg 63435c4bbdfSmrg UpdateCurrentTime(); 63535c4bbdfSmrg 63635c4bbdfSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 63735c4bbdfSmrg INFORM CLIENT OF ITS FAILURE */ 63835c4bbdfSmrg 63935c4bbdfSmrg if (pPort->grab.client && (pPort->grab.client != client)) { 64035c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 64135c4bbdfSmrg return Success; 64205b261ecSmrg } 64305b261ecSmrg 64435c4bbdfSmrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 64535c4bbdfSmrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 64605b261ecSmrg 64735c4bbdfSmrg pOldDraw = pPort->pDraw; 64835c4bbdfSmrg if ((pOldDraw) && (pOldDraw != pDraw)) { 64935c4bbdfSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 65005b261ecSmrg } 65105b261ecSmrg 65235c4bbdfSmrg (void) (*pPort->pAdaptor->ddGetVideo) (pDraw, pPort, pGC, 65335c4bbdfSmrg vid_x, vid_y, vid_w, vid_h, 65435c4bbdfSmrg drw_x, drw_y, drw_w, drw_h); 65505b261ecSmrg 65635c4bbdfSmrg if ((pPort->pDraw) && (pOldDraw != pDraw)) { 65735c4bbdfSmrg pPort->client = client; 65835c4bbdfSmrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 65905b261ecSmrg } 66005b261ecSmrg 66135c4bbdfSmrg pPort->time = currentTime; 66205b261ecSmrg 66335c4bbdfSmrg return Success; 66405b261ecSmrg 66505b261ecSmrg} 66605b261ecSmrg 66705b261ecSmrgint 66835c4bbdfSmrgXvdiGetStill(ClientPtr client, 66935c4bbdfSmrg DrawablePtr pDraw, 67035c4bbdfSmrg XvPortPtr pPort, 67135c4bbdfSmrg GCPtr pGC, 67235c4bbdfSmrg INT16 vid_x, INT16 vid_y, 67335c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 67435c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 67535c4bbdfSmrg{ 67635c4bbdfSmrg int status; 67735c4bbdfSmrg 67835c4bbdfSmrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 67935c4bbdfSmrg 68035c4bbdfSmrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 68135c4bbdfSmrg 68235c4bbdfSmrg UpdateCurrentTime(); 68335c4bbdfSmrg 68435c4bbdfSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 68535c4bbdfSmrg INFORM CLIENT OF ITS FAILURE */ 68635c4bbdfSmrg 68735c4bbdfSmrg if (pPort->grab.client && (pPort->grab.client != client)) { 68835c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 68935c4bbdfSmrg return Success; 69005b261ecSmrg } 69105b261ecSmrg 69235c4bbdfSmrg status = (*pPort->pAdaptor->ddGetStill) (pDraw, pPort, pGC, 69335c4bbdfSmrg vid_x, vid_y, vid_w, vid_h, 69435c4bbdfSmrg drw_x, drw_y, drw_w, drw_h); 69505b261ecSmrg 69635c4bbdfSmrg pPort->time = currentTime; 69705b261ecSmrg 69835c4bbdfSmrg return status; 69905b261ecSmrg 70005b261ecSmrg} 70105b261ecSmrg 70205b261ecSmrgint 70335c4bbdfSmrgXvdiGrabPort(ClientPtr client, XvPortPtr pPort, Time ctime, int *p_result) 70435c4bbdfSmrg{ 70535c4bbdfSmrg unsigned long id; 70635c4bbdfSmrg TimeStamp time; 70735c4bbdfSmrg 70835c4bbdfSmrg UpdateCurrentTime(); 70935c4bbdfSmrg time = ClientTimeToServerTime(ctime); 71035c4bbdfSmrg 71135c4bbdfSmrg if (pPort->grab.client && (client != pPort->grab.client)) { 71235c4bbdfSmrg *p_result = XvAlreadyGrabbed; 71335c4bbdfSmrg return Success; 71405b261ecSmrg } 71505b261ecSmrg 71635c4bbdfSmrg if ((CompareTimeStamps(time, currentTime) == LATER) || 71735c4bbdfSmrg (CompareTimeStamps(time, pPort->time) == EARLIER)) { 71835c4bbdfSmrg *p_result = XvInvalidTime; 71935c4bbdfSmrg return Success; 72005b261ecSmrg } 72105b261ecSmrg 72235c4bbdfSmrg if (client == pPort->grab.client) { 72335c4bbdfSmrg *p_result = Success; 72435c4bbdfSmrg return Success; 72505b261ecSmrg } 72605b261ecSmrg 72735c4bbdfSmrg id = FakeClientID(client->index); 72805b261ecSmrg 72935c4bbdfSmrg if (!AddResource(id, XvRTGrab, &pPort->grab)) { 73035c4bbdfSmrg return BadAlloc; 73105b261ecSmrg } 73205b261ecSmrg 73335c4bbdfSmrg /* IF THERE IS ACTIVE VIDEO THEN STOP IT */ 73405b261ecSmrg 73535c4bbdfSmrg if ((pPort->pDraw) && (client != pPort->client)) { 73635c4bbdfSmrg XvdiStopVideo(NULL, pPort, pPort->pDraw); 73705b261ecSmrg } 73805b261ecSmrg 73935c4bbdfSmrg pPort->grab.client = client; 74035c4bbdfSmrg pPort->grab.id = id; 74105b261ecSmrg 74235c4bbdfSmrg pPort->time = currentTime; 74305b261ecSmrg 74435c4bbdfSmrg *p_result = Success; 74505b261ecSmrg 74635c4bbdfSmrg return Success; 74705b261ecSmrg 74805b261ecSmrg} 74905b261ecSmrg 75005b261ecSmrgint 75135c4bbdfSmrgXvdiUngrabPort(ClientPtr client, XvPortPtr pPort, Time ctime) 75235c4bbdfSmrg{ 75335c4bbdfSmrg TimeStamp time; 75435c4bbdfSmrg 75535c4bbdfSmrg UpdateCurrentTime(); 75635c4bbdfSmrg time = ClientTimeToServerTime(ctime); 75735c4bbdfSmrg 75835c4bbdfSmrg if ((!pPort->grab.client) || (client != pPort->grab.client)) { 75935c4bbdfSmrg return Success; 76005b261ecSmrg } 76105b261ecSmrg 76235c4bbdfSmrg if ((CompareTimeStamps(time, currentTime) == LATER) || 76335c4bbdfSmrg (CompareTimeStamps(time, pPort->time) == EARLIER)) { 76435c4bbdfSmrg return Success; 76505b261ecSmrg } 76605b261ecSmrg 76735c4bbdfSmrg /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */ 76805b261ecSmrg 76935c4bbdfSmrg FreeResource(pPort->grab.id, XvRTGrab); 77035c4bbdfSmrg pPort->grab.client = NULL; 77105b261ecSmrg 77235c4bbdfSmrg pPort->time = currentTime; 77305b261ecSmrg 77435c4bbdfSmrg return Success; 77505b261ecSmrg 77605b261ecSmrg} 77705b261ecSmrg 77805b261ecSmrgint 77935c4bbdfSmrgXvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff) 78035c4bbdfSmrg{ 78135c4bbdfSmrg XvVideoNotifyPtr pn, tpn, fpn; 78235c4bbdfSmrg int rc; 78335c4bbdfSmrg 78435c4bbdfSmrg /* FIND VideoNotify LIST */ 78535c4bbdfSmrg 78635c4bbdfSmrg rc = dixLookupResourceByType((void **) &pn, pDraw->id, 78735c4bbdfSmrg XvRTVideoNotifyList, client, DixWriteAccess); 78835c4bbdfSmrg if (rc != Success && rc != BadValue) 78935c4bbdfSmrg return rc; 79035c4bbdfSmrg 79135c4bbdfSmrg /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */ 79235c4bbdfSmrg 79335c4bbdfSmrg if (!onoff && !pn) 79435c4bbdfSmrg return Success; 79535c4bbdfSmrg 79635c4bbdfSmrg /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST 79735c4bbdfSmrg WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */ 79835c4bbdfSmrg 79935c4bbdfSmrg if (!pn) { 80035c4bbdfSmrg if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) 80135c4bbdfSmrg return BadAlloc; 80235c4bbdfSmrg tpn->next = NULL; 80335c4bbdfSmrg tpn->client = NULL; 80435c4bbdfSmrg if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) 80535c4bbdfSmrg return BadAlloc; 80605b261ecSmrg } 80735c4bbdfSmrg else { 80835c4bbdfSmrg /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ 80935c4bbdfSmrg 81035c4bbdfSmrg fpn = NULL; 81135c4bbdfSmrg tpn = pn; 81235c4bbdfSmrg while (tpn) { 81335c4bbdfSmrg if (tpn->client == client) { 814c82838c1Smrg if (!onoff) { 81535c4bbdfSmrg tpn->client = NULL; 816c82838c1Smrg FreeResource(tpn->id, XvRTVideoNotify); 817c82838c1Smrg } 81835c4bbdfSmrg return Success; 81935c4bbdfSmrg } 82035c4bbdfSmrg if (!tpn->client) 82135c4bbdfSmrg fpn = tpn; /* TAKE NOTE OF FREE ENTRY */ 82235c4bbdfSmrg tpn = tpn->next; 82335c4bbdfSmrg } 82435c4bbdfSmrg 825ed6184dfSmrg /* IF TURNING OFF, THEN JUST RETURN */ 82635c4bbdfSmrg 82735c4bbdfSmrg if (!onoff) 82835c4bbdfSmrg return Success; 82935c4bbdfSmrg 83035c4bbdfSmrg /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */ 83135c4bbdfSmrg 83235c4bbdfSmrg if (fpn) { 83335c4bbdfSmrg tpn = fpn; 83435c4bbdfSmrg } 83535c4bbdfSmrg else { 83635c4bbdfSmrg if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) 83735c4bbdfSmrg return BadAlloc; 83835c4bbdfSmrg tpn->next = pn->next; 83935c4bbdfSmrg pn->next = tpn; 84035c4bbdfSmrg } 84105b261ecSmrg } 84205b261ecSmrg 84335c4bbdfSmrg /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */ 84435c4bbdfSmrg /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */ 84505b261ecSmrg 84635c4bbdfSmrg tpn->client = NULL; 84735c4bbdfSmrg tpn->id = FakeClientID(client->index); 84835c4bbdfSmrg if (!AddResource(tpn->id, XvRTVideoNotify, tpn)) 84935c4bbdfSmrg return BadAlloc; 85005b261ecSmrg 85135c4bbdfSmrg tpn->client = client; 85235c4bbdfSmrg return Success; 85305b261ecSmrg 85405b261ecSmrg} 85505b261ecSmrg 85605b261ecSmrgint 85735c4bbdfSmrgXvdiSelectPortNotify(ClientPtr client, XvPortPtr pPort, BOOL onoff) 85835c4bbdfSmrg{ 85935c4bbdfSmrg XvPortNotifyPtr pn, tpn; 86035c4bbdfSmrg 86135c4bbdfSmrg /* SEE IF CLIENT IS ALREADY IN LIST */ 86235c4bbdfSmrg 86335c4bbdfSmrg tpn = NULL; 86435c4bbdfSmrg pn = pPort->pNotify; 86535c4bbdfSmrg while (pn) { 86635c4bbdfSmrg if (!pn->client) 86735c4bbdfSmrg tpn = pn; /* TAKE NOTE OF FREE ENTRY */ 86835c4bbdfSmrg if (pn->client == client) 86935c4bbdfSmrg break; 87035c4bbdfSmrg pn = pn->next; 87105b261ecSmrg } 87205b261ecSmrg 87335c4bbdfSmrg /* IS THE CLIENT ALREADY ON THE LIST? */ 87405b261ecSmrg 87535c4bbdfSmrg if (pn) { 87635c4bbdfSmrg /* REMOVE IT? */ 87705b261ecSmrg 87835c4bbdfSmrg if (!onoff) { 87935c4bbdfSmrg pn->client = NULL; 88035c4bbdfSmrg FreeResource(pn->id, XvRTPortNotify); 88135c4bbdfSmrg } 88205b261ecSmrg 88335c4bbdfSmrg return Success; 88405b261ecSmrg } 88505b261ecSmrg 88635c4bbdfSmrg /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE 88735c4bbdfSmrg CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */ 88805b261ecSmrg 88935c4bbdfSmrg if (!tpn) { 89035c4bbdfSmrg if (!(tpn = malloc(sizeof(XvPortNotifyRec)))) 89135c4bbdfSmrg return BadAlloc; 89235c4bbdfSmrg tpn->next = pPort->pNotify; 89335c4bbdfSmrg pPort->pNotify = tpn; 89405b261ecSmrg } 89505b261ecSmrg 89635c4bbdfSmrg tpn->client = client; 89735c4bbdfSmrg tpn->id = FakeClientID(client->index); 89835c4bbdfSmrg if (!AddResource(tpn->id, XvRTPortNotify, tpn)) 89935c4bbdfSmrg return BadAlloc; 90005b261ecSmrg 90135c4bbdfSmrg return Success; 90205b261ecSmrg 90305b261ecSmrg} 90405b261ecSmrg 90505b261ecSmrgint 90635c4bbdfSmrgXvdiStopVideo(ClientPtr client, XvPortPtr pPort, DrawablePtr pDraw) 90735c4bbdfSmrg{ 90835c4bbdfSmrg int status; 90935c4bbdfSmrg 91035c4bbdfSmrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 91135c4bbdfSmrg 91235c4bbdfSmrg if (!pPort->pDraw || (pPort->pDraw != pDraw)) { 91335c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 91435c4bbdfSmrg return Success; 91505b261ecSmrg } 91605b261ecSmrg 91735c4bbdfSmrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 91835c4bbdfSmrg INFORM CLIENT OF ITS FAILURE */ 91905b261ecSmrg 92035c4bbdfSmrg if ((client) && (pPort->grab.client) && (pPort->grab.client != client)) { 92135c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 92235c4bbdfSmrg return Success; 92305b261ecSmrg } 92405b261ecSmrg 92535c4bbdfSmrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 92605b261ecSmrg 92735c4bbdfSmrg status = (*pPort->pAdaptor->ddStopVideo) (pPort, pDraw); 92805b261ecSmrg 92935c4bbdfSmrg pPort->pDraw = NULL; 93035c4bbdfSmrg pPort->client = (ClientPtr) client; 93135c4bbdfSmrg pPort->time = currentTime; 93205b261ecSmrg 93335c4bbdfSmrg return status; 93405b261ecSmrg 93505b261ecSmrg} 93605b261ecSmrg 93705b261ecSmrgint 93835c4bbdfSmrgXvdiMatchPort(XvPortPtr pPort, DrawablePtr pDraw) 93935c4bbdfSmrg{ 94005b261ecSmrg 94135c4bbdfSmrg XvAdaptorPtr pa; 94235c4bbdfSmrg XvFormatPtr pf; 94335c4bbdfSmrg int nf; 94405b261ecSmrg 94535c4bbdfSmrg pa = pPort->pAdaptor; 94605b261ecSmrg 94735c4bbdfSmrg if (pa->pScreen != pDraw->pScreen) 94835c4bbdfSmrg return BadMatch; 94905b261ecSmrg 95035c4bbdfSmrg nf = pa->nFormats; 95135c4bbdfSmrg pf = pa->pFormats; 95205b261ecSmrg 95335c4bbdfSmrg while (nf--) { 95435c4bbdfSmrg if (pf->depth == pDraw->depth) 95535c4bbdfSmrg return Success; 95635c4bbdfSmrg pf++; 95735c4bbdfSmrg } 95805b261ecSmrg 95935c4bbdfSmrg return BadMatch; 96005b261ecSmrg 96105b261ecSmrg} 96205b261ecSmrg 96305b261ecSmrgint 96435c4bbdfSmrgXvdiSetPortAttribute(ClientPtr client, 96535c4bbdfSmrg XvPortPtr pPort, Atom attribute, INT32 value) 96635c4bbdfSmrg{ 96735c4bbdfSmrg int status; 96805b261ecSmrg 96935c4bbdfSmrg status = 97035c4bbdfSmrg (*pPort->pAdaptor->ddSetPortAttribute) (pPort, attribute, 97135c4bbdfSmrg value); 97235c4bbdfSmrg if (status == Success) 97335c4bbdfSmrg XvdiSendPortNotify(pPort, attribute, value); 97405b261ecSmrg 97535c4bbdfSmrg return status; 97635c4bbdfSmrg} 97705b261ecSmrg 97835c4bbdfSmrgint 97935c4bbdfSmrgXvdiGetPortAttribute(ClientPtr client, 98035c4bbdfSmrg XvPortPtr pPort, Atom attribute, INT32 *p_value) 98135c4bbdfSmrg{ 98205b261ecSmrg 98335c4bbdfSmrg return 98435c4bbdfSmrg (*pPort->pAdaptor->ddGetPortAttribute) (pPort, attribute, 98535c4bbdfSmrg p_value); 98605b261ecSmrg 98735c4bbdfSmrg} 98805b261ecSmrg 9891b5d61b8Smrgstatic void _X_COLD 99035c4bbdfSmrgWriteSwappedVideoNotifyEvent(xvEvent * from, xvEvent * to) 99135c4bbdfSmrg{ 99205b261ecSmrg 99335c4bbdfSmrg to->u.u.type = from->u.u.type; 99435c4bbdfSmrg to->u.u.detail = from->u.u.detail; 99535c4bbdfSmrg cpswaps(from->u.videoNotify.sequenceNumber, 99635c4bbdfSmrg to->u.videoNotify.sequenceNumber); 99735c4bbdfSmrg cpswapl(from->u.videoNotify.time, to->u.videoNotify.time); 99835c4bbdfSmrg cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable); 99935c4bbdfSmrg cpswapl(from->u.videoNotify.port, to->u.videoNotify.port); 100005b261ecSmrg 100105b261ecSmrg} 100205b261ecSmrg 10031b5d61b8Smrgstatic void _X_COLD 100435c4bbdfSmrgWriteSwappedPortNotifyEvent(xvEvent * from, xvEvent * to) 100535c4bbdfSmrg{ 100605b261ecSmrg 100735c4bbdfSmrg to->u.u.type = from->u.u.type; 100835c4bbdfSmrg to->u.u.detail = from->u.u.detail; 100935c4bbdfSmrg cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber); 101035c4bbdfSmrg cpswapl(from->u.portNotify.time, to->u.portNotify.time); 101135c4bbdfSmrg cpswapl(from->u.portNotify.port, to->u.portNotify.port); 101235c4bbdfSmrg cpswapl(from->u.portNotify.value, to->u.portNotify.value); 101305b261ecSmrg 101405b261ecSmrg} 101505b261ecSmrg 101635c4bbdfSmrgvoid 101735c4bbdfSmrgXvFreeAdaptor(XvAdaptorPtr pAdaptor) 101805b261ecSmrg{ 101935c4bbdfSmrg int i; 102005b261ecSmrg 102135c4bbdfSmrg free(pAdaptor->name); 102235c4bbdfSmrg pAdaptor->name = NULL; 102305b261ecSmrg 102435c4bbdfSmrg if (pAdaptor->pEncodings) { 102535c4bbdfSmrg XvEncodingPtr pEncode = pAdaptor->pEncodings; 102605b261ecSmrg 102735c4bbdfSmrg for (i = 0; i < pAdaptor->nEncodings; i++, pEncode++) 102835c4bbdfSmrg free(pEncode->name); 102935c4bbdfSmrg free(pAdaptor->pEncodings); 103035c4bbdfSmrg pAdaptor->pEncodings = NULL; 103135c4bbdfSmrg } 103205b261ecSmrg 103335c4bbdfSmrg free(pAdaptor->pFormats); 103435c4bbdfSmrg pAdaptor->pFormats = NULL; 103535c4bbdfSmrg 103635c4bbdfSmrg free(pAdaptor->pPorts); 103735c4bbdfSmrg pAdaptor->pPorts = NULL; 103835c4bbdfSmrg 103935c4bbdfSmrg if (pAdaptor->pAttributes) { 104035c4bbdfSmrg XvAttributePtr pAttribute = pAdaptor->pAttributes; 104105b261ecSmrg 104235c4bbdfSmrg for (i = 0; i < pAdaptor->nAttributes; i++, pAttribute++) 104335c4bbdfSmrg free(pAttribute->name); 104435c4bbdfSmrg free(pAdaptor->pAttributes); 104535c4bbdfSmrg pAdaptor->pAttributes = NULL; 104635c4bbdfSmrg } 104735c4bbdfSmrg 104835c4bbdfSmrg free(pAdaptor->pImages); 104935c4bbdfSmrg pAdaptor->pImages = NULL; 105035c4bbdfSmrg 105135c4bbdfSmrg free(pAdaptor->devPriv.ptr); 105235c4bbdfSmrg pAdaptor->devPriv.ptr = NULL; 105335c4bbdfSmrg} 105405b261ecSmrg 105535c4bbdfSmrgvoid 105635c4bbdfSmrgXvFillColorKey(DrawablePtr pDraw, CARD32 key, RegionPtr region) 105735c4bbdfSmrg{ 105835c4bbdfSmrg ScreenPtr pScreen = pDraw->pScreen; 105935c4bbdfSmrg ChangeGCVal pval[2]; 106035c4bbdfSmrg BoxPtr pbox = RegionRects(region); 106135c4bbdfSmrg int i, nbox = RegionNumRects(region); 106235c4bbdfSmrg xRectangle *rects; 106335c4bbdfSmrg GCPtr gc; 106435c4bbdfSmrg 106535c4bbdfSmrg gc = GetScratchGC(pDraw->depth, pScreen); 106635c4bbdfSmrg if (!gc) 106735c4bbdfSmrg return; 106835c4bbdfSmrg 106935c4bbdfSmrg pval[0].val = key; 107035c4bbdfSmrg pval[1].val = IncludeInferiors; 107135c4bbdfSmrg (void) ChangeGC(NullClient, gc, GCForeground | GCSubwindowMode, pval); 107235c4bbdfSmrg ValidateGC(pDraw, gc); 107335c4bbdfSmrg 107435c4bbdfSmrg rects = xallocarray(nbox, sizeof(xRectangle)); 107535c4bbdfSmrg if (rects) { 107635c4bbdfSmrg for (i = 0; i < nbox; i++, pbox++) { 107735c4bbdfSmrg rects[i].x = pbox->x1 - pDraw->x; 107835c4bbdfSmrg rects[i].y = pbox->y1 - pDraw->y; 107935c4bbdfSmrg rects[i].width = pbox->x2 - pbox->x1; 108035c4bbdfSmrg rects[i].height = pbox->y2 - pbox->y1; 108135c4bbdfSmrg } 108235c4bbdfSmrg 108335c4bbdfSmrg (*gc->ops->PolyFillRect) (pDraw, gc, nbox, rects); 108435c4bbdfSmrg 108535c4bbdfSmrg free(rects); 108635c4bbdfSmrg } 108735c4bbdfSmrg FreeScratchGC(gc); 108805b261ecSmrg} 1089