xref: /OK3568_Linux_fs/external/xserver/dbe/midbe.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright (c) 1994, 1995  Hewlett-Packard Company
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining
6*4882a593Smuzhiyun  * a copy of this software and associated documentation files (the
7*4882a593Smuzhiyun  * "Software"), to deal in the Software without restriction, including
8*4882a593Smuzhiyun  * without limitation the rights to use, copy, modify, merge, publish,
9*4882a593Smuzhiyun  * distribute, sublicense, and/or sell copies of the Software, and to
10*4882a593Smuzhiyun  * permit persons to whom the Software is furnished to do so, subject to
11*4882a593Smuzhiyun  * the following conditions:
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included
14*4882a593Smuzhiyun  * in all copies or substantial portions of the Software.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*4882a593Smuzhiyun  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*4882a593Smuzhiyun  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19*4882a593Smuzhiyun  * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
20*4882a593Smuzhiyun  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21*4882a593Smuzhiyun  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22*4882a593Smuzhiyun  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  * Except as contained in this notice, the name of the Hewlett-Packard
25*4882a593Smuzhiyun  * Company shall not be used in advertising or otherwise to promote the
26*4882a593Smuzhiyun  * sale, use or other dealings in this Software without prior written
27*4882a593Smuzhiyun  * authorization from the Hewlett-Packard Company.
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  *     Machine-independent DBE code
30*4882a593Smuzhiyun  *
31*4882a593Smuzhiyun  *****************************************************************************/
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* INCLUDES */
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
36*4882a593Smuzhiyun #include <dix-config.h>
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #include <X11/X.h>
40*4882a593Smuzhiyun #include <X11/Xproto.h>
41*4882a593Smuzhiyun #include "misc.h"
42*4882a593Smuzhiyun #include "os.h"
43*4882a593Smuzhiyun #include "windowstr.h"
44*4882a593Smuzhiyun #include "scrnintstr.h"
45*4882a593Smuzhiyun #include "pixmapstr.h"
46*4882a593Smuzhiyun #include "extnsionst.h"
47*4882a593Smuzhiyun #include "dixstruct.h"
48*4882a593Smuzhiyun #include "resource.h"
49*4882a593Smuzhiyun #include "opaque.h"
50*4882a593Smuzhiyun #include "dbestruct.h"
51*4882a593Smuzhiyun #include "regionstr.h"
52*4882a593Smuzhiyun #include "gcstruct.h"
53*4882a593Smuzhiyun #include "inputstr.h"
54*4882a593Smuzhiyun #include "midbe.h"
55*4882a593Smuzhiyun #include "xace.h"
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun #include <stdio.h>
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /******************************************************************************
61*4882a593Smuzhiyun  *
62*4882a593Smuzhiyun  * DBE MI Procedure: miDbeGetVisualInfo
63*4882a593Smuzhiyun  *
64*4882a593Smuzhiyun  * Description:
65*4882a593Smuzhiyun  *
66*4882a593Smuzhiyun  *     This is the MI function for the DbeGetVisualInfo request.  This function
67*4882a593Smuzhiyun  *     is called through pDbeScreenPriv->GetVisualInfo.  This function is also
68*4882a593Smuzhiyun  *     called for the DbeAllocateBackBufferName request at the extension level;
69*4882a593Smuzhiyun  *     it is called by ProcDbeAllocateBackBufferName() in dbe.c.
70*4882a593Smuzhiyun  *
71*4882a593Smuzhiyun  *     If memory allocation fails or we can not get the visual info, this
72*4882a593Smuzhiyun  *     function returns FALSE.  Otherwise, it returns TRUE for success.
73*4882a593Smuzhiyun  *
74*4882a593Smuzhiyun  *****************************************************************************/
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun static Bool
miDbeGetVisualInfo(ScreenPtr pScreen,XdbeScreenVisualInfo * pScrVisInfo)77*4882a593Smuzhiyun miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun     register int i, j, k;
80*4882a593Smuzhiyun     register int count;
81*4882a593Smuzhiyun     DepthPtr pDepth;
82*4882a593Smuzhiyun     XdbeVisualInfo *visInfo;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun     /* Determine number of visuals for this screen. */
85*4882a593Smuzhiyun     for (i = 0, count = 0; i < pScreen->numDepths; i++) {
86*4882a593Smuzhiyun         count += pScreen->allowedDepths[i].numVids;
87*4882a593Smuzhiyun     }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun     /* Allocate an array of XdbeVisualInfo items. */
90*4882a593Smuzhiyun     if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) {
91*4882a593Smuzhiyun         return FALSE;           /* memory alloc failure */
92*4882a593Smuzhiyun     }
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun     for (i = 0, k = 0; i < pScreen->numDepths; i++) {
95*4882a593Smuzhiyun         /* For each depth of this screen, get visual information. */
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun         pDepth = &pScreen->allowedDepths[i];
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun         for (j = 0; j < pDepth->numVids; j++) {
100*4882a593Smuzhiyun             /* For each visual for this depth of this screen, get visual ID
101*4882a593Smuzhiyun              * and visual depth.  Since this is MI code, we will always return
102*4882a593Smuzhiyun              * the same performance level for all visuals (0).  A higher
103*4882a593Smuzhiyun              * performance level value indicates higher performance.
104*4882a593Smuzhiyun              */
105*4882a593Smuzhiyun             visInfo[k].visual = pDepth->vids[j];
106*4882a593Smuzhiyun             visInfo[k].depth = pDepth->depth;
107*4882a593Smuzhiyun             visInfo[k].perflevel = 0;
108*4882a593Smuzhiyun             k++;
109*4882a593Smuzhiyun         }
110*4882a593Smuzhiyun     }
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun     /* Record the number of visuals and point visual_depth to
113*4882a593Smuzhiyun      * the array of visual info.
114*4882a593Smuzhiyun      */
115*4882a593Smuzhiyun     pScrVisInfo->count = count;
116*4882a593Smuzhiyun     pScrVisInfo->visinfo = visInfo;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun     return TRUE;                /* success */
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun }                               /* miDbeGetVisualInfo() */
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun /******************************************************************************
123*4882a593Smuzhiyun  *
124*4882a593Smuzhiyun  * DBE MI Procedure: miAllocBackBufferName
125*4882a593Smuzhiyun  *
126*4882a593Smuzhiyun  * Description:
127*4882a593Smuzhiyun  *
128*4882a593Smuzhiyun  *     This is the MI function for the DbeAllocateBackBufferName request.
129*4882a593Smuzhiyun  *
130*4882a593Smuzhiyun  *****************************************************************************/
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun static int
miDbeAllocBackBufferName(WindowPtr pWin,XID bufId,int swapAction)133*4882a593Smuzhiyun miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun     ScreenPtr pScreen;
136*4882a593Smuzhiyun     DbeWindowPrivPtr pDbeWindowPriv;
137*4882a593Smuzhiyun     DbeScreenPrivPtr pDbeScreenPriv;
138*4882a593Smuzhiyun     GCPtr pGC;
139*4882a593Smuzhiyun     xRectangle clearRect;
140*4882a593Smuzhiyun     int rc;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun     pScreen = pWin->drawable.pScreen;
143*4882a593Smuzhiyun     pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun     if (pDbeWindowPriv->nBufferIDs == 0) {
146*4882a593Smuzhiyun         /* There is no buffer associated with the window.
147*4882a593Smuzhiyun          * We have to create the window priv priv.  Remember, the window
148*4882a593Smuzhiyun          * priv was created at the DIX level, so all we need to do is
149*4882a593Smuzhiyun          * create the priv priv and attach it to the priv.
150*4882a593Smuzhiyun          */
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun         pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun         /* Get a front pixmap. */
155*4882a593Smuzhiyun         if (!(pDbeWindowPriv->pFrontBuffer =
156*4882a593Smuzhiyun               (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width,
157*4882a593Smuzhiyun                                         pDbeWindowPriv->height,
158*4882a593Smuzhiyun                                         pWin->drawable.depth, 0))) {
159*4882a593Smuzhiyun             return BadAlloc;
160*4882a593Smuzhiyun         }
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun         /* Get a back pixmap. */
163*4882a593Smuzhiyun         if (!(pDbeWindowPriv->pBackBuffer =
164*4882a593Smuzhiyun               (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width,
165*4882a593Smuzhiyun                                         pDbeWindowPriv->height,
166*4882a593Smuzhiyun                                         pWin->drawable.depth, 0))) {
167*4882a593Smuzhiyun             (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer);
168*4882a593Smuzhiyun             return BadAlloc;
169*4882a593Smuzhiyun         }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun         /* Security creation/labeling check. */
172*4882a593Smuzhiyun         rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId,
173*4882a593Smuzhiyun                       dbeDrawableResType, pDbeWindowPriv->pBackBuffer,
174*4882a593Smuzhiyun                       RT_WINDOW, pWin, DixCreateAccess);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun         /* Make the back pixmap a DBE drawable resource. */
177*4882a593Smuzhiyun         if (rc != Success || !AddResource(bufId, dbeDrawableResType,
178*4882a593Smuzhiyun                                           pDbeWindowPriv->pBackBuffer)) {
179*4882a593Smuzhiyun             /* free the buffer and the drawable resource */
180*4882a593Smuzhiyun             FreeResource(bufId, RT_NONE);
181*4882a593Smuzhiyun             return (rc == Success) ? BadAlloc : rc;
182*4882a593Smuzhiyun         }
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun         /* Clear the back buffer. */
185*4882a593Smuzhiyun         pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
186*4882a593Smuzhiyun         if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
187*4882a593Smuzhiyun             ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC);
188*4882a593Smuzhiyun             clearRect.x = clearRect.y = 0;
189*4882a593Smuzhiyun             clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width;
190*4882a593Smuzhiyun             clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height;
191*4882a593Smuzhiyun             (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv->
192*4882a593Smuzhiyun                                        pBackBuffer, pGC, 1, &clearRect);
193*4882a593Smuzhiyun         }
194*4882a593Smuzhiyun         FreeScratchGC(pGC);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun     }                           /* if no buffer associated with the window */
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun     else {
199*4882a593Smuzhiyun         /* A buffer is already associated with the window.
200*4882a593Smuzhiyun          * Place the new buffer ID information at the head of the ID list.
201*4882a593Smuzhiyun          */
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun         /* Associate the new ID with an existing pixmap. */
204*4882a593Smuzhiyun         if (!AddResource(bufId, dbeDrawableResType,
205*4882a593Smuzhiyun                          (void *) pDbeWindowPriv->pBackBuffer)) {
206*4882a593Smuzhiyun             return BadAlloc;
207*4882a593Smuzhiyun         }
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun     }
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun     return Success;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun }                               /* miDbeAllocBackBufferName() */
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun /******************************************************************************
216*4882a593Smuzhiyun  *
217*4882a593Smuzhiyun  * DBE MI Procedure: miDbeAliasBuffers
218*4882a593Smuzhiyun  *
219*4882a593Smuzhiyun  * Description:
220*4882a593Smuzhiyun  *
221*4882a593Smuzhiyun  *     This function associates all XIDs of a buffer with the back pixmap
222*4882a593Smuzhiyun  *     stored in the window priv.
223*4882a593Smuzhiyun  *
224*4882a593Smuzhiyun  *****************************************************************************/
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun static void
miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)227*4882a593Smuzhiyun miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun     int i;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun     for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) {
232*4882a593Smuzhiyun         ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
233*4882a593Smuzhiyun                             (void *) pDbeWindowPriv->pBackBuffer);
234*4882a593Smuzhiyun     }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun }                               /* miDbeAliasBuffers() */
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /******************************************************************************
239*4882a593Smuzhiyun  *
240*4882a593Smuzhiyun  * DBE MI Procedure: miDbeSwapBuffers
241*4882a593Smuzhiyun  *
242*4882a593Smuzhiyun  * Description:
243*4882a593Smuzhiyun  *
244*4882a593Smuzhiyun  *     This is the MI function for the DbeSwapBuffers request.
245*4882a593Smuzhiyun  *
246*4882a593Smuzhiyun  *****************************************************************************/
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun static int
miDbeSwapBuffers(ClientPtr client,int * pNumWindows,DbeSwapInfoPtr swapInfo)249*4882a593Smuzhiyun miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun     DbeScreenPrivPtr pDbeScreenPriv;
252*4882a593Smuzhiyun     DbeWindowPrivPtr pDbeWindowPriv;
253*4882a593Smuzhiyun     GCPtr pGC;
254*4882a593Smuzhiyun     WindowPtr pWin;
255*4882a593Smuzhiyun     PixmapPtr pTmpBuffer;
256*4882a593Smuzhiyun     xRectangle clearRect;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun     pWin = swapInfo[0].pWindow;
259*4882a593Smuzhiyun     pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
260*4882a593Smuzhiyun     pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
261*4882a593Smuzhiyun     pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun     /*
264*4882a593Smuzhiyun      **********************************************************************
265*4882a593Smuzhiyun      ** Setup before swap.
266*4882a593Smuzhiyun      **********************************************************************
267*4882a593Smuzhiyun      */
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun     switch (swapInfo[0].swapAction) {
270*4882a593Smuzhiyun     case XdbeUndefined:
271*4882a593Smuzhiyun         break;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun     case XdbeBackground:
274*4882a593Smuzhiyun         break;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun     case XdbeUntouched:
277*4882a593Smuzhiyun         ValidateGC((DrawablePtr) pDbeWindowPriv->pFrontBuffer, pGC);
278*4882a593Smuzhiyun         (*pGC->ops->CopyArea) ((DrawablePtr) pWin,
279*4882a593Smuzhiyun                                (DrawablePtr) pDbeWindowPriv->pFrontBuffer,
280*4882a593Smuzhiyun                                pGC, 0, 0, pWin->drawable.width,
281*4882a593Smuzhiyun                                pWin->drawable.height, 0, 0);
282*4882a593Smuzhiyun         break;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun     case XdbeCopied:
285*4882a593Smuzhiyun         break;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun     }
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun     /*
290*4882a593Smuzhiyun      **********************************************************************
291*4882a593Smuzhiyun      ** Swap.
292*4882a593Smuzhiyun      **********************************************************************
293*4882a593Smuzhiyun      */
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun     ValidateGC((DrawablePtr) pWin, pGC);
296*4882a593Smuzhiyun     (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer,
297*4882a593Smuzhiyun                            (DrawablePtr) pWin, pGC, 0, 0,
298*4882a593Smuzhiyun                            pWin->drawable.width, pWin->drawable.height, 0, 0);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun     /*
301*4882a593Smuzhiyun      **********************************************************************
302*4882a593Smuzhiyun      ** Tasks after swap.
303*4882a593Smuzhiyun      **********************************************************************
304*4882a593Smuzhiyun      */
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun     switch (swapInfo[0].swapAction) {
307*4882a593Smuzhiyun     case XdbeUndefined:
308*4882a593Smuzhiyun         break;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun     case XdbeBackground:
311*4882a593Smuzhiyun         if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
312*4882a593Smuzhiyun             ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC);
313*4882a593Smuzhiyun             clearRect.x = 0;
314*4882a593Smuzhiyun             clearRect.y = 0;
315*4882a593Smuzhiyun             clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width;
316*4882a593Smuzhiyun             clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height;
317*4882a593Smuzhiyun             (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv->
318*4882a593Smuzhiyun                                        pBackBuffer, pGC, 1, &clearRect);
319*4882a593Smuzhiyun         }
320*4882a593Smuzhiyun         break;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun     case XdbeUntouched:
323*4882a593Smuzhiyun         /* Swap pixmap pointers. */
324*4882a593Smuzhiyun         pTmpBuffer = pDbeWindowPriv->pBackBuffer;
325*4882a593Smuzhiyun         pDbeWindowPriv->pBackBuffer = pDbeWindowPriv->pFrontBuffer;
326*4882a593Smuzhiyun         pDbeWindowPriv->pFrontBuffer = pTmpBuffer;
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun         miDbeAliasBuffers(pDbeWindowPriv);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun         break;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun     case XdbeCopied:
333*4882a593Smuzhiyun         break;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun     }
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun     /* Remove the swapped window from the swap information array and decrement
338*4882a593Smuzhiyun      * pNumWindows to indicate to the DIX level how many windows were actually
339*4882a593Smuzhiyun      * swapped.
340*4882a593Smuzhiyun      */
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun     if (*pNumWindows > 1) {
343*4882a593Smuzhiyun         /* We were told to swap more than one window, but we only swapped the
344*4882a593Smuzhiyun          * first one.  Remove the first window in the list by moving the last
345*4882a593Smuzhiyun          * window to the beginning.
346*4882a593Smuzhiyun          */
347*4882a593Smuzhiyun         swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow;
348*4882a593Smuzhiyun         swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun         /* Clear the last window information just to be safe. */
351*4882a593Smuzhiyun         swapInfo[*pNumWindows - 1].pWindow = (WindowPtr) NULL;
352*4882a593Smuzhiyun         swapInfo[*pNumWindows - 1].swapAction = 0;
353*4882a593Smuzhiyun     }
354*4882a593Smuzhiyun     else {
355*4882a593Smuzhiyun         /* Clear the window information just to be safe. */
356*4882a593Smuzhiyun         swapInfo[0].pWindow = (WindowPtr) NULL;
357*4882a593Smuzhiyun         swapInfo[0].swapAction = 0;
358*4882a593Smuzhiyun     }
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun     (*pNumWindows)--;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun     FreeScratchGC(pGC);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun     return Success;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun }                               /* miSwapBuffers() */
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun /******************************************************************************
369*4882a593Smuzhiyun  *
370*4882a593Smuzhiyun  * DBE MI Procedure: miDbeWinPrivDelete
371*4882a593Smuzhiyun  *
372*4882a593Smuzhiyun  * Description:
373*4882a593Smuzhiyun  *
374*4882a593Smuzhiyun  *     This is the MI function for deleting the dbeWindowPrivResType resource.
375*4882a593Smuzhiyun  *     This function is invoked indirectly by calling FreeResource() to free
376*4882a593Smuzhiyun  *     the resources associated with a DBE buffer ID.  There are 5 ways that
377*4882a593Smuzhiyun  *     miDbeWinPrivDelete() can be called by FreeResource().  They are:
378*4882a593Smuzhiyun  *
379*4882a593Smuzhiyun  *     - A DBE window is destroyed, in which case the DbeDestroyWindow()
380*4882a593Smuzhiyun  *       wrapper is invoked.  The wrapper calls FreeResource() for all DBE
381*4882a593Smuzhiyun  *       buffer IDs.
382*4882a593Smuzhiyun  *
383*4882a593Smuzhiyun  *     - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
384*4882a593Smuzhiyun  *       after a buffer allocation failure.
385*4882a593Smuzhiyun  *
386*4882a593Smuzhiyun  *     - The PositionWindow wrapper, miDbePositionWindow(), calls
387*4882a593Smuzhiyun  *       FreeResource() when it fails to create buffers of the new size.
388*4882a593Smuzhiyun  *       FreeResource() is called for all DBE buffer IDs.
389*4882a593Smuzhiyun  *
390*4882a593Smuzhiyun  *     - FreeClientResources() calls FreeResource() when a client dies or the
391*4882a593Smuzhiyun  *       the server resets.
392*4882a593Smuzhiyun  *
393*4882a593Smuzhiyun  *     When FreeResource() is called for a DBE buffer ID, the delete function
394*4882a593Smuzhiyun  *     for the only other type of DBE resource, dbeDrawableResType, is also
395*4882a593Smuzhiyun  *     invoked.  This delete function (DbeDrawableDelete) is a NOOP to make
396*4882a593Smuzhiyun  *     resource deletion easier.  It is not guaranteed which delete function is
397*4882a593Smuzhiyun  *     called first.  Hence, we will let miDbeWinPrivDelete() free all DBE
398*4882a593Smuzhiyun  *     resources.
399*4882a593Smuzhiyun  *
400*4882a593Smuzhiyun  *     This function deletes/frees the following stuff associated with
401*4882a593Smuzhiyun  *     the window private:
402*4882a593Smuzhiyun  *
403*4882a593Smuzhiyun  *     - the ID node in the ID list representing the passed in ID.
404*4882a593Smuzhiyun  *
405*4882a593Smuzhiyun  *     In addition, pDbeWindowPriv->nBufferIDs is decremented.
406*4882a593Smuzhiyun  *
407*4882a593Smuzhiyun  *     If this function is called for the last/only buffer ID for a window,
408*4882a593Smuzhiyun  *     these are additionally deleted/freed:
409*4882a593Smuzhiyun  *
410*4882a593Smuzhiyun  *     - the front and back pixmaps
411*4882a593Smuzhiyun  *     - the window priv itself
412*4882a593Smuzhiyun  *
413*4882a593Smuzhiyun  *****************************************************************************/
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun static void
miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv,XID bufId)416*4882a593Smuzhiyun miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun     if (pDbeWindowPriv->nBufferIDs != 0) {
419*4882a593Smuzhiyun         /* We still have at least one more buffer ID associated with this
420*4882a593Smuzhiyun          * window.
421*4882a593Smuzhiyun          */
422*4882a593Smuzhiyun         return;
423*4882a593Smuzhiyun     }
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun     /* We have no more buffer IDs associated with this window.  We need to
426*4882a593Smuzhiyun      * free some stuff.
427*4882a593Smuzhiyun      */
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun     /* Destroy the front and back pixmaps. */
430*4882a593Smuzhiyun     if (pDbeWindowPriv->pFrontBuffer) {
431*4882a593Smuzhiyun         (*pDbeWindowPriv->pWindow->drawable.pScreen->
432*4882a593Smuzhiyun          DestroyPixmap) (pDbeWindowPriv->pFrontBuffer);
433*4882a593Smuzhiyun     }
434*4882a593Smuzhiyun     if (pDbeWindowPriv->pBackBuffer) {
435*4882a593Smuzhiyun         (*pDbeWindowPriv->pWindow->drawable.pScreen->
436*4882a593Smuzhiyun          DestroyPixmap) (pDbeWindowPriv->pBackBuffer);
437*4882a593Smuzhiyun     }
438*4882a593Smuzhiyun }                               /* miDbeWinPrivDelete() */
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun /******************************************************************************
441*4882a593Smuzhiyun  *
442*4882a593Smuzhiyun  * DBE MI Procedure: miDbePositionWindow
443*4882a593Smuzhiyun  *
444*4882a593Smuzhiyun  * Description:
445*4882a593Smuzhiyun  *
446*4882a593Smuzhiyun  *     This function was cloned from miMbxPositionWindow() in mimultibuf.c.
447*4882a593Smuzhiyun  *     This function resizes the buffer when the window is resized.
448*4882a593Smuzhiyun  *
449*4882a593Smuzhiyun  *****************************************************************************/
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun static Bool
miDbePositionWindow(WindowPtr pWin,int x,int y)452*4882a593Smuzhiyun miDbePositionWindow(WindowPtr pWin, int x, int y)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun     ScreenPtr pScreen;
455*4882a593Smuzhiyun     DbeScreenPrivPtr pDbeScreenPriv;
456*4882a593Smuzhiyun     DbeWindowPrivPtr pDbeWindowPriv;
457*4882a593Smuzhiyun     int width, height;
458*4882a593Smuzhiyun     int dx, dy, dw, dh;
459*4882a593Smuzhiyun     int sourcex, sourcey;
460*4882a593Smuzhiyun     int destx, desty;
461*4882a593Smuzhiyun     int savewidth, saveheight;
462*4882a593Smuzhiyun     PixmapPtr pFrontBuffer;
463*4882a593Smuzhiyun     PixmapPtr pBackBuffer;
464*4882a593Smuzhiyun     Bool clear;
465*4882a593Smuzhiyun     GCPtr pGC;
466*4882a593Smuzhiyun     xRectangle clearRect;
467*4882a593Smuzhiyun     Bool ret;
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun     /*
470*4882a593Smuzhiyun      **************************************************************************
471*4882a593Smuzhiyun      ** 1. Unwrap the member routine.
472*4882a593Smuzhiyun      **************************************************************************
473*4882a593Smuzhiyun      */
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun     pScreen = pWin->drawable.pScreen;
476*4882a593Smuzhiyun     pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
477*4882a593Smuzhiyun     pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun     /*
480*4882a593Smuzhiyun      **************************************************************************
481*4882a593Smuzhiyun      ** 2. Do any work necessary before the member routine is called.
482*4882a593Smuzhiyun      **
483*4882a593Smuzhiyun      **    In this case we do not need to do anything.
484*4882a593Smuzhiyun      **************************************************************************
485*4882a593Smuzhiyun      */
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun     /*
488*4882a593Smuzhiyun      **************************************************************************
489*4882a593Smuzhiyun      ** 3. Call the member routine, saving its result if necessary.
490*4882a593Smuzhiyun      **************************************************************************
491*4882a593Smuzhiyun      */
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun     ret = (*pScreen->PositionWindow) (pWin, x, y);
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun     /*
496*4882a593Smuzhiyun      **************************************************************************
497*4882a593Smuzhiyun      ** 4. Rewrap the member routine, restoring the wrapper value first in case
498*4882a593Smuzhiyun      **    the wrapper (or something that it wrapped) change this value.
499*4882a593Smuzhiyun      **************************************************************************
500*4882a593Smuzhiyun      */
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun     pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
503*4882a593Smuzhiyun     pScreen->PositionWindow = miDbePositionWindow;
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun     /*
506*4882a593Smuzhiyun      **************************************************************************
507*4882a593Smuzhiyun      ** 5. Do any work necessary after the member routine has been called.
508*4882a593Smuzhiyun      **************************************************************************
509*4882a593Smuzhiyun      */
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun     if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) {
512*4882a593Smuzhiyun         return ret;
513*4882a593Smuzhiyun     }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun     if (pDbeWindowPriv->width == pWin->drawable.width &&
516*4882a593Smuzhiyun         pDbeWindowPriv->height == pWin->drawable.height) {
517*4882a593Smuzhiyun         return ret;
518*4882a593Smuzhiyun     }
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun     width = pWin->drawable.width;
521*4882a593Smuzhiyun     height = pWin->drawable.height;
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun     dx = pWin->drawable.x - pDbeWindowPriv->x;
524*4882a593Smuzhiyun     dy = pWin->drawable.y - pDbeWindowPriv->y;
525*4882a593Smuzhiyun     dw = width - pDbeWindowPriv->width;
526*4882a593Smuzhiyun     dh = height - pDbeWindowPriv->height;
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun     GravityTranslate(0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun     clear = ((pDbeWindowPriv->width < (unsigned short) width) ||
531*4882a593Smuzhiyun              (pDbeWindowPriv->height < (unsigned short) height) ||
532*4882a593Smuzhiyun              (pWin->bitGravity == ForgetGravity));
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun     sourcex = 0;
535*4882a593Smuzhiyun     sourcey = 0;
536*4882a593Smuzhiyun     savewidth = pDbeWindowPriv->width;
537*4882a593Smuzhiyun     saveheight = pDbeWindowPriv->height;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun     /* Clip rectangle to source and destination. */
540*4882a593Smuzhiyun     if (destx < 0) {
541*4882a593Smuzhiyun         savewidth += destx;
542*4882a593Smuzhiyun         sourcex -= destx;
543*4882a593Smuzhiyun         destx = 0;
544*4882a593Smuzhiyun     }
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun     if (destx + savewidth > width) {
547*4882a593Smuzhiyun         savewidth = width - destx;
548*4882a593Smuzhiyun     }
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun     if (desty < 0) {
551*4882a593Smuzhiyun         saveheight += desty;
552*4882a593Smuzhiyun         sourcey -= desty;
553*4882a593Smuzhiyun         desty = 0;
554*4882a593Smuzhiyun     }
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun     if (desty + saveheight > height) {
557*4882a593Smuzhiyun         saveheight = height - desty;
558*4882a593Smuzhiyun     }
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun     pDbeWindowPriv->width = width;
561*4882a593Smuzhiyun     pDbeWindowPriv->height = height;
562*4882a593Smuzhiyun     pDbeWindowPriv->x = pWin->drawable.x;
563*4882a593Smuzhiyun     pDbeWindowPriv->y = pWin->drawable.y;
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun     pGC = GetScratchGC(pWin->drawable.depth, pScreen);
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun     if (clear) {
568*4882a593Smuzhiyun         if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
569*4882a593Smuzhiyun             clearRect.x = 0;
570*4882a593Smuzhiyun             clearRect.y = 0;
571*4882a593Smuzhiyun             clearRect.width = width;
572*4882a593Smuzhiyun             clearRect.height = height;
573*4882a593Smuzhiyun         }
574*4882a593Smuzhiyun         else {
575*4882a593Smuzhiyun             clear = FALSE;
576*4882a593Smuzhiyun         }
577*4882a593Smuzhiyun     }
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun     /* Create DBE buffer pixmaps equal to size of resized window. */
580*4882a593Smuzhiyun     pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, width, height,
581*4882a593Smuzhiyun                                              pWin->drawable.depth, 0);
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun     pBackBuffer = (*pScreen->CreatePixmap) (pScreen, width, height,
584*4882a593Smuzhiyun                                             pWin->drawable.depth, 0);
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun     if (!pFrontBuffer || !pBackBuffer) {
587*4882a593Smuzhiyun         /* We failed at creating 1 or 2 of the pixmaps. */
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun         if (pFrontBuffer) {
590*4882a593Smuzhiyun             (*pScreen->DestroyPixmap) (pFrontBuffer);
591*4882a593Smuzhiyun         }
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun         if (pBackBuffer) {
594*4882a593Smuzhiyun             (*pScreen->DestroyPixmap) (pBackBuffer);
595*4882a593Smuzhiyun         }
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun         /* Destroy all buffers for this window. */
598*4882a593Smuzhiyun         while (pDbeWindowPriv) {
599*4882a593Smuzhiyun             /* DbeWindowPrivDelete() will free the window private if there no
600*4882a593Smuzhiyun              * more buffer IDs associated with this window.
601*4882a593Smuzhiyun              */
602*4882a593Smuzhiyun             FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
603*4882a593Smuzhiyun             pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
604*4882a593Smuzhiyun         }
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun         FreeScratchGC(pGC);
607*4882a593Smuzhiyun         return FALSE;
608*4882a593Smuzhiyun     }
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun     else {
611*4882a593Smuzhiyun         /* Clear out the new DBE buffer pixmaps. */
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun         /* I suppose this could avoid quite a bit of work if
614*4882a593Smuzhiyun          * it computed the minimal area required.
615*4882a593Smuzhiyun          */
616*4882a593Smuzhiyun         ValidateGC(&pFrontBuffer->drawable, pGC);
617*4882a593Smuzhiyun         if (clear) {
618*4882a593Smuzhiyun             (*pGC->ops->PolyFillRect) ((DrawablePtr) pFrontBuffer, pGC, 1,
619*4882a593Smuzhiyun                                        &clearRect);
620*4882a593Smuzhiyun         }
621*4882a593Smuzhiyun         /* Copy the contents of the old front pixmap to the new one. */
622*4882a593Smuzhiyun         if (pWin->bitGravity != ForgetGravity) {
623*4882a593Smuzhiyun             (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pFrontBuffer,
624*4882a593Smuzhiyun 				   (DrawablePtr) pFrontBuffer, pGC,
625*4882a593Smuzhiyun 				   sourcex, sourcey, savewidth, saveheight,
626*4882a593Smuzhiyun                                    destx, desty);
627*4882a593Smuzhiyun         }
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun         ValidateGC(&pBackBuffer->drawable, pGC);
630*4882a593Smuzhiyun         if (clear) {
631*4882a593Smuzhiyun             (*pGC->ops->PolyFillRect) ((DrawablePtr) pBackBuffer, pGC, 1,
632*4882a593Smuzhiyun                                        &clearRect);
633*4882a593Smuzhiyun         }
634*4882a593Smuzhiyun         /* Copy the contents of the old back pixmap to the new one. */
635*4882a593Smuzhiyun         if (pWin->bitGravity != ForgetGravity) {
636*4882a593Smuzhiyun             (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer,
637*4882a593Smuzhiyun 				   (DrawablePtr) pBackBuffer, pGC,
638*4882a593Smuzhiyun                                    sourcex, sourcey, savewidth, saveheight,
639*4882a593Smuzhiyun                                    destx, desty);
640*4882a593Smuzhiyun         }
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun         /* Destroy the old pixmaps, and point the DBE window priv to the new
643*4882a593Smuzhiyun          * pixmaps.
644*4882a593Smuzhiyun          */
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun         (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer);
647*4882a593Smuzhiyun         (*pScreen->DestroyPixmap) (pDbeWindowPriv->pBackBuffer);
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun         pDbeWindowPriv->pFrontBuffer = pFrontBuffer;
650*4882a593Smuzhiyun         pDbeWindowPriv->pBackBuffer = pBackBuffer;
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun         /* Make sure all XID are associated with the new back pixmap. */
653*4882a593Smuzhiyun         miDbeAliasBuffers(pDbeWindowPriv);
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun         FreeScratchGC(pGC);
656*4882a593Smuzhiyun     }
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun     return ret;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun }                               /* miDbePositionWindow() */
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun /******************************************************************************
663*4882a593Smuzhiyun  *
664*4882a593Smuzhiyun  * DBE MI Procedure: miDbeInit
665*4882a593Smuzhiyun  *
666*4882a593Smuzhiyun  * Description:
667*4882a593Smuzhiyun  *
668*4882a593Smuzhiyun  *     This is the MI initialization function called by DbeExtensionInit().
669*4882a593Smuzhiyun  *
670*4882a593Smuzhiyun  *****************************************************************************/
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun Bool
miDbeInit(ScreenPtr pScreen,DbeScreenPrivPtr pDbeScreenPriv)673*4882a593Smuzhiyun miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun     /* Wrap functions. */
676*4882a593Smuzhiyun     pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
677*4882a593Smuzhiyun     pScreen->PositionWindow = miDbePositionWindow;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun     /* Initialize the per-screen DBE function pointers. */
680*4882a593Smuzhiyun     pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo;
681*4882a593Smuzhiyun     pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName;
682*4882a593Smuzhiyun     pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers;
683*4882a593Smuzhiyun     pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete;
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun     return TRUE;
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun }                               /* miDbeInit() */
688