(file) Return to xvmain.c CVS log (file) (dir) Up to [XFree86 CVS] / xc / programs / Xserver / Xext

   1 dawes 1.2 /***********************************************************
   2           Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
   3           and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
   4           
   5                                   All Rights Reserved
   6           
   7           Permission to use, copy, modify, and distribute this software and its 
   8           documentation for any purpose and without fee is hereby granted, 
   9           provided that the above copyright notice appear in all copies and that
  10           both that copyright notice and this permission notice appear in 
  11           supporting documentation, and that the names of Digital or MIT not be
  12           used in advertising or publicity pertaining to distribution of the
  13           software without specific, written prior permission.  
  14           
  15           DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16           ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17           DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18           ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19           WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20           ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21           SOFTWARE.
  22 dawes 1.2 
  23           ******************************************************************/
  24 tsi   1.8 /* $XFree86: xc/programs/Xserver/Xext/xvmain.c,v 1.7 1999/12/11 19:26:32 mvojkovi Exp $ */
  25 dawes 1.2 
  26           /*
  27           ** File: 
  28           **
  29           **   xvmain.c --- Xv server extension main device independent module.
  30           **   
  31           ** Author: 
  32           **
  33           **   David Carver (Digital Workstation Engineering/Project Athena)
  34           **
  35           ** Revisions:
  36           **
  37           **   04.09.91 Carver
  38           **     - change: stop video always generates an event even when video
  39           **       wasn't active
  40           **
  41           **   29.08.91 Carver
  42           **     - change: unrealizing windows no longer preempts video
  43           **
  44           **   11.06.91 Carver
  45           **     - changed SetPortControl to SetPortAttribute
  46 dawes 1.2 **     - changed GetPortControl to GetPortAttribute
  47           **     - changed QueryBestSize
  48           **
  49           **   28.05.91 Carver
  50           **     - fixed Put and Get requests to not preempt operations to same drawable
  51           **
  52           **   15.05.91 Carver
  53           **     - version 2.0 upgrade
  54           **
  55           **   19.03.91 Carver
  56           **     - fixed Put and Get requests to honor grabbed ports.
  57           **     - fixed Video requests to update di structure with new drawable, and
  58           **       client after calling ddx.
  59           **
  60           **   24.01.91 Carver
  61           **     - version 1.4 upgrade
  62           **       
  63           ** Notes:
  64           **
  65           **   Port structures reference client structures in a two different
  66           **   ways: when grabs, or video is active.  Each reference is encoded
  67 dawes 1.2 **   as fake client resources and thus when the client is goes away so
  68           **   does the reference (it is zeroed).  No other action is taken, so
  69           **   video doesn't necessarily stop.  It probably will as a result of
  70           **   other resources going away, but if a client starts video using
  71           **   none of its own resources, then the video will continue to play
  72           **   after the client disappears.
  73           **
  74           **
  75           */
  76           
  77           #include "X.h"
  78           #include "Xproto.h"
  79           #include "misc.h"
  80           #include "os.h"
  81           #include "scrnintstr.h"
  82           #include "windowstr.h"
  83           #include "pixmapstr.h"
  84           #include "gc.h"
  85           #include "extnsionst.h"
  86           #include "dixstruct.h"
  87           #include "resource.h"
  88 dawes 1.2 #include "opaque.h"
  89           #include "input.h"
  90           
  91           #define GLOBAL
  92           
  93           #include "Xv.h"
  94           #include "Xvproto.h"
  95           #include "xvdix.h"
  96 dawes 1.4 
  97           #ifdef EXTMODULE
  98           #include "xf86_ansic.h"
  99           #endif
 100 dawes 1.2 
 101 dawes 1.3 int  XvScreenIndex = -1;
 102           unsigned long XvExtensionGeneration;
 103           unsigned long XvScreenGeneration;
 104           unsigned long XvResourceGeneration;
 105           
 106           int XvReqCode;
 107           int XvEventBase;
 108           int XvErrorBase;
 109           
 110           unsigned long XvRTPort;
 111           unsigned long XvRTEncoding;
 112           unsigned long XvRTGrab;
 113           unsigned long XvRTVideoNotify;
 114           unsigned long XvRTVideoNotifyList;
 115           unsigned long XvRTPortNotify;
 116           
 117           
 118           
 119 dawes 1.2 /* EXTERNAL */
 120           
 121           extern WindowPtr *WindowTable;
 122           extern XID clientErrorValue;
 123           
 124           static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *);
 125           static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *);
 126           static Bool CreateResourceTypes(void);
 127           
 128           static int lastScreenWithAdaptors = 0;
 129           
 130           static Bool XvCloseScreen(int, ScreenPtr);
 131           static Bool XvDestroyPixmap(PixmapPtr);
 132           static Bool XvDestroyWindow(WindowPtr);
 133           static void XvResetProc(ExtensionEntry*);
 134           static int XvdiDestroyGrab(pointer, XID);
 135           static int XvdiDestroyEncoding(pointer, XID);
 136           static int XvdiDestroyVideoNotify(pointer, XID);
 137           static int XvdiDestroyPortNotify(pointer, XID);
 138           static int XvdiDestroyVideoNotifyList(pointer, XID);
 139           static int XvdiDestroyPort(pointer, XID);
 140 dawes 1.3 static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int);
 141           
 142           
 143           
 144 dawes 1.2 
 145           /*
 146           ** XvExtensionInit
 147           **
 148           **
 149           */
 150           
 151           void 
 152           XvExtensionInit()
 153           {
 154             int ii;
 155             register ExtensionEntry *extEntry;
 156           
 157             /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN
 158                INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */
 159           
 160             if (XvScreenGeneration != serverGeneration)
 161               {
 162                 if (!CreateResourceTypes())
 163           	{
 164           	  ErrorF("XvExtensionInit: Unable to allocate resource types\n");
 165 dawes 1.2 	  return;
 166           	}
 167                 XvScreenIndex = AllocateScreenPrivateIndex ();
 168                 if (XvScreenIndex < 0)
 169           	{
 170           	  ErrorF("XvExtensionInit: Unable to allocate screen private index\n");
 171           	  return;
 172           	}
 173           
 174                 XvScreenGeneration = serverGeneration;
 175               }
 176           
 177             /* ITS A LITTLE HARD TO UNDERSTAND WHAT THIS DOES, BUT ESSENTIALLY I WANT 
 178                ALL SCREEN THAT HAVE ADAPTORS TO HAVE A VALID DEVPRIVATE POINTER AND ANY 
 179                THAT DON'T TO HAVE NULL DEVPRIVATE POINTERS; THIS WAY I DON'T HAVE TO 
 180                CALL A SPECIAL XV SCREEN INITIALIZE FOR SCREENS WITHOUT ADAPTORS; THERE
 181                SHOULD BE AN EASIER WAY TO DO THIS, BUT main.c DOESN'T INITIALIZE THE 
 182                DEVPRIVATE POINTERS FOR A NEWLY CREATED SCREEN, NOR ARE THEY INITIALIZED
 183                WHEN A NEW SCREEN PRIVATE INDEX IS ALLOCATED */
 184           
 185             for (ii=lastScreenWithAdaptors; ii<screenInfo.numScreens; ii++)
 186 dawes 1.2     screenInfo.screens[ii]->devPrivates[XvScreenIndex].ptr = (pointer)NULL;
 187             lastScreenWithAdaptors = screenInfo.numScreens;
 188           
 189             if (XvExtensionGeneration != serverGeneration)
 190               {
 191                 XvExtensionGeneration = serverGeneration;
 192           
 193                 extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, 
 194           			      ProcXvDispatch, SProcXvDispatch,
 195           			      XvResetProc, StandardMinorOpcode);
 196                 if (!extEntry) 
 197           	{
 198           	  FatalError("XvExtensionInit: AddExtensions failed\n");
 199           	}
 200           
 201                 XvReqCode = extEntry->base;
 202                 XvEventBase = extEntry->eventBase;
 203                 XvErrorBase = extEntry->errorBase;
 204           
 205                 EventSwapVector[XvEventBase+XvVideoNotify] = 
 206           	WriteSwappedVideoNotifyEvent;
 207 dawes 1.2       EventSwapVector[XvEventBase+XvPortNotify] = 
 208           	WriteSwappedPortNotifyEvent;
 209           
 210                 (void)MakeAtom(XvName, strlen(XvName), xTrue);
 211           
 212               }
 213           }
 214           
 215           static Bool
 216           CreateResourceTypes()
 217           
 218           {
 219             
 220             if (XvResourceGeneration == serverGeneration) return TRUE;
 221           
 222             XvResourceGeneration = serverGeneration;
 223           
 224             if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort)))
 225               {
 226                 ErrorF("CreateResourceTypes: failed to allocate port resource.\n");
 227                 return FALSE;
 228 dawes 1.2     }
 229             
 230             if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab)))
 231               {
 232                 ErrorF("CreateResourceTypes: failed to allocate grab resource.\n");
 233                 return FALSE;
 234               }
 235             
 236             if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding)))
 237               {
 238                 ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n");
 239                 return FALSE;
 240               }
 241             
 242             if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify)))
 243               {
 244                 ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n");
 245                 return FALSE;
 246               }
 247             
 248             if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList)))
 249 dawes 1.2     {
 250                 ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n");
 251                 return FALSE;
 252               }
 253           
 254             if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify)))
 255               {
 256                 ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n");
 257                 return FALSE;
 258               }
 259           
 260             return TRUE;
 261           
 262           }
 263           
 264           int
 265           XvScreenInit(ScreenPtr pScreen)
 266           {
 267           
 268             int ii;
 269             XvScreenPtr pxvs;
 270 dawes 1.2 
 271             if (XvScreenGeneration != serverGeneration)
 272               {
 273                 if (!CreateResourceTypes())
 274           	{
 275           	  ErrorF("XvScreenInit: Unable to allocate resource types\n");
 276           	  return BadAlloc;
 277           	}
 278                 XvScreenIndex = AllocateScreenPrivateIndex ();
 279                 if (XvScreenIndex < 0)
 280           	{
 281           	  ErrorF("XvScreenInit: Unable to allocate screen private index\n");
 282           	  return BadAlloc;
 283           	}
 284                 XvScreenGeneration = serverGeneration; 
 285               }
 286           
 287             /* ITS A LITTLE HARD TO UNDERSTAND WHAT THIS DOES, BUT ESSENTIALLY I WANT 
 288                ALL SCREEN THAT HAVE ADAPTORS TO HAVE A VALID DEVPRIVATE POINTER AND ANY 
 289                THAT DON'T TO HAVE NULL DEVPRIVATE POINTERS; THIS WAY I DON'T HAVE TO 
 290                CALL A SPECIAL XV SCREEN INITIALIZE FOR SCREENS WITHOUT ADAPTORS; THERE
 291 dawes 1.2      SHOULD BE AN EASIER WAY TO DO THIS, BUT main.c DOESN'T INITIALIZE THE 
 292                DEVPRIVATE POINTERS FOR A NEWLY CREATED SCREEN, NOR ARE THEY INITIALIZED
 293                WHEN A NEW SCREEN PRIVATE INDEX IS ALLOCATED */
 294           
 295             for (ii=lastScreenWithAdaptors; ii<screenInfo.numScreens; ii++)
 296               screenInfo.screens[ii]->devPrivates[XvScreenIndex].ptr = (pointer)NULL;
 297             lastScreenWithAdaptors = screenInfo.numScreens;
 298           
 299             if (pScreen->devPrivates[XvScreenIndex].ptr)
 300               {
 301                 ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n");
 302               }
 303           
 304             /* ALLOCATE SCREEN PRIVATE RECORD */
 305             
 306             pxvs = (XvScreenPtr) xalloc (sizeof (XvScreenRec));
 307             if (!pxvs)
 308               {
 309                 ErrorF("XvScreenInit: Unable to allocate screen private structure\n");
 310                 return BadAlloc;
 311               }
 312 dawes 1.3 
 313             pScreen->devPrivates[XvScreenIndex].ptr = (pointer)pxvs;
 314           
 315 dawes 1.2   
 316             pxvs->DestroyPixmap = pScreen->DestroyPixmap;
 317             pxvs->DestroyWindow = pScreen->DestroyWindow;
 318             pxvs->CloseScreen = pScreen->CloseScreen;
 319             
 320             pScreen->DestroyPixmap = XvDestroyPixmap;
 321             pScreen->DestroyWindow = XvDestroyWindow;
 322             pScreen->CloseScreen = XvCloseScreen;
 323           
 324             return Success;
 325           }
 326           
 327           static Bool
 328 dawes 1.3 XvCloseScreen(
 329             int ii,
 330             ScreenPtr pScreen
 331           ){
 332 dawes 1.2 
 333             XvScreenPtr pxvs;
 334           
 335             pxvs = (XvScreenPtr) pScreen->devPrivates[XvScreenIndex].ptr;
 336           
 337             pScreen->DestroyPixmap = pxvs->DestroyPixmap;
 338             pScreen->DestroyWindow = pxvs->DestroyWindow;
 339             pScreen->CloseScreen = pxvs->CloseScreen;
 340           
 341 dawes 1.3   (* pxvs->ddCloseScreen)(ii, pScreen); 
 342 dawes 1.2 
 343             xfree(pxvs);
 344           
 345             pScreen->devPrivates[XvScreenIndex].ptr = (pointer)NULL;
 346           
 347             return (*pScreen->CloseScreen)(ii, pScreen);
 348           
 349           }
 350           
 351           static void
 352           XvResetProc(ExtensionEntry* extEntry)
 353           {
 354             lastScreenWithAdaptors = 0;
 355           }
 356           
 357 dawes 1.3 int
 358           XvGetScreenIndex()
 359           {
 360             return XvScreenIndex;
 361           }
 362           
 363           unsigned long
 364           XvGetRTPort()
 365           {
 366             return XvRTPort;
 367           }
 368           
 369 dawes 1.2 static Bool
 370           XvDestroyPixmap(PixmapPtr pPix)
 371           {
 372             Bool status;
 373             ScreenPtr pScreen;
 374             XvScreenPtr pxvs;
 375             XvAdaptorPtr pa;
 376             int na;
 377             XvPortPtr pp;
 378             int np;
 379           
 380             pScreen = pPix->drawable.pScreen;
 381           
 382             SCREEN_PROLOGUE(pScreen, DestroyPixmap);
 383           
 384             pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
 385           
 386             /* CHECK TO SEE IF THIS PORT IS IN USE */
 387           
 388             pa = pxvs->pAdaptors;
 389             na = pxvs->nAdaptors;
 390 dawes 1.2   while (na--)
 391               {
 392                 np = pa->nPorts;
 393                 pp = pa->pPorts;
 394           
 395                 while (np--)
 396           	{
 397           	  if (pp->pDraw == (DrawablePtr)pPix)
 398           	    {
 399           	      XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
 400           
 401           	      (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp, 
 402           						  pp->pDraw);
 403           
 404           	      pp->pDraw = (DrawablePtr)NULL;
 405           	      pp->client = (ClientPtr)NULL;
 406           	      pp->time = currentTime;
 407           	    }
 408           	  pp++;
 409           	}
 410                 pa++;
 411 dawes 1.2     }
 412             
 413             status = (* pScreen->DestroyPixmap)(pPix);
 414           
 415             SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap);
 416           
 417             return status;
 418           
 419           }
 420           
 421           static Bool
 422 dawes 1.3 XvDestroyWindow(WindowPtr pWin)
 423 dawes 1.2 {
 424             Bool status;
 425             ScreenPtr pScreen;
 426             XvScreenPtr pxvs;
 427             XvAdaptorPtr pa;
 428             int na;
 429             XvPortPtr pp;
 430             int np;
 431           
 432             pScreen = pWin->drawable.pScreen;
 433           
 434             SCREEN_PROLOGUE(pScreen, DestroyWindow);
 435           
 436             pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
 437           
 438             /* CHECK TO SEE IF THIS PORT IS IN USE */
 439           
 440             pa = pxvs->pAdaptors;
 441             na = pxvs->nAdaptors;
 442             while (na--)
 443               {
 444 dawes 1.2       np = pa->nPorts;
 445                 pp = pa->pPorts;
 446           
 447                 while (np--)
 448           	{
 449           	  if (pp->pDraw == (DrawablePtr)pWin)
 450           	    {
 451           	      XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
 452           
 453           	      (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp, 
 454           						  pp->pDraw);
 455           
 456           	      pp->pDraw = (DrawablePtr)NULL;
 457           	      pp->client = (ClientPtr)NULL;
 458           	      pp->time = currentTime;
 459           	    }
 460           	  pp++;
 461           	}
 462                 pa++;
 463               }
 464 dawes 1.3 
 465 dawes 1.2   
 466             status = (* pScreen->DestroyWindow)(pWin);
 467           
 468             SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow);
 469           
 470             return status;
 471           
 472           }
 473           
 474           /* The XvdiVideoStopped procedure is a hook for the device dependent layer.
 475              It provides a way for the dd layer to inform the di layer that video has
 476              stopped in a port for reasons that the di layer had no control over; note
 477              that it doesn't call back into the dd layer */
 478           
 479           int
 480           XvdiVideoStopped(XvPortPtr pPort, int reason)
 481           {
 482             
 483             /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
 484           
 485             if (!pPort->pDraw) return Success;
 486 dawes 1.2 
 487             XvdiSendVideoNotify(pPort, pPort->pDraw, reason);
 488           
 489             pPort->pDraw = (DrawablePtr)NULL;
 490             pPort->client = (ClientPtr)NULL;
 491             pPort->time = currentTime;
 492           
 493             return Success;
 494           
 495           }
 496           
 497           static int 
 498           XvdiDestroyPort(pointer pPort, XID id)
 499           {
 500             return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort);
 501           }
 502           
 503           static int
 504           XvdiDestroyGrab(pointer pGrab, XID id)
 505           {
 506             ((XvGrabPtr)pGrab)->client = (ClientPtr)NULL;
 507 dawes 1.3   return Success;
 508 dawes 1.2 }
 509           
 510           static int
 511           XvdiDestroyVideoNotify(pointer pn, XID id)
 512           {
 513             /* JUST CLEAR OUT THE client POINTER FIELD */
 514           
 515             ((XvVideoNotifyPtr)pn)->client = (ClientPtr)NULL;
 516 dawes 1.3   return Success;
 517 dawes 1.2 }
 518           
 519           static int
 520           XvdiDestroyPortNotify(pointer pn, XID id)
 521           {
 522             /* JUST CLEAR OUT THE client POINTER FIELD */
 523           
 524             ((XvPortNotifyPtr)pn)->client = (ClientPtr)NULL;
 525 dawes 1.3   return Success;
 526 dawes 1.2 }
 527           
 528           static int
 529           XvdiDestroyVideoNotifyList(pointer pn, XID id)
 530           {
 531             XvVideoNotifyPtr npn,cpn;
 532           
 533             /* ACTUALLY DESTROY THE NOTITY LIST */
 534           
 535             cpn = (XvVideoNotifyPtr)pn;
 536           
 537             while (cpn)
 538               {
 539                 npn = cpn->next;
 540                 if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify);
 541                 xfree(cpn);
 542                 cpn = npn;
 543               }
 544 dawes 1.3   return Success;
 545 dawes 1.2 }
 546           
 547           static int
 548           XvdiDestroyEncoding(pointer value, XID id)
 549           {
 550 dawes 1.3   return Success;
 551 dawes 1.2 }
 552           
 553           static int
 554           XvdiSendVideoNotify(pPort, pDraw, reason)
 555           
 556           XvPortPtr pPort;
 557           DrawablePtr pDraw;
 558           int reason;
 559           
 560           {
 561             xvEvent event;
 562             XvVideoNotifyPtr pn;
 563           
 564             pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList);
 565           
 566             while (pn) 
 567               {
 568                 if (pn->client)
 569           	{
 570           	  event.u.u.type = XvEventBase + XvVideoNotify;
 571           	  event.u.u.sequenceNumber = pn->client->sequence;
 572 dawes 1.2 	  event.u.videoNotify.time = currentTime.milliseconds;
 573           	  event.u.videoNotify.drawable = pDraw->id;
 574           	  event.u.videoNotify.port = pPort->id;
 575           	  event.u.videoNotify.reason = reason;
 576           	  (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask,
 577           				 NoEventMask, NullGrab);
 578           	}
 579                 pn = pn->next;
 580               }
 581           
 582             return Success;
 583           
 584           }
 585           
 586           
 587           int
 588 dawes 1.3 XvdiSendPortNotify(
 589             XvPortPtr pPort,
 590             Atom attribute,
 591             INT32 value
 592           ){
 593 dawes 1.2   xvEvent event;
 594             XvPortNotifyPtr pn;
 595           
 596             pn = pPort->pNotify;
 597           
 598             while (pn) 
 599               {
 600                 if (pn->client)
 601           	{
 602           	  event.u.u.type = XvEventBase + XvPortNotify;
 603           	  event.u.u.sequenceNumber = pn->client->sequence;
 604           	  event.u.portNotify.time = currentTime.milliseconds;
 605           	  event.u.portNotify.port = pPort->id;
 606           	  event.u.portNotify.attribute = attribute;
 607           	  event.u.portNotify.value = value;
 608           	  (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask,
 609           				 NoEventMask, NullGrab);
 610           	}
 611                 pn = pn->next;
 612               }
 613           
 614 dawes 1.2   return Success;
 615           
 616           }
 617           
 618           int
 619 dawes 1.3 XvdiPutVideo(   
 620              ClientPtr client,
 621              DrawablePtr pDraw,
 622              XvPortPtr pPort,
 623              GCPtr pGC,
 624              INT16 vid_x, INT16 vid_y, 
 625              CARD16 vid_w, CARD16 vid_h, 
 626              INT16 drw_x, INT16 drw_y,
 627              CARD16 drw_w, CARD16 drw_h
 628           ){
 629             int status;
 630 dawes 1.2   DrawablePtr pOldDraw;
 631           
 632 dawes 1.5   if(!drw_w || !drw_h || !vid_w || !vid_h)
 633           	return BadValue;
 634           
 635 dawes 1.2   /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
 636           
 637             UpdateCurrentTime();
 638           
 639             /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
 640                INFORM CLIENT OF ITS FAILURE */
 641           
 642             if (pPort->grab.client && (pPort->grab.client != client))
 643               {
 644                 XvdiSendVideoNotify(pPort, pDraw, XvBusy);
 645                 return Success;
 646               }
 647           
 648             /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
 649                EVENTS TO ANY CLIENTS WHO WANT THEM */
 650           
 651             pOldDraw = pPort->pDraw;
 652             if ((pOldDraw) && (pOldDraw != pDraw))
 653               {
 654                 XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
 655               }
 656 dawes 1.2 
 657             status = (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC, 
 658           					   vid_x, vid_y, vid_w, vid_h, 
 659           					   drw_x, drw_y, drw_w, drw_h);
 660           
 661             if ((pPort->pDraw) && (pOldDraw != pDraw))
 662               {
 663                 pPort->client = client;
 664                 XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
 665               }
 666           
 667             pPort->time = currentTime;
 668           
 669             return (Success);
 670           
 671           }
 672           
 673           int
 674 dawes 1.3 XvdiPutStill(   
 675              ClientPtr client,
 676              DrawablePtr pDraw,
 677              XvPortPtr pPort,
 678              GCPtr pGC,
 679              INT16 vid_x, INT16 vid_y, 
 680              CARD16 vid_w, CARD16 vid_h, 
 681              INT16 drw_x, INT16 drw_y,
 682              CARD16 drw_w, CARD16 drw_h
 683           ){
 684             int status;
 685 dawes 1.2 
 686 dawes 1.5   if(!drw_w || !drw_h || !vid_w || !vid_h)
 687           	return BadValue;
 688           
 689 dawes 1.2   /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
 690           
 691             UpdateCurrentTime();
 692           
 693             /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
 694                INFORM CLIENT OF ITS FAILURE */
 695           
 696             if (pPort->grab.client && (pPort->grab.client != client))
 697               {
 698                 XvdiSendVideoNotify(pPort, pDraw, XvBusy);
 699                 return Success;
 700               }
 701           
 702             pPort->time = currentTime;
 703           
 704             status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC, 
 705           					   vid_x, vid_y, vid_w, vid_h, 
 706           					   drw_x, drw_y, drw_w, drw_h);
 707           
 708             return status;
 709           
 710 dawes 1.2 }
 711 mvojkovi 1.7 
 712              int
 713              XvdiPutImage(   
 714                 ClientPtr client, 
 715                 DrawablePtr pDraw, 
 716                 XvPortPtr pPort, 
 717                 GCPtr pGC,
 718                 INT16 src_x, INT16 src_y, 
 719                 CARD16 src_w, CARD16 src_h, 
 720                 INT16 drw_x, INT16 drw_y,
 721                 CARD16 drw_w, CARD16 drw_h,
 722                 XvImagePtr image,
 723 tsi      1.8    unsigned char* data,
 724 mvojkovi 1.7    Bool sync,
 725                 CARD16 width, CARD16 height
 726              ){
 727                if(!drw_w || !drw_h || !src_w || !src_h)
 728              	return BadValue;
 729              
 730                /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
 731              
 732                UpdateCurrentTime();
 733              
 734                /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
 735                   INFORM CLIENT OF ITS FAILURE */
 736              
 737                if (pPort->grab.client && (pPort->grab.client != client))
 738                  {
 739                    XvdiSendVideoNotify(pPort, pDraw, XvBusy);
 740                    return Success;
 741                  }
 742              
 743                pPort->time = currentTime;
 744              
 745 mvojkovi 1.7   return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC, 
 746              					   src_x, src_y, src_w, src_h, 
 747              					   drw_x, drw_y, drw_w, drw_h,
 748              					   image, data, sync, width, height);
 749              }
 750              
 751              
 752 dawes    1.2 int
 753 dawes    1.3 XvdiGetVideo(
 754                 ClientPtr client,
 755                 DrawablePtr pDraw,
 756                 XvPortPtr pPort,
 757                 GCPtr pGC,
 758                 INT16 vid_x, INT16 vid_y, 
 759                 CARD16 vid_w, CARD16 vid_h, 
 760                 INT16 drw_x, INT16 drw_y,
 761                 CARD16 drw_w, CARD16 drw_h
 762              ){
 763                int status;
 764 dawes    1.2   DrawablePtr pOldDraw;
 765              
 766 dawes    1.5   if(!drw_w || !drw_h || !vid_w || !vid_h)
 767              	return BadValue;
 768              
 769 dawes    1.2   /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
 770              
 771                UpdateCurrentTime();
 772              
 773                /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
 774                   INFORM CLIENT OF ITS FAILURE */
 775              
 776                if (pPort->grab.client && (pPort->grab.client != client))
 777                  {
 778                    XvdiSendVideoNotify(pPort, pDraw, XvBusy);
 779                    return Success;
 780                  }
 781              
 782                /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
 783                   EVENTS TO ANY CLIENTS WHO WANT THEM */
 784              
 785                pOldDraw = pPort->pDraw;
 786                if ((pOldDraw) && (pOldDraw != pDraw))
 787                  {
 788                    XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
 789                  }
 790 dawes    1.2 
 791                status = (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC,
 792              					   vid_x, vid_y, vid_w, vid_h, 
 793              					   drw_x, drw_y, drw_w, drw_h);
 794              
 795                if ((pPort->pDraw) && (pOldDraw != pDraw))
 796                  {
 797                    pPort->client = client;
 798                    XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
 799                  }
 800              
 801                pPort->time = currentTime;
 802              
 803                return (Success);
 804              
 805              }
 806              
 807              int
 808 dawes    1.3 XvdiGetStill(
 809                 ClientPtr client,
 810                 DrawablePtr pDraw,
 811                 XvPortPtr pPort,
 812                 GCPtr pGC,
 813                 INT16 vid_x, INT16 vid_y, 
 814                 CARD16 vid_w, CARD16 vid_h, 
 815                 INT16 drw_x, INT16 drw_y,
 816                 CARD16 drw_w, CARD16 drw_h
 817              ){
 818                int status;
 819 dawes    1.5 
 820                if(!drw_w || !drw_h || !vid_w || !vid_h)
 821              	return BadValue;
 822 dawes    1.2 
 823                /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
 824              
 825                UpdateCurrentTime();
 826              
 827                /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
 828                   INFORM CLIENT OF ITS FAILURE */
 829              
 830                if (pPort->grab.client && (pPort->grab.client != client))
 831                  {
 832                    XvdiSendVideoNotify(pPort, pDraw, XvBusy);
 833                    return Success;
 834                  }
 835              
 836                status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC, 
 837              					   vid_x, vid_y, vid_w, vid_h, 
 838              					   drw_x, drw_y, drw_w, drw_h);
 839              
 840                pPort->time = currentTime;
 841              
 842                return status;
 843 dawes    1.2 
 844              }
 845              
 846              int
 847 dawes    1.3 XvdiGrabPort(
 848                 ClientPtr client,
 849                 XvPortPtr pPort,
 850                 Time ctime,
 851                 int *p_result
 852              ){
 853 dawes    1.2   unsigned long id;
 854                TimeStamp time;
 855              
 856                UpdateCurrentTime();
 857                time = ClientTimeToServerTime(ctime);
 858              
 859                if (pPort->grab.client && (client != pPort->grab.client))
 860                  {
 861                    *p_result = XvAlreadyGrabbed;
 862                    return Success;
 863                  }
 864              
 865                if ((CompareTimeStamps(time, currentTime) == LATER) ||
 866                    (CompareTimeStamps(time, pPort->time) == EARLIER))
 867                  {
 868                    *p_result = XvInvalidTime;
 869                    return Success;
 870                  }
 871              
 872                if (client == pPort->grab.client)
 873                  {
 874 dawes    1.2       *p_result = Success;
 875                    return Success;
 876                  }
 877              
 878                id = FakeClientID(client->index);
 879              
 880                if (!AddResource(id, XvRTGrab, &pPort->grab))
 881                  {
 882                    return BadAlloc;
 883                  }
 884              
 885                /* IF THERE IS ACTIVE VIDEO THEN STOP IT */
 886              
 887                if ((pPort->pDraw) && (client != pPort->client))
 888                  {
 889                    XVCALL(diStopVideo)((ClientPtr)NULL, pPort, pPort->pDraw);
 890                  }
 891              
 892                pPort->grab.client = client;
 893                pPort->grab.id = id;
 894              
 895 dawes    1.2   pPort->time = currentTime;
 896              
 897                *p_result = Success;
 898              
 899                return Success;
 900              
 901              }
 902              
 903              int
 904 dawes    1.3 XvdiUngrabPort(
 905                ClientPtr client,
 906                XvPortPtr pPort,
 907                Time ctime
 908              ){
 909 dawes    1.2   TimeStamp time;
 910              
 911                UpdateCurrentTime();
 912                time = ClientTimeToServerTime(ctime);
 913              
 914                if ((!pPort->grab.client) || (client != pPort->grab.client))
 915                  {
 916                    return Success;
 917                  }
 918              
 919                if ((CompareTimeStamps(time, currentTime) == LATER) ||
 920                    (CompareTimeStamps(time, pPort->time) == EARLIER))
 921                  {
 922                    return Success;
 923                  }
 924              
 925                /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */
 926              
 927                FreeResource(pPort->grab.id, XvRTGrab);
 928                pPort->grab.client = (ClientPtr)NULL;
 929              
 930 dawes    1.2   pPort->time = currentTime;
 931              
 932                return Success;
 933              
 934              }
 935              
 936              
 937              int
 938 dawes    1.3 XvdiSelectVideoNotify(
 939                ClientPtr client,
 940                DrawablePtr pDraw,
 941                BOOL onoff
 942              ){
 943 dawes    1.2   XvVideoNotifyPtr pn,tpn,fpn;
 944              
 945                /* FIND VideoNotify LIST */
 946              
 947                pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList);
 948              
 949                /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */
 950              
 951                if (!onoff && !pn) return Success;
 952              
 953                /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST
 954                   WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */
 955              
 956                if (!pn) 
 957                  {
 958                    if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec))))
 959              	return BadAlloc;
 960                    tpn->next = (XvVideoNotifyPtr)NULL;
 961                    if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn))
 962              	{
 963              	  xfree(tpn);
 964 dawes    1.2 	  return BadAlloc;
 965              	}
 966                  }
 967                else
 968                  {
 969                    /* LOOK TO SEE IF ENTRY ALREADY EXISTS */
 970              
 971                    fpn = (XvVideoNotifyPtr)NULL;
 972                    tpn = pn;
 973                    while (tpn)
 974              	{
 975              	  if (tpn->client == client) 
 976              	    {
 977              	      if (!onoff) tpn->client = (ClientPtr)NULL;
 978              	      return Success;
 979              	    }
 980              	  if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */
 981              	  tpn = tpn->next;
 982              	}
 983              
 984                    /* IF TUNNING OFF, THEN JUST RETURN */
 985 dawes    1.2 
 986                    if (!onoff) return Success;
 987              
 988                    /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */
 989              
 990                    if (fpn)
 991              	{
 992              	  tpn = fpn;
 993              	}
 994                    else
 995              	{
 996              	  if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec))))
 997              	    return BadAlloc;
 998              	  tpn->next = pn->next;
 999              	  pn->next = tpn;
1000              	}
1001                  }
1002              
1003                /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */
1004                /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */
1005              
1006 dawes    1.2   tpn->client = (ClientPtr)NULL;
1007                tpn->id = FakeClientID(client->index);
1008                AddResource(tpn->id, XvRTVideoNotify, tpn);
1009              
1010                tpn->client = client;
1011                return Success;
1012              
1013              }
1014              
1015              int
1016 dawes    1.3 XvdiSelectPortNotify(
1017                 ClientPtr client,
1018                 XvPortPtr pPort,
1019                 BOOL onoff
1020              ){
1021 dawes    1.2   XvPortNotifyPtr pn,tpn;
1022              
1023                /* SEE IF CLIENT IS ALREADY IN LIST */
1024              
1025                tpn = (XvPortNotifyPtr)NULL;
1026                pn = pPort->pNotify;
1027                while (pn)
1028                  {
1029                    if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */
1030                    if (pn->client == client) break;
1031                    pn = pn->next;
1032                  }
1033              
1034                /* IS THE CLIENT ALREADY ON THE LIST? */
1035              
1036                if (pn)
1037                  {
1038                    /* REMOVE IT? */
1039              
1040                    if (!onoff)
1041              	{
1042 dawes    1.2 	  pn->client = (ClientPtr)NULL;
1043              	  FreeResource(pn->id, XvRTPortNotify);
1044              	}
1045              
1046                    return Success;
1047                  }
1048              
1049                /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE 
1050                   CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */
1051              
1052                if (!tpn)
1053                  {
1054                    if (!(tpn = (XvPortNotifyPtr)xalloc(sizeof(XvPortNotifyRec))))
1055              	return BadAlloc;
1056                    tpn->next = pPort->pNotify;
1057                    pPort->pNotify = tpn;
1058                  }
1059              
1060                tpn->client = client;
1061                tpn->id = FakeClientID(client->index);
1062                AddResource(tpn->id, XvRTPortNotify, tpn);
1063 dawes    1.2 
1064                return Success;
1065              
1066              }
1067              
1068              int
1069 dawes    1.3 XvdiStopVideo(
1070                ClientPtr client,
1071                XvPortPtr pPort,
1072                DrawablePtr pDraw
1073              ){
1074 dawes    1.2   int status;
1075              
1076                /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
1077              
1078                if (!pPort->pDraw || (pPort->pDraw != pDraw)) 
1079                  {
1080                    XvdiSendVideoNotify(pPort, pDraw, XvStopped);
1081                    return Success;
1082                  }
1083              
1084                /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
1085                   INFORM CLIENT OF ITS FAILURE */
1086              
1087                if ((client) && (pPort->grab.client) && (pPort->grab.client != client))
1088                  {
1089                    XvdiSendVideoNotify(pPort, pDraw, XvBusy);
1090                    return Success;
1091                  }
1092              
1093                XvdiSendVideoNotify(pPort, pDraw, XvStopped);
1094              
1095 dawes    1.2   status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw);
1096              
1097                pPort->pDraw = (DrawablePtr)NULL;
1098                pPort->client = (ClientPtr)client;
1099                pPort->time = currentTime;
1100              
1101                return status;
1102              
1103              }
1104              
1105              int
1106 dawes    1.3 XvdiPreemptVideo(
1107                ClientPtr client,
1108                XvPortPtr pPort,
1109                DrawablePtr pDraw
1110              ){
1111 dawes    1.2   int status;
1112              
1113                /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
1114              
1115                if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success;
1116              
1117                XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
1118              
1119                status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw);
1120              
1121                pPort->pDraw = (DrawablePtr)NULL;
1122                pPort->client = (ClientPtr)client;
1123                pPort->time = currentTime;
1124              
1125                return status;
1126              
1127              }
1128              
1129 dawes    1.3 int
1130              XvdiMatchPort(
1131                XvPortPtr pPort,
1132                DrawablePtr pDraw
1133              ){
1134 dawes    1.2 
1135                XvAdaptorPtr pa;
1136                XvFormatPtr pf;
1137                int nf;
1138              
1139                pa = pPort->pAdaptor;
1140              
1141                if (pa->pScreen != pDraw->pScreen) return BadMatch;
1142              
1143                nf = pa->nFormats;
1144                pf = pa->pFormats;
1145              
1146                while (nf--)
1147                  {
1148                    if ((pf->depth == pDraw->depth) &&
1149              	  ((pDraw->type == DRAWABLE_PIXMAP) || 
1150              	   (wVisual(((WindowPtr)pDraw)) == pf->visual)))
1151              	return Success;
1152                    pf++;
1153                  }
1154              
1155 dawes    1.2   return BadMatch;
1156              
1157              }
1158              
1159              int
1160 dawes    1.3 XvdiSetPortAttribute(
1161                ClientPtr client,
1162                XvPortPtr pPort,
1163                Atom attribute,
1164                INT32 value
1165              ){
1166 dawes    1.6 
1167                  XvdiSendPortNotify(pPort, attribute, value);
1168 dawes    1.2 
1169                return 
1170                  (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value);
1171              
1172              }
1173              
1174              int
1175 dawes    1.3 XvdiGetPortAttribute(
1176                ClientPtr client,
1177                XvPortPtr pPort,
1178                Atom attribute,
1179                INT32 *p_value
1180              ){
1181 dawes    1.2 
1182                return 
1183                  (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value);
1184              
1185              }
1186              
1187              static void
1188 dawes    1.3 WriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to)
1189 dawes    1.2 
1190              {
1191              
1192                to->u.u.type = from->u.u.type;
1193                to->u.u.detail = from->u.u.detail;
1194                cpswaps(from->u.videoNotify.sequenceNumber, 
1195              	  to->u.videoNotify.sequenceNumber);
1196                cpswapl(from->u.videoNotify.time, to->u.videoNotify.time);
1197                cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable);
1198                cpswapl(from->u.videoNotify.port, to->u.videoNotify.port);
1199              
1200              }
1201              
1202              static void
1203 dawes    1.3 WriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to)
1204 dawes    1.2 
1205              {
1206              
1207                to->u.u.type = from->u.u.type;
1208                to->u.u.detail = from->u.u.detail;
1209                cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber);
1210                cpswapl(from->u.portNotify.time, to->u.portNotify.time);
1211                cpswapl(from->u.portNotify.port, to->u.portNotify.port);
1212                cpswapl(from->u.portNotify.value, to->u.portNotify.value);
1213              
1214              }

Powered by
ViewCVS 0.9.2