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