1706f2543Smrg/*********************************************************** 2706f2543SmrgCopyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, 3706f2543Smrgand the Massachusetts Institute of Technology, Cambridge, Massachusetts. 4706f2543Smrg 5706f2543Smrg All Rights Reserved 6706f2543Smrg 7706f2543SmrgPermission to use, copy, modify, and distribute this software and its 8706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 9706f2543Smrgprovided that the above copyright notice appear in all copies and that 10706f2543Smrgboth that copyright notice and this permission notice appear in 11706f2543Smrgsupporting documentation, and that the names of Digital or MIT not be 12706f2543Smrgused in advertising or publicity pertaining to distribution of the 13706f2543Smrgsoftware without specific, written prior permission. 14706f2543Smrg 15706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 16706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 17706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 18706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 19706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 20706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 21706f2543SmrgSOFTWARE. 22706f2543Smrg 23706f2543Smrg******************************************************************/ 24706f2543Smrg 25706f2543Smrg/* 26706f2543Smrg** File: 27706f2543Smrg** 28706f2543Smrg** xvmain.c --- Xv server extension main device independent module. 29706f2543Smrg** 30706f2543Smrg** Author: 31706f2543Smrg** 32706f2543Smrg** David Carver (Digital Workstation Engineering/Project Athena) 33706f2543Smrg** 34706f2543Smrg** Revisions: 35706f2543Smrg** 36706f2543Smrg** 04.09.91 Carver 37706f2543Smrg** - change: stop video always generates an event even when video 38706f2543Smrg** wasn't active 39706f2543Smrg** 40706f2543Smrg** 29.08.91 Carver 41706f2543Smrg** - change: unrealizing windows no longer preempts video 42706f2543Smrg** 43706f2543Smrg** 11.06.91 Carver 44706f2543Smrg** - changed SetPortControl to SetPortAttribute 45706f2543Smrg** - changed GetPortControl to GetPortAttribute 46706f2543Smrg** - changed QueryBestSize 47706f2543Smrg** 48706f2543Smrg** 28.05.91 Carver 49706f2543Smrg** - fixed Put and Get requests to not preempt operations to same drawable 50706f2543Smrg** 51706f2543Smrg** 15.05.91 Carver 52706f2543Smrg** - version 2.0 upgrade 53706f2543Smrg** 54706f2543Smrg** 19.03.91 Carver 55706f2543Smrg** - fixed Put and Get requests to honor grabbed ports. 56706f2543Smrg** - fixed Video requests to update di structure with new drawable, and 57706f2543Smrg** client after calling ddx. 58706f2543Smrg** 59706f2543Smrg** 24.01.91 Carver 60706f2543Smrg** - version 1.4 upgrade 61706f2543Smrg** 62706f2543Smrg** Notes: 63706f2543Smrg** 64706f2543Smrg** Port structures reference client structures in a two different 65706f2543Smrg** ways: when grabs, or video is active. Each reference is encoded 66706f2543Smrg** as fake client resources and thus when the client is goes away so 67706f2543Smrg** does the reference (it is zeroed). No other action is taken, so 68706f2543Smrg** video doesn't necessarily stop. It probably will as a result of 69706f2543Smrg** other resources going away, but if a client starts video using 70706f2543Smrg** none of its own resources, then the video will continue to play 71706f2543Smrg** after the client disappears. 72706f2543Smrg** 73706f2543Smrg** 74706f2543Smrg*/ 75706f2543Smrg 76706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 77706f2543Smrg#include <dix-config.h> 78706f2543Smrg#endif 79706f2543Smrg 80706f2543Smrg#include <string.h> 81706f2543Smrg 82706f2543Smrg#include <X11/X.h> 83706f2543Smrg#include <X11/Xproto.h> 84706f2543Smrg#include "misc.h" 85706f2543Smrg#include "os.h" 86706f2543Smrg#include "scrnintstr.h" 87706f2543Smrg#include "windowstr.h" 88706f2543Smrg#include "pixmapstr.h" 89706f2543Smrg#include "gc.h" 90706f2543Smrg#include "extnsionst.h" 91706f2543Smrg#include "dixstruct.h" 92706f2543Smrg#include "resource.h" 93706f2543Smrg#include "opaque.h" 94706f2543Smrg#include "input.h" 95706f2543Smrg 96706f2543Smrg#define GLOBAL 97706f2543Smrg 98706f2543Smrg#include <X11/extensions/Xv.h> 99706f2543Smrg#include <X11/extensions/Xvproto.h> 100706f2543Smrg#include "xvdix.h" 101706f2543Smrg 102706f2543Smrg#ifdef PANORAMIX 103706f2543Smrg#include "panoramiX.h" 104706f2543Smrg#include "panoramiXsrv.h" 105706f2543Smrg#endif 106706f2543Smrg#include "xvdisp.h" 107706f2543Smrg 108706f2543Smrgstatic DevPrivateKeyRec XvScreenKeyRec; 109706f2543Smrg#define XvScreenKey (&XvScreenKeyRec) 110706f2543Smrgunsigned long XvExtensionGeneration = 0; 111706f2543Smrgunsigned long XvScreenGeneration = 0; 112706f2543Smrgunsigned long XvResourceGeneration = 0; 113706f2543Smrg 114706f2543Smrgint XvReqCode; 115706f2543Smrgint XvEventBase; 116706f2543Smrgint XvErrorBase; 117706f2543Smrg 118706f2543Smrgunsigned long XvRTPort; 119706f2543Smrgunsigned long XvRTEncoding; 120706f2543Smrgunsigned long XvRTGrab; 121706f2543Smrgunsigned long XvRTVideoNotify; 122706f2543Smrgunsigned long XvRTVideoNotifyList; 123706f2543Smrgunsigned long XvRTPortNotify; 124706f2543Smrg 125706f2543Smrg 126706f2543Smrg 127706f2543Smrg/* EXTERNAL */ 128706f2543Smrg 129706f2543Smrgstatic void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); 130706f2543Smrgstatic void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); 131706f2543Smrgstatic Bool CreateResourceTypes(void); 132706f2543Smrg 133706f2543Smrgstatic Bool XvCloseScreen(int, ScreenPtr); 134706f2543Smrgstatic Bool XvDestroyPixmap(PixmapPtr); 135706f2543Smrgstatic Bool XvDestroyWindow(WindowPtr); 136706f2543Smrgstatic void XvResetProc(ExtensionEntry*); 137706f2543Smrgstatic int XvdiDestroyGrab(pointer, XID); 138706f2543Smrgstatic int XvdiDestroyEncoding(pointer, XID); 139706f2543Smrgstatic int XvdiDestroyVideoNotify(pointer, XID); 140706f2543Smrgstatic int XvdiDestroyPortNotify(pointer, XID); 141706f2543Smrgstatic int XvdiDestroyVideoNotifyList(pointer, XID); 142706f2543Smrgstatic int XvdiDestroyPort(pointer, XID); 143706f2543Smrgstatic int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int); 144706f2543Smrg 145706f2543Smrg 146706f2543Smrg 147706f2543Smrg 148706f2543Smrg/* 149706f2543Smrg** XvExtensionInit 150706f2543Smrg** 151706f2543Smrg** 152706f2543Smrg*/ 153706f2543Smrg 154706f2543Smrgvoid 155706f2543SmrgXvExtensionInit(void) 156706f2543Smrg{ 157706f2543Smrg ExtensionEntry *extEntry; 158706f2543Smrg 159706f2543Smrg if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) 160706f2543Smrg return; 161706f2543Smrg 162706f2543Smrg /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN 163706f2543Smrg INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */ 164706f2543Smrg if (XvScreenGeneration != serverGeneration) 165706f2543Smrg { 166706f2543Smrg if (!CreateResourceTypes()) 167706f2543Smrg { 168706f2543Smrg ErrorF("XvExtensionInit: Unable to allocate resource types\n"); 169706f2543Smrg return; 170706f2543Smrg } 171706f2543Smrg#ifdef PANORAMIX 172706f2543Smrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 173706f2543Smrg#endif 174706f2543Smrg XvScreenGeneration = serverGeneration; 175706f2543Smrg } 176706f2543Smrg 177706f2543Smrg if (XvExtensionGeneration != serverGeneration) 178706f2543Smrg { 179706f2543Smrg XvExtensionGeneration = serverGeneration; 180706f2543Smrg 181706f2543Smrg extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, 182706f2543Smrg ProcXvDispatch, SProcXvDispatch, 183706f2543Smrg XvResetProc, StandardMinorOpcode); 184706f2543Smrg if (!extEntry) 185706f2543Smrg { 186706f2543Smrg FatalError("XvExtensionInit: AddExtensions failed\n"); 187706f2543Smrg } 188706f2543Smrg 189706f2543Smrg XvReqCode = extEntry->base; 190706f2543Smrg XvEventBase = extEntry->eventBase; 191706f2543Smrg XvErrorBase = extEntry->errorBase; 192706f2543Smrg 193706f2543Smrg EventSwapVector[XvEventBase+XvVideoNotify] = 194706f2543Smrg (EventSwapPtr)WriteSwappedVideoNotifyEvent; 195706f2543Smrg EventSwapVector[XvEventBase+XvPortNotify] = 196706f2543Smrg (EventSwapPtr)WriteSwappedPortNotifyEvent; 197706f2543Smrg 198706f2543Smrg SetResourceTypeErrorValue(XvRTPort, _XvBadPort); 199706f2543Smrg (void)MakeAtom(XvName, strlen(XvName), xTrue); 200706f2543Smrg 201706f2543Smrg } 202706f2543Smrg} 203706f2543Smrg 204706f2543Smrgstatic Bool 205706f2543SmrgCreateResourceTypes(void) 206706f2543Smrg 207706f2543Smrg{ 208706f2543Smrg 209706f2543Smrg if (XvResourceGeneration == serverGeneration) return TRUE; 210706f2543Smrg 211706f2543Smrg XvResourceGeneration = serverGeneration; 212706f2543Smrg 213706f2543Smrg if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort, "XvRTPort"))) 214706f2543Smrg { 215706f2543Smrg ErrorF("CreateResourceTypes: failed to allocate port resource.\n"); 216706f2543Smrg return FALSE; 217706f2543Smrg } 218706f2543Smrg 219706f2543Smrg if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab, "XvRTGrab"))) 220706f2543Smrg { 221706f2543Smrg ErrorF("CreateResourceTypes: failed to allocate grab resource.\n"); 222706f2543Smrg return FALSE; 223706f2543Smrg } 224706f2543Smrg 225706f2543Smrg if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding, 226706f2543Smrg "XvRTEncoding"))) 227706f2543Smrg { 228706f2543Smrg ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n"); 229706f2543Smrg return FALSE; 230706f2543Smrg } 231706f2543Smrg 232706f2543Smrg if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify, 233706f2543Smrg "XvRTVideoNotify"))) 234706f2543Smrg { 235706f2543Smrg ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n"); 236706f2543Smrg return FALSE; 237706f2543Smrg } 238706f2543Smrg 239706f2543Smrg if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList, 240706f2543Smrg "XvRTVideoNotifyList"))) 241706f2543Smrg { 242706f2543Smrg ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n"); 243706f2543Smrg return FALSE; 244706f2543Smrg } 245706f2543Smrg 246706f2543Smrg if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify, 247706f2543Smrg "XvRTPortNotify"))) 248706f2543Smrg { 249706f2543Smrg ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n"); 250706f2543Smrg return FALSE; 251706f2543Smrg } 252706f2543Smrg 253706f2543Smrg return TRUE; 254706f2543Smrg 255706f2543Smrg} 256706f2543Smrg 257706f2543Smrgint 258706f2543SmrgXvScreenInit(ScreenPtr pScreen) 259706f2543Smrg{ 260706f2543Smrg XvScreenPtr pxvs; 261706f2543Smrg 262706f2543Smrg if (XvScreenGeneration != serverGeneration) 263706f2543Smrg { 264706f2543Smrg if (!CreateResourceTypes()) 265706f2543Smrg { 266706f2543Smrg ErrorF("XvScreenInit: Unable to allocate resource types\n"); 267706f2543Smrg return BadAlloc; 268706f2543Smrg } 269706f2543Smrg#ifdef PANORAMIX 270706f2543Smrg XineramaRegisterConnectionBlockCallback(XineramifyXv); 271706f2543Smrg#endif 272706f2543Smrg XvScreenGeneration = serverGeneration; 273706f2543Smrg } 274706f2543Smrg 275706f2543Smrg if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) 276706f2543Smrg return BadAlloc; 277706f2543Smrg 278706f2543Smrg if (dixLookupPrivate(&pScreen->devPrivates, XvScreenKey)) 279706f2543Smrg { 280706f2543Smrg ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n"); 281706f2543Smrg } 282706f2543Smrg 283706f2543Smrg /* ALLOCATE SCREEN PRIVATE RECORD */ 284706f2543Smrg 285706f2543Smrg pxvs = malloc(sizeof (XvScreenRec)); 286706f2543Smrg if (!pxvs) 287706f2543Smrg { 288706f2543Smrg ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); 289706f2543Smrg return BadAlloc; 290706f2543Smrg } 291706f2543Smrg 292706f2543Smrg dixSetPrivate(&pScreen->devPrivates, XvScreenKey, pxvs); 293706f2543Smrg 294706f2543Smrg pxvs->DestroyPixmap = pScreen->DestroyPixmap; 295706f2543Smrg pxvs->DestroyWindow = pScreen->DestroyWindow; 296706f2543Smrg pxvs->CloseScreen = pScreen->CloseScreen; 297706f2543Smrg 298706f2543Smrg pScreen->DestroyPixmap = XvDestroyPixmap; 299706f2543Smrg pScreen->DestroyWindow = XvDestroyWindow; 300706f2543Smrg pScreen->CloseScreen = XvCloseScreen; 301706f2543Smrg 302706f2543Smrg return Success; 303706f2543Smrg} 304706f2543Smrg 305706f2543Smrgstatic Bool 306706f2543SmrgXvCloseScreen( 307706f2543Smrg int ii, 308706f2543Smrg ScreenPtr pScreen 309706f2543Smrg){ 310706f2543Smrg 311706f2543Smrg XvScreenPtr pxvs; 312706f2543Smrg 313706f2543Smrg pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 314706f2543Smrg 315706f2543Smrg pScreen->DestroyPixmap = pxvs->DestroyPixmap; 316706f2543Smrg pScreen->DestroyWindow = pxvs->DestroyWindow; 317706f2543Smrg pScreen->CloseScreen = pxvs->CloseScreen; 318706f2543Smrg 319706f2543Smrg (* pxvs->ddCloseScreen)(ii, pScreen); 320706f2543Smrg 321706f2543Smrg free(pxvs); 322706f2543Smrg 323706f2543Smrg dixSetPrivate(&pScreen->devPrivates, XvScreenKey, NULL); 324706f2543Smrg 325706f2543Smrg return (*pScreen->CloseScreen)(ii, pScreen); 326706f2543Smrg} 327706f2543Smrg 328706f2543Smrgstatic void 329706f2543SmrgXvResetProc(ExtensionEntry* extEntry) 330706f2543Smrg{ 331706f2543Smrg XvResetProcVector(); 332706f2543Smrg} 333706f2543Smrg 334706f2543SmrgDevPrivateKey 335706f2543SmrgXvGetScreenKey(void) 336706f2543Smrg{ 337706f2543Smrg return XvScreenKey; 338706f2543Smrg} 339706f2543Smrg 340706f2543Smrgunsigned long 341706f2543SmrgXvGetRTPort(void) 342706f2543Smrg{ 343706f2543Smrg return XvRTPort; 344706f2543Smrg} 345706f2543Smrg 346706f2543Smrgstatic Bool 347706f2543SmrgXvDestroyPixmap(PixmapPtr pPix) 348706f2543Smrg{ 349706f2543Smrg Bool status; 350706f2543Smrg ScreenPtr pScreen; 351706f2543Smrg XvScreenPtr pxvs; 352706f2543Smrg XvAdaptorPtr pa; 353706f2543Smrg int na; 354706f2543Smrg XvPortPtr pp; 355706f2543Smrg int np; 356706f2543Smrg 357706f2543Smrg pScreen = pPix->drawable.pScreen; 358706f2543Smrg 359706f2543Smrg SCREEN_PROLOGUE(pScreen, DestroyPixmap); 360706f2543Smrg 361706f2543Smrg pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 362706f2543Smrg 363706f2543Smrg /* CHECK TO SEE IF THIS PORT IS IN USE */ 364706f2543Smrg 365706f2543Smrg pa = pxvs->pAdaptors; 366706f2543Smrg na = pxvs->nAdaptors; 367706f2543Smrg while (na--) 368706f2543Smrg { 369706f2543Smrg np = pa->nPorts; 370706f2543Smrg pp = pa->pPorts; 371706f2543Smrg 372706f2543Smrg while (np--) 373706f2543Smrg { 374706f2543Smrg if (pp->pDraw == (DrawablePtr)pPix) 375706f2543Smrg { 376706f2543Smrg XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); 377706f2543Smrg 378706f2543Smrg (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); 379706f2543Smrg 380706f2543Smrg pp->pDraw = NULL; 381706f2543Smrg pp->client = NULL; 382706f2543Smrg pp->time = currentTime; 383706f2543Smrg } 384706f2543Smrg pp++; 385706f2543Smrg } 386706f2543Smrg pa++; 387706f2543Smrg } 388706f2543Smrg 389706f2543Smrg status = (* pScreen->DestroyPixmap)(pPix); 390706f2543Smrg 391706f2543Smrg SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap); 392706f2543Smrg 393706f2543Smrg return status; 394706f2543Smrg 395706f2543Smrg} 396706f2543Smrg 397706f2543Smrgstatic Bool 398706f2543SmrgXvDestroyWindow(WindowPtr pWin) 399706f2543Smrg{ 400706f2543Smrg Bool status; 401706f2543Smrg ScreenPtr pScreen; 402706f2543Smrg XvScreenPtr pxvs; 403706f2543Smrg XvAdaptorPtr pa; 404706f2543Smrg int na; 405706f2543Smrg XvPortPtr pp; 406706f2543Smrg int np; 407706f2543Smrg 408706f2543Smrg pScreen = pWin->drawable.pScreen; 409706f2543Smrg 410706f2543Smrg SCREEN_PROLOGUE(pScreen, DestroyWindow); 411706f2543Smrg 412706f2543Smrg pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); 413706f2543Smrg 414706f2543Smrg /* CHECK TO SEE IF THIS PORT IS IN USE */ 415706f2543Smrg 416706f2543Smrg pa = pxvs->pAdaptors; 417706f2543Smrg na = pxvs->nAdaptors; 418706f2543Smrg while (na--) 419706f2543Smrg { 420706f2543Smrg np = pa->nPorts; 421706f2543Smrg pp = pa->pPorts; 422706f2543Smrg 423706f2543Smrg while (np--) 424706f2543Smrg { 425706f2543Smrg if (pp->pDraw == (DrawablePtr)pWin) 426706f2543Smrg { 427706f2543Smrg XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); 428706f2543Smrg 429706f2543Smrg (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); 430706f2543Smrg 431706f2543Smrg pp->pDraw = NULL; 432706f2543Smrg pp->client = NULL; 433706f2543Smrg pp->time = currentTime; 434706f2543Smrg } 435706f2543Smrg pp++; 436706f2543Smrg } 437706f2543Smrg pa++; 438706f2543Smrg } 439706f2543Smrg 440706f2543Smrg 441706f2543Smrg status = (* pScreen->DestroyWindow)(pWin); 442706f2543Smrg 443706f2543Smrg SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow); 444706f2543Smrg 445706f2543Smrg return status; 446706f2543Smrg 447706f2543Smrg} 448706f2543Smrg 449706f2543Smrg/* The XvdiVideoStopped procedure is a hook for the device dependent layer. 450706f2543Smrg It provides a way for the dd layer to inform the di layer that video has 451706f2543Smrg stopped in a port for reasons that the di layer had no control over; note 452706f2543Smrg that it doesn't call back into the dd layer */ 453706f2543Smrg 454706f2543Smrgint 455706f2543SmrgXvdiVideoStopped(XvPortPtr pPort, int reason) 456706f2543Smrg{ 457706f2543Smrg 458706f2543Smrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 459706f2543Smrg 460706f2543Smrg if (!pPort->pDraw) return Success; 461706f2543Smrg 462706f2543Smrg XvdiSendVideoNotify(pPort, pPort->pDraw, reason); 463706f2543Smrg 464706f2543Smrg pPort->pDraw = NULL; 465706f2543Smrg pPort->client = NULL; 466706f2543Smrg pPort->time = currentTime; 467706f2543Smrg 468706f2543Smrg return Success; 469706f2543Smrg 470706f2543Smrg} 471706f2543Smrg 472706f2543Smrgstatic int 473706f2543SmrgXvdiDestroyPort(pointer pPort, XID id) 474706f2543Smrg{ 475706f2543Smrg return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort); 476706f2543Smrg} 477706f2543Smrg 478706f2543Smrgstatic int 479706f2543SmrgXvdiDestroyGrab(pointer pGrab, XID id) 480706f2543Smrg{ 481706f2543Smrg ((XvGrabPtr)pGrab)->client = NULL; 482706f2543Smrg return Success; 483706f2543Smrg} 484706f2543Smrg 485706f2543Smrgstatic int 486706f2543SmrgXvdiDestroyVideoNotify(pointer pn, XID id) 487706f2543Smrg{ 488706f2543Smrg /* JUST CLEAR OUT THE client POINTER FIELD */ 489706f2543Smrg 490706f2543Smrg ((XvVideoNotifyPtr)pn)->client = NULL; 491706f2543Smrg return Success; 492706f2543Smrg} 493706f2543Smrg 494706f2543Smrgstatic int 495706f2543SmrgXvdiDestroyPortNotify(pointer pn, XID id) 496706f2543Smrg{ 497706f2543Smrg /* JUST CLEAR OUT THE client POINTER FIELD */ 498706f2543Smrg 499706f2543Smrg ((XvPortNotifyPtr)pn)->client = NULL; 500706f2543Smrg return Success; 501706f2543Smrg} 502706f2543Smrg 503706f2543Smrgstatic int 504706f2543SmrgXvdiDestroyVideoNotifyList(pointer pn, XID id) 505706f2543Smrg{ 506706f2543Smrg XvVideoNotifyPtr npn,cpn; 507706f2543Smrg 508706f2543Smrg /* ACTUALLY DESTROY THE NOTITY LIST */ 509706f2543Smrg 510706f2543Smrg cpn = (XvVideoNotifyPtr)pn; 511706f2543Smrg 512706f2543Smrg while (cpn) 513706f2543Smrg { 514706f2543Smrg npn = cpn->next; 515706f2543Smrg if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify); 516706f2543Smrg free(cpn); 517706f2543Smrg cpn = npn; 518706f2543Smrg } 519706f2543Smrg return Success; 520706f2543Smrg} 521706f2543Smrg 522706f2543Smrgstatic int 523706f2543SmrgXvdiDestroyEncoding(pointer value, XID id) 524706f2543Smrg{ 525706f2543Smrg return Success; 526706f2543Smrg} 527706f2543Smrg 528706f2543Smrgstatic int 529706f2543SmrgXvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason) 530706f2543Smrg{ 531706f2543Smrg xvEvent event; 532706f2543Smrg XvVideoNotifyPtr pn; 533706f2543Smrg 534706f2543Smrg dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, 535706f2543Smrg serverClient, DixReadAccess); 536706f2543Smrg 537706f2543Smrg while (pn) 538706f2543Smrg { 539706f2543Smrg event.u.u.type = XvEventBase + XvVideoNotify; 540706f2543Smrg event.u.videoNotify.time = currentTime.milliseconds; 541706f2543Smrg event.u.videoNotify.drawable = pDraw->id; 542706f2543Smrg event.u.videoNotify.port = pPort->id; 543706f2543Smrg event.u.videoNotify.reason = reason; 544706f2543Smrg WriteEventsToClient(pn->client, 1, (xEventPtr)&event); 545706f2543Smrg pn = pn->next; 546706f2543Smrg } 547706f2543Smrg 548706f2543Smrg return Success; 549706f2543Smrg 550706f2543Smrg} 551706f2543Smrg 552706f2543Smrg 553706f2543Smrgint 554706f2543SmrgXvdiSendPortNotify( 555706f2543Smrg XvPortPtr pPort, 556706f2543Smrg Atom attribute, 557706f2543Smrg INT32 value 558706f2543Smrg){ 559706f2543Smrg xvEvent event; 560706f2543Smrg XvPortNotifyPtr pn; 561706f2543Smrg 562706f2543Smrg pn = pPort->pNotify; 563706f2543Smrg 564706f2543Smrg while (pn) 565706f2543Smrg { 566706f2543Smrg event.u.u.type = XvEventBase + XvPortNotify; 567706f2543Smrg event.u.portNotify.time = currentTime.milliseconds; 568706f2543Smrg event.u.portNotify.port = pPort->id; 569706f2543Smrg event.u.portNotify.attribute = attribute; 570706f2543Smrg event.u.portNotify.value = value; 571706f2543Smrg WriteEventsToClient(pn->client, 1, (xEventPtr)&event); 572706f2543Smrg pn = pn->next; 573706f2543Smrg } 574706f2543Smrg 575706f2543Smrg return Success; 576706f2543Smrg 577706f2543Smrg} 578706f2543Smrg 579706f2543Smrg 580706f2543Smrg#define CHECK_SIZE(dw, dh, sw, sh) { \ 581706f2543Smrg if(!dw || !dh || !sw || !sh) return Success; \ 582706f2543Smrg /* The region code will break these if they are too large */ \ 583706f2543Smrg if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \ 584706f2543Smrg return BadValue; \ 585706f2543Smrg} 586706f2543Smrg 587706f2543Smrg 588706f2543Smrgint 589706f2543SmrgXvdiPutVideo( 590706f2543Smrg ClientPtr client, 591706f2543Smrg DrawablePtr pDraw, 592706f2543Smrg XvPortPtr pPort, 593706f2543Smrg GCPtr pGC, 594706f2543Smrg INT16 vid_x, INT16 vid_y, 595706f2543Smrg CARD16 vid_w, CARD16 vid_h, 596706f2543Smrg INT16 drw_x, INT16 drw_y, 597706f2543Smrg CARD16 drw_w, CARD16 drw_h 598706f2543Smrg){ 599706f2543Smrg DrawablePtr pOldDraw; 600706f2543Smrg 601706f2543Smrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 602706f2543Smrg 603706f2543Smrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 604706f2543Smrg 605706f2543Smrg UpdateCurrentTime(); 606706f2543Smrg 607706f2543Smrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 608706f2543Smrg INFORM CLIENT OF ITS FAILURE */ 609706f2543Smrg 610706f2543Smrg if (pPort->grab.client && (pPort->grab.client != client)) 611706f2543Smrg { 612706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 613706f2543Smrg return Success; 614706f2543Smrg } 615706f2543Smrg 616706f2543Smrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 617706f2543Smrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 618706f2543Smrg 619706f2543Smrg pOldDraw = pPort->pDraw; 620706f2543Smrg if ((pOldDraw) && (pOldDraw != pDraw)) 621706f2543Smrg { 622706f2543Smrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 623706f2543Smrg } 624706f2543Smrg 625706f2543Smrg (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC, 626706f2543Smrg vid_x, vid_y, vid_w, vid_h, 627706f2543Smrg drw_x, drw_y, drw_w, drw_h); 628706f2543Smrg 629706f2543Smrg if ((pPort->pDraw) && (pOldDraw != pDraw)) 630706f2543Smrg { 631706f2543Smrg pPort->client = client; 632706f2543Smrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 633706f2543Smrg } 634706f2543Smrg 635706f2543Smrg pPort->time = currentTime; 636706f2543Smrg 637706f2543Smrg return Success; 638706f2543Smrg 639706f2543Smrg} 640706f2543Smrg 641706f2543Smrgint 642706f2543SmrgXvdiPutStill( 643706f2543Smrg ClientPtr client, 644706f2543Smrg DrawablePtr pDraw, 645706f2543Smrg XvPortPtr pPort, 646706f2543Smrg GCPtr pGC, 647706f2543Smrg INT16 vid_x, INT16 vid_y, 648706f2543Smrg CARD16 vid_w, CARD16 vid_h, 649706f2543Smrg INT16 drw_x, INT16 drw_y, 650706f2543Smrg CARD16 drw_w, CARD16 drw_h 651706f2543Smrg){ 652706f2543Smrg int status; 653706f2543Smrg 654706f2543Smrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 655706f2543Smrg 656706f2543Smrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 657706f2543Smrg 658706f2543Smrg UpdateCurrentTime(); 659706f2543Smrg 660706f2543Smrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 661706f2543Smrg INFORM CLIENT OF ITS FAILURE */ 662706f2543Smrg 663706f2543Smrg if (pPort->grab.client && (pPort->grab.client != client)) 664706f2543Smrg { 665706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 666706f2543Smrg return Success; 667706f2543Smrg } 668706f2543Smrg 669706f2543Smrg pPort->time = currentTime; 670706f2543Smrg 671706f2543Smrg status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC, 672706f2543Smrg vid_x, vid_y, vid_w, vid_h, 673706f2543Smrg drw_x, drw_y, drw_w, drw_h); 674706f2543Smrg 675706f2543Smrg return status; 676706f2543Smrg 677706f2543Smrg} 678706f2543Smrg 679706f2543Smrgint 680706f2543SmrgXvdiPutImage( 681706f2543Smrg ClientPtr client, 682706f2543Smrg DrawablePtr pDraw, 683706f2543Smrg XvPortPtr pPort, 684706f2543Smrg GCPtr pGC, 685706f2543Smrg INT16 src_x, INT16 src_y, 686706f2543Smrg CARD16 src_w, CARD16 src_h, 687706f2543Smrg INT16 drw_x, INT16 drw_y, 688706f2543Smrg CARD16 drw_w, CARD16 drw_h, 689706f2543Smrg XvImagePtr image, 690706f2543Smrg unsigned char* data, 691706f2543Smrg Bool sync, 692706f2543Smrg CARD16 width, CARD16 height 693706f2543Smrg){ 694706f2543Smrg CHECK_SIZE(drw_w, drw_h, src_w, src_h); 695706f2543Smrg 696706f2543Smrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 697706f2543Smrg 698706f2543Smrg UpdateCurrentTime(); 699706f2543Smrg 700706f2543Smrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 701706f2543Smrg INFORM CLIENT OF ITS FAILURE */ 702706f2543Smrg 703706f2543Smrg if (pPort->grab.client && (pPort->grab.client != client)) 704706f2543Smrg { 705706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 706706f2543Smrg return Success; 707706f2543Smrg } 708706f2543Smrg 709706f2543Smrg pPort->time = currentTime; 710706f2543Smrg 711706f2543Smrg return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC, 712706f2543Smrg src_x, src_y, src_w, src_h, 713706f2543Smrg drw_x, drw_y, drw_w, drw_h, 714706f2543Smrg image, data, sync, width, height); 715706f2543Smrg} 716706f2543Smrg 717706f2543Smrg 718706f2543Smrgint 719706f2543SmrgXvdiGetVideo( 720706f2543Smrg ClientPtr client, 721706f2543Smrg DrawablePtr pDraw, 722706f2543Smrg XvPortPtr pPort, 723706f2543Smrg GCPtr pGC, 724706f2543Smrg INT16 vid_x, INT16 vid_y, 725706f2543Smrg CARD16 vid_w, CARD16 vid_h, 726706f2543Smrg INT16 drw_x, INT16 drw_y, 727706f2543Smrg CARD16 drw_w, CARD16 drw_h 728706f2543Smrg){ 729706f2543Smrg DrawablePtr pOldDraw; 730706f2543Smrg 731706f2543Smrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 732706f2543Smrg 733706f2543Smrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 734706f2543Smrg 735706f2543Smrg UpdateCurrentTime(); 736706f2543Smrg 737706f2543Smrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 738706f2543Smrg INFORM CLIENT OF ITS FAILURE */ 739706f2543Smrg 740706f2543Smrg if (pPort->grab.client && (pPort->grab.client != client)) 741706f2543Smrg { 742706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 743706f2543Smrg return Success; 744706f2543Smrg } 745706f2543Smrg 746706f2543Smrg /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED 747706f2543Smrg EVENTS TO ANY CLIENTS WHO WANT THEM */ 748706f2543Smrg 749706f2543Smrg pOldDraw = pPort->pDraw; 750706f2543Smrg if ((pOldDraw) && (pOldDraw != pDraw)) 751706f2543Smrg { 752706f2543Smrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 753706f2543Smrg } 754706f2543Smrg 755706f2543Smrg (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC, 756706f2543Smrg vid_x, vid_y, vid_w, vid_h, 757706f2543Smrg drw_x, drw_y, drw_w, drw_h); 758706f2543Smrg 759706f2543Smrg if ((pPort->pDraw) && (pOldDraw != pDraw)) 760706f2543Smrg { 761706f2543Smrg pPort->client = client; 762706f2543Smrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); 763706f2543Smrg } 764706f2543Smrg 765706f2543Smrg pPort->time = currentTime; 766706f2543Smrg 767706f2543Smrg return Success; 768706f2543Smrg 769706f2543Smrg} 770706f2543Smrg 771706f2543Smrgint 772706f2543SmrgXvdiGetStill( 773706f2543Smrg ClientPtr client, 774706f2543Smrg DrawablePtr pDraw, 775706f2543Smrg XvPortPtr pPort, 776706f2543Smrg GCPtr pGC, 777706f2543Smrg INT16 vid_x, INT16 vid_y, 778706f2543Smrg CARD16 vid_w, CARD16 vid_h, 779706f2543Smrg INT16 drw_x, INT16 drw_y, 780706f2543Smrg CARD16 drw_w, CARD16 drw_h 781706f2543Smrg){ 782706f2543Smrg int status; 783706f2543Smrg 784706f2543Smrg CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); 785706f2543Smrg 786706f2543Smrg /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ 787706f2543Smrg 788706f2543Smrg UpdateCurrentTime(); 789706f2543Smrg 790706f2543Smrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 791706f2543Smrg INFORM CLIENT OF ITS FAILURE */ 792706f2543Smrg 793706f2543Smrg if (pPort->grab.client && (pPort->grab.client != client)) 794706f2543Smrg { 795706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 796706f2543Smrg return Success; 797706f2543Smrg } 798706f2543Smrg 799706f2543Smrg status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC, 800706f2543Smrg vid_x, vid_y, vid_w, vid_h, 801706f2543Smrg drw_x, drw_y, drw_w, drw_h); 802706f2543Smrg 803706f2543Smrg pPort->time = currentTime; 804706f2543Smrg 805706f2543Smrg return status; 806706f2543Smrg 807706f2543Smrg} 808706f2543Smrg 809706f2543Smrgint 810706f2543SmrgXvdiGrabPort( 811706f2543Smrg ClientPtr client, 812706f2543Smrg XvPortPtr pPort, 813706f2543Smrg Time ctime, 814706f2543Smrg int *p_result 815706f2543Smrg){ 816706f2543Smrg unsigned long id; 817706f2543Smrg TimeStamp time; 818706f2543Smrg 819706f2543Smrg UpdateCurrentTime(); 820706f2543Smrg time = ClientTimeToServerTime(ctime); 821706f2543Smrg 822706f2543Smrg if (pPort->grab.client && (client != pPort->grab.client)) 823706f2543Smrg { 824706f2543Smrg *p_result = XvAlreadyGrabbed; 825706f2543Smrg return Success; 826706f2543Smrg } 827706f2543Smrg 828706f2543Smrg if ((CompareTimeStamps(time, currentTime) == LATER) || 829706f2543Smrg (CompareTimeStamps(time, pPort->time) == EARLIER)) 830706f2543Smrg { 831706f2543Smrg *p_result = XvInvalidTime; 832706f2543Smrg return Success; 833706f2543Smrg } 834706f2543Smrg 835706f2543Smrg if (client == pPort->grab.client) 836706f2543Smrg { 837706f2543Smrg *p_result = Success; 838706f2543Smrg return Success; 839706f2543Smrg } 840706f2543Smrg 841706f2543Smrg id = FakeClientID(client->index); 842706f2543Smrg 843706f2543Smrg if (!AddResource(id, XvRTGrab, &pPort->grab)) 844706f2543Smrg { 845706f2543Smrg return BadAlloc; 846706f2543Smrg } 847706f2543Smrg 848706f2543Smrg /* IF THERE IS ACTIVE VIDEO THEN STOP IT */ 849706f2543Smrg 850706f2543Smrg if ((pPort->pDraw) && (client != pPort->client)) 851706f2543Smrg { 852706f2543Smrg XvdiStopVideo(NULL, pPort, pPort->pDraw); 853706f2543Smrg } 854706f2543Smrg 855706f2543Smrg pPort->grab.client = client; 856706f2543Smrg pPort->grab.id = id; 857706f2543Smrg 858706f2543Smrg pPort->time = currentTime; 859706f2543Smrg 860706f2543Smrg *p_result = Success; 861706f2543Smrg 862706f2543Smrg return Success; 863706f2543Smrg 864706f2543Smrg} 865706f2543Smrg 866706f2543Smrgint 867706f2543SmrgXvdiUngrabPort( 868706f2543Smrg ClientPtr client, 869706f2543Smrg XvPortPtr pPort, 870706f2543Smrg Time ctime 871706f2543Smrg){ 872706f2543Smrg TimeStamp time; 873706f2543Smrg 874706f2543Smrg UpdateCurrentTime(); 875706f2543Smrg time = ClientTimeToServerTime(ctime); 876706f2543Smrg 877706f2543Smrg if ((!pPort->grab.client) || (client != pPort->grab.client)) 878706f2543Smrg { 879706f2543Smrg return Success; 880706f2543Smrg } 881706f2543Smrg 882706f2543Smrg if ((CompareTimeStamps(time, currentTime) == LATER) || 883706f2543Smrg (CompareTimeStamps(time, pPort->time) == EARLIER)) 884706f2543Smrg { 885706f2543Smrg return Success; 886706f2543Smrg } 887706f2543Smrg 888706f2543Smrg /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */ 889706f2543Smrg 890706f2543Smrg FreeResource(pPort->grab.id, XvRTGrab); 891706f2543Smrg pPort->grab.client = NULL; 892706f2543Smrg 893706f2543Smrg pPort->time = currentTime; 894706f2543Smrg 895706f2543Smrg return Success; 896706f2543Smrg 897706f2543Smrg} 898706f2543Smrg 899706f2543Smrg 900706f2543Smrgint 901706f2543SmrgXvdiSelectVideoNotify( 902706f2543Smrg ClientPtr client, 903706f2543Smrg DrawablePtr pDraw, 904706f2543Smrg BOOL onoff 905706f2543Smrg){ 906706f2543Smrg XvVideoNotifyPtr pn,tpn,fpn; 907706f2543Smrg int rc; 908706f2543Smrg 909706f2543Smrg /* FIND VideoNotify LIST */ 910706f2543Smrg 911706f2543Smrg rc = dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, 912706f2543Smrg client, DixWriteAccess); 913706f2543Smrg if (rc != Success && rc != BadValue) 914706f2543Smrg return rc; 915706f2543Smrg 916706f2543Smrg /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */ 917706f2543Smrg 918706f2543Smrg if (!onoff && !pn) return Success; 919706f2543Smrg 920706f2543Smrg /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST 921706f2543Smrg WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */ 922706f2543Smrg 923706f2543Smrg if (!pn) 924706f2543Smrg { 925706f2543Smrg if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) 926706f2543Smrg return BadAlloc; 927706f2543Smrg tpn->next = NULL; 928706f2543Smrg if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) 929706f2543Smrg { 930706f2543Smrg free(tpn); 931706f2543Smrg return BadAlloc; 932706f2543Smrg } 933706f2543Smrg } 934706f2543Smrg else 935706f2543Smrg { 936706f2543Smrg /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ 937706f2543Smrg 938706f2543Smrg fpn = NULL; 939706f2543Smrg tpn = pn; 940706f2543Smrg while (tpn) 941706f2543Smrg { 942706f2543Smrg if (tpn->client == client) 943706f2543Smrg { 944706f2543Smrg if (!onoff) tpn->client = NULL; 945706f2543Smrg return Success; 946706f2543Smrg } 947706f2543Smrg if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */ 948706f2543Smrg tpn = tpn->next; 949706f2543Smrg } 950706f2543Smrg 951706f2543Smrg /* IF TUNNING OFF, THEN JUST RETURN */ 952706f2543Smrg 953706f2543Smrg if (!onoff) return Success; 954706f2543Smrg 955706f2543Smrg /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */ 956706f2543Smrg 957706f2543Smrg if (fpn) 958706f2543Smrg { 959706f2543Smrg tpn = fpn; 960706f2543Smrg } 961706f2543Smrg else 962706f2543Smrg { 963706f2543Smrg if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) 964706f2543Smrg return BadAlloc; 965706f2543Smrg tpn->next = pn->next; 966706f2543Smrg pn->next = tpn; 967706f2543Smrg } 968706f2543Smrg } 969706f2543Smrg 970706f2543Smrg /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */ 971706f2543Smrg /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */ 972706f2543Smrg 973706f2543Smrg tpn->client = NULL; 974706f2543Smrg tpn->id = FakeClientID(client->index); 975706f2543Smrg AddResource(tpn->id, XvRTVideoNotify, tpn); 976706f2543Smrg 977706f2543Smrg tpn->client = client; 978706f2543Smrg return Success; 979706f2543Smrg 980706f2543Smrg} 981706f2543Smrg 982706f2543Smrgint 983706f2543SmrgXvdiSelectPortNotify( 984706f2543Smrg ClientPtr client, 985706f2543Smrg XvPortPtr pPort, 986706f2543Smrg BOOL onoff 987706f2543Smrg){ 988706f2543Smrg XvPortNotifyPtr pn,tpn; 989706f2543Smrg 990706f2543Smrg /* SEE IF CLIENT IS ALREADY IN LIST */ 991706f2543Smrg 992706f2543Smrg tpn = NULL; 993706f2543Smrg pn = pPort->pNotify; 994706f2543Smrg while (pn) 995706f2543Smrg { 996706f2543Smrg if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */ 997706f2543Smrg if (pn->client == client) break; 998706f2543Smrg pn = pn->next; 999706f2543Smrg } 1000706f2543Smrg 1001706f2543Smrg /* IS THE CLIENT ALREADY ON THE LIST? */ 1002706f2543Smrg 1003706f2543Smrg if (pn) 1004706f2543Smrg { 1005706f2543Smrg /* REMOVE IT? */ 1006706f2543Smrg 1007706f2543Smrg if (!onoff) 1008706f2543Smrg { 1009706f2543Smrg pn->client = NULL; 1010706f2543Smrg FreeResource(pn->id, XvRTPortNotify); 1011706f2543Smrg } 1012706f2543Smrg 1013706f2543Smrg return Success; 1014706f2543Smrg } 1015706f2543Smrg 1016706f2543Smrg /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE 1017706f2543Smrg CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */ 1018706f2543Smrg 1019706f2543Smrg if (!tpn) 1020706f2543Smrg { 1021706f2543Smrg if (!(tpn = malloc(sizeof(XvPortNotifyRec)))) 1022706f2543Smrg return BadAlloc; 1023706f2543Smrg tpn->next = pPort->pNotify; 1024706f2543Smrg pPort->pNotify = tpn; 1025706f2543Smrg } 1026706f2543Smrg 1027706f2543Smrg tpn->client = client; 1028706f2543Smrg tpn->id = FakeClientID(client->index); 1029706f2543Smrg AddResource(tpn->id, XvRTPortNotify, tpn); 1030706f2543Smrg 1031706f2543Smrg return Success; 1032706f2543Smrg 1033706f2543Smrg} 1034706f2543Smrg 1035706f2543Smrgint 1036706f2543SmrgXvdiStopVideo( 1037706f2543Smrg ClientPtr client, 1038706f2543Smrg XvPortPtr pPort, 1039706f2543Smrg DrawablePtr pDraw 1040706f2543Smrg){ 1041706f2543Smrg int status; 1042706f2543Smrg 1043706f2543Smrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 1044706f2543Smrg 1045706f2543Smrg if (!pPort->pDraw || (pPort->pDraw != pDraw)) 1046706f2543Smrg { 1047706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 1048706f2543Smrg return Success; 1049706f2543Smrg } 1050706f2543Smrg 1051706f2543Smrg /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN 1052706f2543Smrg INFORM CLIENT OF ITS FAILURE */ 1053706f2543Smrg 1054706f2543Smrg if ((client) && (pPort->grab.client) && (pPort->grab.client != client)) 1055706f2543Smrg { 1056706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvBusy); 1057706f2543Smrg return Success; 1058706f2543Smrg } 1059706f2543Smrg 1060706f2543Smrg XvdiSendVideoNotify(pPort, pDraw, XvStopped); 1061706f2543Smrg 1062706f2543Smrg status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw); 1063706f2543Smrg 1064706f2543Smrg pPort->pDraw = NULL; 1065706f2543Smrg pPort->client = (ClientPtr)client; 1066706f2543Smrg pPort->time = currentTime; 1067706f2543Smrg 1068706f2543Smrg return status; 1069706f2543Smrg 1070706f2543Smrg} 1071706f2543Smrg 1072706f2543Smrgint 1073706f2543SmrgXvdiPreemptVideo( 1074706f2543Smrg ClientPtr client, 1075706f2543Smrg XvPortPtr pPort, 1076706f2543Smrg DrawablePtr pDraw 1077706f2543Smrg){ 1078706f2543Smrg int status; 1079706f2543Smrg 1080706f2543Smrg /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ 1081706f2543Smrg 1082706f2543Smrg if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success; 1083706f2543Smrg 1084706f2543Smrg XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); 1085706f2543Smrg 1086706f2543Smrg status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw); 1087706f2543Smrg 1088706f2543Smrg pPort->pDraw = NULL; 1089706f2543Smrg pPort->client = (ClientPtr)client; 1090706f2543Smrg pPort->time = currentTime; 1091706f2543Smrg 1092706f2543Smrg return status; 1093706f2543Smrg 1094706f2543Smrg} 1095706f2543Smrg 1096706f2543Smrgint 1097706f2543SmrgXvdiMatchPort( 1098706f2543Smrg XvPortPtr pPort, 1099706f2543Smrg DrawablePtr pDraw 1100706f2543Smrg){ 1101706f2543Smrg 1102706f2543Smrg XvAdaptorPtr pa; 1103706f2543Smrg XvFormatPtr pf; 1104706f2543Smrg int nf; 1105706f2543Smrg 1106706f2543Smrg pa = pPort->pAdaptor; 1107706f2543Smrg 1108706f2543Smrg if (pa->pScreen != pDraw->pScreen) return BadMatch; 1109706f2543Smrg 1110706f2543Smrg nf = pa->nFormats; 1111706f2543Smrg pf = pa->pFormats; 1112706f2543Smrg 1113706f2543Smrg while (nf--) 1114706f2543Smrg { 1115706f2543Smrg if ((pf->depth == pDraw->depth) 1116706f2543Smrg#if 0 1117706f2543Smrg && ((pDraw->type == DRAWABLE_PIXMAP) || 1118706f2543Smrg (wVisual(((WindowPtr)pDraw)) == pf->visual)) 1119706f2543Smrg#endif 1120706f2543Smrg ) 1121706f2543Smrg return Success; 1122706f2543Smrg pf++; 1123706f2543Smrg } 1124706f2543Smrg 1125706f2543Smrg return BadMatch; 1126706f2543Smrg 1127706f2543Smrg} 1128706f2543Smrg 1129706f2543Smrgint 1130706f2543SmrgXvdiSetPortAttribute( 1131706f2543Smrg ClientPtr client, 1132706f2543Smrg XvPortPtr pPort, 1133706f2543Smrg Atom attribute, 1134706f2543Smrg INT32 value 1135706f2543Smrg){ 1136706f2543Smrg int status; 1137706f2543Smrg 1138706f2543Smrg status = (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value); 1139706f2543Smrg if (status == Success) 1140706f2543Smrg XvdiSendPortNotify(pPort, attribute, value); 1141706f2543Smrg 1142706f2543Smrg return status; 1143706f2543Smrg} 1144706f2543Smrg 1145706f2543Smrgint 1146706f2543SmrgXvdiGetPortAttribute( 1147706f2543Smrg ClientPtr client, 1148706f2543Smrg XvPortPtr pPort, 1149706f2543Smrg Atom attribute, 1150706f2543Smrg INT32 *p_value 1151706f2543Smrg){ 1152706f2543Smrg 1153706f2543Smrg return 1154706f2543Smrg (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value); 1155706f2543Smrg 1156706f2543Smrg} 1157706f2543Smrg 1158706f2543Smrgstatic void 1159706f2543SmrgWriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to) 1160706f2543Smrg 1161706f2543Smrg{ 1162706f2543Smrg 1163706f2543Smrg to->u.u.type = from->u.u.type; 1164706f2543Smrg to->u.u.detail = from->u.u.detail; 1165706f2543Smrg cpswaps(from->u.videoNotify.sequenceNumber, 1166706f2543Smrg to->u.videoNotify.sequenceNumber); 1167706f2543Smrg cpswapl(from->u.videoNotify.time, to->u.videoNotify.time); 1168706f2543Smrg cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable); 1169706f2543Smrg cpswapl(from->u.videoNotify.port, to->u.videoNotify.port); 1170706f2543Smrg 1171706f2543Smrg} 1172706f2543Smrg 1173706f2543Smrgstatic void 1174706f2543SmrgWriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to) 1175706f2543Smrg 1176706f2543Smrg{ 1177706f2543Smrg 1178706f2543Smrg to->u.u.type = from->u.u.type; 1179706f2543Smrg to->u.u.detail = from->u.u.detail; 1180706f2543Smrg cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber); 1181706f2543Smrg cpswapl(from->u.portNotify.time, to->u.portNotify.time); 1182706f2543Smrg cpswapl(from->u.portNotify.port, to->u.portNotify.port); 1183706f2543Smrg cpswapl(from->u.portNotify.value, to->u.portNotify.value); 1184706f2543Smrg 1185706f2543Smrg} 1186