~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to Xext/xvmain.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

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