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