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