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 }
|