812 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			812 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
| /******************************************************************************
 | ||
|  * 
 | ||
|  * Copyright (c) 1994, 1995  Hewlett-Packard Company
 | ||
|  *
 | ||
|  * Permission is hereby granted, free of charge, to any person obtaining
 | ||
|  * a copy of this software and associated documentation files (the
 | ||
|  * "Software"), to deal in the Software without restriction, including
 | ||
|  * without limitation the rights to use, copy, modify, merge, publish,
 | ||
|  * distribute, sublicense, and/or sell copies of the Software, and to
 | ||
|  * permit persons to whom the Software is furnished to do so, subject to
 | ||
|  * the following conditions:
 | ||
|  * 
 | ||
|  * The above copyright notice and this permission notice shall be included
 | ||
|  * in all copies or substantial portions of the Software.
 | ||
|  * 
 | ||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | ||
|  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | ||
|  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | ||
|  * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
 | ||
|  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 | ||
|  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 | ||
|  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | ||
|  * 
 | ||
|  * Except as contained in this notice, the name of the Hewlett-Packard
 | ||
|  * Company shall not be used in advertising or otherwise to promote the
 | ||
|  * sale, use or other dealings in this Software without prior written
 | ||
|  * authorization from the Hewlett-Packard Company.
 | ||
|  * 
 | ||
|  *     Machine-independent DBE code
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| 
 | ||
| /* INCLUDES */
 | ||
| 
 | ||
| #define NEED_REPLIES
 | ||
| #define NEED_EVENTS
 | ||
| #ifdef HAVE_DIX_CONFIG_H
 | ||
| #include <dix-config.h>
 | ||
| #endif
 | ||
| 
 | ||
| #include <X11/X.h>
 | ||
| #include <X11/Xproto.h>
 | ||
| #include "misc.h"
 | ||
| #include "os.h"
 | ||
| #include "windowstr.h"
 | ||
| #include "scrnintstr.h"
 | ||
| #include "pixmapstr.h"
 | ||
| #include "extnsionst.h"
 | ||
| #include "dixstruct.h"
 | ||
| #include "resource.h"
 | ||
| #include "opaque.h"
 | ||
| #include "dbestruct.h"
 | ||
| #include "midbestr.h"
 | ||
| #include "regionstr.h"
 | ||
| #include "gcstruct.h"
 | ||
| #include "inputstr.h"
 | ||
| #include "midbe.h"
 | ||
| #include "xace.h"
 | ||
| 
 | ||
| #include <stdio.h>
 | ||
| 
 | ||
| static int miDbeWindowPrivPrivKeyIndex;
 | ||
| static DevPrivateKey miDbeWindowPrivPrivKey = &miDbeWindowPrivPrivKeyIndex;
 | ||
| static RESTYPE	dbeDrawableResType;
 | ||
| static RESTYPE	dbeWindowPrivResType;
 | ||
| static int dbeScreenPrivKeyIndex;
 | ||
| static DevPrivateKey dbeScreenPrivKey = &dbeScreenPrivKeyIndex;
 | ||
| static int dbeWindowPrivKeyIndex;
 | ||
| static DevPrivateKey dbeWindowPrivKey = &dbeWindowPrivKeyIndex;
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miDbeGetVisualInfo
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the MI function for the DbeGetVisualInfo request.  This function
 | ||
|  *     is called through pDbeScreenPriv->GetVisualInfo.  This function is also
 | ||
|  *     called for the DbeAllocateBackBufferName request at the extension level;
 | ||
|  *     it is called by ProcDbeAllocateBackBufferName() in dbe.c.
 | ||
|  *
 | ||
|  *     If memory allocation fails or we can not get the visual info, this
 | ||
|  *     function returns FALSE.  Otherwise, it returns TRUE for success.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static Bool
 | ||
| miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo *pScrVisInfo)
 | ||
| {
 | ||
|     register int	i, j, k;
 | ||
|     register int	count;
 | ||
|     DepthPtr		pDepth;
 | ||
|     XdbeVisualInfo	*visInfo;
 | ||
| 
 | ||
| 
 | ||
|     /* Determine number of visuals for this screen. */
 | ||
|     for (i = 0, count = 0; i < pScreen->numDepths; i++)
 | ||
|     {
 | ||
|         count += pScreen->allowedDepths[i].numVids;
 | ||
|     }
 | ||
| 
 | ||
|     /* Allocate an array of XdbeVisualInfo items. */
 | ||
|     if (!(visInfo = (XdbeVisualInfo *)xalloc(count * sizeof(XdbeVisualInfo))))
 | ||
|     {
 | ||
|         return(FALSE); /* memory alloc failure */
 | ||
|     }
 | ||
| 
 | ||
|     for (i = 0, k = 0; i < pScreen->numDepths; i++)
 | ||
|     {
 | ||
|         /* For each depth of this screen, get visual information. */
 | ||
| 
 | ||
|         pDepth = &pScreen->allowedDepths[i];
 | ||
| 
 | ||
|         for (j = 0; j < pDepth->numVids; j++)
 | ||
|         {
 | ||
|             /* For each visual for this depth of this screen, get visual ID
 | ||
|              * and visual depth.  Since this is MI code, we will always return
 | ||
|              * the same performance level for all visuals (0).  A higher
 | ||
|              * performance level value indicates higher performance.
 | ||
|              */
 | ||
|             visInfo[k].visual    = pDepth->vids[j];
 | ||
|             visInfo[k].depth     = pDepth->depth;
 | ||
|             visInfo[k].perflevel = 0;
 | ||
|             k++;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /* Record the number of visuals and point visual_depth to
 | ||
|      * the array of visual info.
 | ||
|      */
 | ||
|     pScrVisInfo->count   = count;
 | ||
|     pScrVisInfo->visinfo = visInfo;
 | ||
| 
 | ||
|     return(TRUE); /* success */
 | ||
| 
 | ||
| } /* miDbeGetVisualInfo() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miAllocBackBufferName
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the MI function for the DbeAllocateBackBufferName request.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
 | ||
| {
 | ||
|     ScreenPtr			pScreen;
 | ||
|     DbeWindowPrivPtr		pDbeWindowPriv;
 | ||
|     MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv; 
 | ||
|     DbeScreenPrivPtr		pDbeScreenPriv;
 | ||
|     GCPtr			pGC;
 | ||
|     xRectangle			clearRect;
 | ||
|     int				rc;
 | ||
| 
 | ||
| 
 | ||
|     pScreen = pWin->drawable.pScreen;
 | ||
|     pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
 | ||
| 
 | ||
|     if (pDbeWindowPriv->nBufferIDs == 0)
 | ||
|     {
 | ||
|         /* There is no buffer associated with the window.
 | ||
|          * We have to create the window priv priv.  Remember, the window
 | ||
|          * priv was created at the DIX level, so all we need to do is
 | ||
|          * create the priv priv and attach it to the priv.
 | ||
|          */
 | ||
| 
 | ||
|         pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
| 
 | ||
|         /* Setup the window priv priv. */
 | ||
|         pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
 | ||
|         pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv;
 | ||
| 
 | ||
|         /* Get a front pixmap. */
 | ||
|         if (!(pDbeWindowPrivPriv->pFrontBuffer =
 | ||
|             (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
 | ||
|                                      pDbeWindowPriv->height,
 | ||
|                                      pWin->drawable.depth, 0)))
 | ||
|         {
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
|         /* Get a back pixmap. */
 | ||
|         if (!(pDbeWindowPrivPriv->pBackBuffer =
 | ||
|             (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
 | ||
|                                      pDbeWindowPriv->height,
 | ||
|                                      pWin->drawable.depth, 0)))
 | ||
|         {
 | ||
|             (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); 
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
| 	/* Security creation/labeling check. */
 | ||
| 	rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId,
 | ||
| 		      dbeDrawableResType, pDbeWindowPrivPriv->pBackBuffer,
 | ||
| 		      RT_WINDOW, pWin, DixCreateAccess);
 | ||
| 
 | ||
|         /* Make the back pixmap a DBE drawable resource. */
 | ||
|         if (rc != Success || !AddResource(bufId, dbeDrawableResType,
 | ||
| 					  pDbeWindowPrivPriv->pBackBuffer))
 | ||
|         {
 | ||
|             /* free the buffer and the drawable resource */
 | ||
|             FreeResource(bufId, RT_NONE);
 | ||
|             return (rc == Success) ? BadAlloc : rc;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /* Attach the priv priv to the priv. */
 | ||
| 	dixSetPrivate(&pDbeWindowPriv->devPrivates, miDbeWindowPrivPrivKey,
 | ||
| 		      pDbeWindowPrivPriv);
 | ||
| 
 | ||
| 
 | ||
|         /* Clear the back buffer. */
 | ||
|         pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
 | ||
|         if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
 | ||
|         {
 | ||
|             ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
 | ||
|             clearRect.x = clearRect.y = 0;
 | ||
|             clearRect.width  = pDbeWindowPrivPriv->pBackBuffer->drawable.width;
 | ||
|             clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height;
 | ||
|             (*pGC->ops->PolyFillRect)(
 | ||
|                 (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1,
 | ||
|                 &clearRect);
 | ||
|         }
 | ||
|         FreeScratchGC(pGC);
 | ||
| 
 | ||
|     } /* if no buffer associated with the window */
 | ||
| 
 | ||
|     else
 | ||
|     {
 | ||
|         /* A buffer is already associated with the window.
 | ||
|          * Place the new buffer ID information at the head of the ID list.
 | ||
|          */
 | ||
| 
 | ||
|         /* Associate the new ID with an existing pixmap. */
 | ||
|         pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
 | ||
|         if (!AddResource(bufId, dbeDrawableResType,
 | ||
|                          (pointer)pDbeWindowPrivPriv->pBackBuffer))
 | ||
|         {
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     return(Success);
 | ||
| 
 | ||
| } /* miDbeAllocBackBufferName() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miDbeAliasBuffers
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function associates all XIDs of a buffer with the back pixmap
 | ||
|  *     stored in the window priv.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static void
 | ||
| miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
 | ||
| {
 | ||
|     int				i;
 | ||
|     MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv =
 | ||
|                                     MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
 | ||
| 
 | ||
|     for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
 | ||
|     {
 | ||
|         ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
 | ||
|                             (pointer)pDbeWindowPrivPriv->pBackBuffer);
 | ||
|     }
 | ||
| 
 | ||
| } /* miDbeAliasBuffers() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miDbeSwapBuffers
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the MI function for the DbeSwapBuffers request.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
 | ||
| {
 | ||
|     DbeScreenPrivPtr		pDbeScreenPriv;
 | ||
|     GCPtr		    	pGC;
 | ||
|     WindowPtr		    	pWin;
 | ||
|     MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv; 
 | ||
|     PixmapPtr			pTmpBuffer;
 | ||
|     xRectangle			clearRect;
 | ||
| 
 | ||
| 
 | ||
|     pWin               = swapInfo[0].pWindow;
 | ||
|     pDbeScreenPriv     = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
 | ||
|     pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin);
 | ||
|     pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
 | ||
| 
 | ||
|     /*
 | ||
|      **********************************************************************
 | ||
|      ** Setup before swap.
 | ||
|      **********************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     switch(swapInfo[0].swapAction)
 | ||
|     {
 | ||
|         case XdbeUndefined:
 | ||
|             break;
 | ||
| 
 | ||
|         case XdbeBackground:
 | ||
|             break;
 | ||
| 
 | ||
|         case XdbeUntouched:
 | ||
|             ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC);
 | ||
|             (*pGC->ops->CopyArea)((DrawablePtr)pWin,
 | ||
|                                   (DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
 | ||
|                                   pGC, 0, 0, pWin->drawable.width,
 | ||
|                                   pWin->drawable.height, 0, 0);
 | ||
|             break;
 | ||
| 
 | ||
|         case XdbeCopied:
 | ||
|             break;
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     /*
 | ||
|      **********************************************************************
 | ||
|      ** Swap.
 | ||
|      **********************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     ValidateGC((DrawablePtr)pWin, pGC);
 | ||
|     (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
 | ||
|                           (DrawablePtr)pWin, pGC, 0, 0,
 | ||
|                           pWin->drawable.width, pWin->drawable.height,
 | ||
|                           0, 0);
 | ||
| 
 | ||
|     /*
 | ||
|      **********************************************************************
 | ||
|      ** Tasks after swap.
 | ||
|      **********************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     switch(swapInfo[0].swapAction)
 | ||
|     {
 | ||
|         case XdbeUndefined:
 | ||
|             break;
 | ||
| 
 | ||
|         case XdbeBackground:
 | ||
|             if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
 | ||
|             {
 | ||
|                 ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
 | ||
|                 clearRect.x = 0;
 | ||
|                 clearRect.y = 0;
 | ||
|                 clearRect.width =
 | ||
|                     pDbeWindowPrivPriv->pBackBuffer->drawable.width;
 | ||
|                 clearRect.height =
 | ||
|                     pDbeWindowPrivPriv->pBackBuffer->drawable.height;
 | ||
|                 (*pGC->ops->PolyFillRect)(
 | ||
| 				(DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
 | ||
| 				pGC, 1, &clearRect);
 | ||
| 	    }
 | ||
|             break;
 | ||
| 
 | ||
|         case XdbeUntouched:
 | ||
|             /* Swap pixmap pointers. */
 | ||
|             pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer;
 | ||
|             pDbeWindowPrivPriv->pBackBuffer =
 | ||
|                 pDbeWindowPrivPriv->pFrontBuffer;
 | ||
|             pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer;
 | ||
| 
 | ||
|             miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv);
 | ||
| 
 | ||
|             break;
 | ||
| 
 | ||
|         case XdbeCopied:
 | ||
|             break;
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     /* Remove the swapped window from the swap information array and decrement
 | ||
|      * pNumWindows to indicate to the DIX level how many windows were actually
 | ||
|      * swapped.
 | ||
|      */
 | ||
| 
 | ||
|     if (*pNumWindows > 1)
 | ||
|     {
 | ||
|         /* We were told to swap more than one window, but we only swapped the
 | ||
|          * first one.  Remove the first window in the list by moving the last
 | ||
|          * window to the beginning.
 | ||
|          */
 | ||
|         swapInfo[0].pWindow    = swapInfo[*pNumWindows - 1].pWindow;
 | ||
|         swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
 | ||
| 
 | ||
|         /* Clear the last window information just to be safe. */
 | ||
|         swapInfo[*pNumWindows - 1].pWindow    = (WindowPtr)NULL;
 | ||
|         swapInfo[*pNumWindows - 1].swapAction = 0;
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|         /* Clear the window information just to be safe. */
 | ||
|         swapInfo[0].pWindow    = (WindowPtr)NULL;
 | ||
|         swapInfo[0].swapAction = 0;
 | ||
|     }
 | ||
| 
 | ||
|     (*pNumWindows)--;
 | ||
| 
 | ||
|     FreeScratchGC(pGC);
 | ||
| 
 | ||
|     return(Success);
 | ||
| 
 | ||
| } /* miSwapBuffers() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miDbeWinPrivDelete
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the MI function for deleting the dbeWindowPrivResType resource.
 | ||
|  *     This function is invoked indirectly by calling FreeResource() to free
 | ||
|  *     the resources associated with a DBE buffer ID.  There are 5 ways that
 | ||
|  *     miDbeWinPrivDelete() can be called by FreeResource().  They are:
 | ||
|  *
 | ||
|  *     - A DBE window is destroyed, in which case the DbeDestroyWindow()
 | ||
|  *       wrapper is invoked.  The wrapper calls FreeResource() for all DBE
 | ||
|  *       buffer IDs.
 | ||
|  *
 | ||
|  *     - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
 | ||
|  *       after a buffer allocation failure.
 | ||
|  *
 | ||
|  *     - The PositionWindow wrapper, miDbePositionWindow(), calls
 | ||
|  *       FreeResource() when it fails to create buffers of the new size.
 | ||
|  *       FreeResource() is called for all DBE buffer IDs.
 | ||
|  *
 | ||
|  *     - FreeClientResources() calls FreeResource() when a client dies or the
 | ||
|  *       the server resets.
 | ||
|  *
 | ||
|  *     When FreeResource() is called for a DBE buffer ID, the delete function
 | ||
|  *     for the only other type of DBE resource, dbeDrawableResType, is also
 | ||
|  *     invoked.  This delete function (DbeDrawableDelete) is a NOOP to make
 | ||
|  *     resource deletion easier.  It is not guaranteed which delete function is
 | ||
|  *     called first.  Hence, we will let miDbeWinPrivDelete() free all DBE
 | ||
|  *     resources.
 | ||
|  *     
 | ||
|  *     This function deletes/frees the following stuff associated with
 | ||
|  *     the window private:
 | ||
|  *
 | ||
|  *     - the ID node in the ID list representing the passed in ID.
 | ||
|  *
 | ||
|  *     In addition, pDbeWindowPriv->nBufferIDs is decremented.
 | ||
|  *
 | ||
|  *     If this function is called for the last/only buffer ID for a window,
 | ||
|  *     these are additionally deleted/freed:
 | ||
|  *
 | ||
|  *     - the front and back pixmaps
 | ||
|  *     - the window priv itself
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static void
 | ||
| miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
 | ||
| {
 | ||
|     MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv;
 | ||
| 
 | ||
| 
 | ||
|     if (pDbeWindowPriv->nBufferIDs != 0)
 | ||
|     {
 | ||
|         /* We still have at least one more buffer ID associated with this
 | ||
|          * window.
 | ||
|          */
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /* We have no more buffer IDs associated with this window.  We need to
 | ||
|      * free some stuff.
 | ||
|      */
 | ||
| 
 | ||
|     pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
 | ||
| 
 | ||
|     /* Destroy the front and back pixmaps. */
 | ||
|     if (pDbeWindowPrivPriv->pFrontBuffer)
 | ||
|     {
 | ||
|         (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
 | ||
|             pDbeWindowPrivPriv->pFrontBuffer);
 | ||
|     }
 | ||
|     if (pDbeWindowPrivPriv->pBackBuffer)
 | ||
|     {
 | ||
|         (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
 | ||
|             pDbeWindowPrivPriv->pBackBuffer);
 | ||
|     }
 | ||
| 
 | ||
| } /* miDbeWinPrivDelete() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miDbePositionWindow
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function was cloned from miMbxPositionWindow() in mimultibuf.c. 
 | ||
|  *     This function resizes the buffer when the window is resized.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static Bool
 | ||
| miDbePositionWindow(WindowPtr pWin, int x, int y)
 | ||
| {
 | ||
|     ScreenPtr			pScreen;
 | ||
|     DbeScreenPrivPtr		pDbeScreenPriv;
 | ||
|     DbeWindowPrivPtr		pDbeWindowPriv;
 | ||
|     int				width, height;
 | ||
|     int				dx, dy, dw, dh;
 | ||
|     int				sourcex, sourcey;
 | ||
|     int				destx, desty;
 | ||
|     int				savewidth, saveheight;
 | ||
|     PixmapPtr			pFrontBuffer;
 | ||
|     PixmapPtr			pBackBuffer;
 | ||
|     Bool			clear;
 | ||
|     GCPtr			pGC;
 | ||
|     xRectangle			clearRect;
 | ||
|     Bool			ret;
 | ||
| 
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 1. Unwrap the member routine.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
|      
 | ||
|     pScreen                 = pWin->drawable.pScreen;
 | ||
|     pDbeScreenPriv          = DBE_SCREEN_PRIV(pScreen);
 | ||
|     pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 2. Do any work necessary before the member routine is called.
 | ||
|      **
 | ||
|      **    In this case we do not need to do anything.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
|      
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 3. Call the member routine, saving its result if necessary.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
|      
 | ||
|     ret = (*pScreen->PositionWindow)(pWin, x, y);
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 4. Rewrap the member routine, restoring the wrapper value first in case
 | ||
|      **    the wrapper (or something that it wrapped) change this value.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
 | ||
|     pScreen->PositionWindow = miDbePositionWindow;
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 5. Do any work necessary after the member routine has been called.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
|      
 | ||
|     if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
 | ||
|     {
 | ||
| 	return(ret);
 | ||
|     }
 | ||
| 
 | ||
|     if (pDbeWindowPriv->width  == pWin->drawable.width &&
 | ||
|         pDbeWindowPriv->height == pWin->drawable.height)
 | ||
|     {
 | ||
| 	return(ret);
 | ||
|     }
 | ||
| 
 | ||
|     width  = pWin->drawable.width;
 | ||
|     height = pWin->drawable.height;
 | ||
| 
 | ||
|     dx = pWin->drawable.x - pDbeWindowPriv->x;
 | ||
|     dy = pWin->drawable.y - pDbeWindowPriv->y;
 | ||
|     dw = width  - pDbeWindowPriv->width;
 | ||
|     dh = height - pDbeWindowPriv->height;
 | ||
| 
 | ||
|     GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
 | ||
| 
 | ||
|     clear = ((pDbeWindowPriv->width  < (unsigned short)width ) ||
 | ||
|              (pDbeWindowPriv->height < (unsigned short)height) ||
 | ||
|              (pWin->bitGravity == ForgetGravity));
 | ||
| 
 | ||
|     sourcex = 0;
 | ||
|     sourcey = 0;
 | ||
|     savewidth  = pDbeWindowPriv->width;
 | ||
|     saveheight = pDbeWindowPriv->height;
 | ||
| 
 | ||
|     /* Clip rectangle to source and destination. */
 | ||
|     if (destx < 0)
 | ||
|     {
 | ||
| 	savewidth += destx;
 | ||
| 	sourcex   -= destx;
 | ||
| 	destx      = 0;
 | ||
|     }
 | ||
| 
 | ||
|     if (destx + savewidth > width)
 | ||
|     {
 | ||
| 	savewidth = width - destx;
 | ||
|     }
 | ||
| 
 | ||
|     if (desty < 0)
 | ||
|     {
 | ||
| 	saveheight += desty;
 | ||
| 	sourcey    -= desty;
 | ||
| 	desty       = 0;
 | ||
|     }
 | ||
| 
 | ||
|     if (desty + saveheight > height)
 | ||
|     {
 | ||
| 	saveheight = height - desty;
 | ||
|     }
 | ||
| 
 | ||
|     pDbeWindowPriv->width  = width;
 | ||
|     pDbeWindowPriv->height = height;
 | ||
|     pDbeWindowPriv->x = pWin->drawable.x;
 | ||
|     pDbeWindowPriv->y = pWin->drawable.y;
 | ||
| 
 | ||
|     pGC = GetScratchGC (pWin->drawable.depth, pScreen);
 | ||
| 
 | ||
|     if (clear)
 | ||
|     {
 | ||
| 	if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
 | ||
| 	{
 | ||
| 	    clearRect.x = 0;
 | ||
| 	    clearRect.y = 0;
 | ||
| 	    clearRect.width  = width;
 | ||
| 	    clearRect.height = height;
 | ||
| 	}
 | ||
| 	else
 | ||
| 	{ 
 | ||
| 	    clear = FALSE;
 | ||
| 	}
 | ||
|     }
 | ||
| 
 | ||
|     /* Create DBE buffer pixmaps equal to size of resized window. */
 | ||
|     pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
 | ||
| 					    pWin->drawable.depth, 0);
 | ||
| 
 | ||
|     pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
 | ||
| 					   pWin->drawable.depth, 0);
 | ||
| 
 | ||
|     if (!pFrontBuffer || !pBackBuffer)
 | ||
|     {
 | ||
|         /* We failed at creating 1 or 2 of the pixmaps. */
 | ||
| 
 | ||
|         if (pFrontBuffer)
 | ||
|         {
 | ||
| 	    (*pScreen->DestroyPixmap)(pFrontBuffer);
 | ||
|         }
 | ||
| 
 | ||
|         if (pBackBuffer)
 | ||
|         {
 | ||
| 	    (*pScreen->DestroyPixmap)(pBackBuffer);
 | ||
|         }
 | ||
| 
 | ||
|         /* Destroy all buffers for this window. */
 | ||
|         while (pDbeWindowPriv)
 | ||
|         {
 | ||
|             /* DbeWindowPrivDelete() will free the window private if there no
 | ||
|              * more buffer IDs associated with this window.
 | ||
|              */
 | ||
|             FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
 | ||
|             pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
 | ||
|         }
 | ||
| 
 | ||
|         FreeScratchGC(pGC);
 | ||
|         return(FALSE);
 | ||
|     }
 | ||
| 
 | ||
|     else
 | ||
|     {
 | ||
|         /* Clear out the new DBE buffer pixmaps. */
 | ||
| 
 | ||
|         MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv;
 | ||
| 
 | ||
| 
 | ||
|         pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
 | ||
|         ValidateGC((DrawablePtr)pFrontBuffer, pGC);
 | ||
| 
 | ||
| 	/* I suppose this could avoid quite a bit of work if
 | ||
| 	 * it computed the minimal area required.
 | ||
| 	 */
 | ||
| 	if (clear)
 | ||
|         {
 | ||
| 	    (*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1,
 | ||
| 				      &clearRect);
 | ||
| 	    (*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1,
 | ||
| 				      &clearRect);
 | ||
|         }
 | ||
| 
 | ||
|         /* Copy the contents of the old DBE pixmaps to the new pixmaps. */
 | ||
| 	if (pWin->bitGravity != ForgetGravity)
 | ||
| 	{
 | ||
| 	    (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
 | ||
|                                   (DrawablePtr)pFrontBuffer, pGC, sourcex,
 | ||
|                                   sourcey, savewidth, saveheight, destx, desty);
 | ||
| 	    (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
 | ||
|                                   (DrawablePtr)pBackBuffer, pGC, sourcex,
 | ||
|                                   sourcey, savewidth, saveheight, destx, desty);
 | ||
| 	}
 | ||
| 
 | ||
|         /* Destroy the old pixmaps, and point the DBE window priv to the new
 | ||
|          * pixmaps.
 | ||
|          */
 | ||
| 
 | ||
| 	(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
 | ||
| 	(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer);
 | ||
| 
 | ||
|         pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer;
 | ||
|         pDbeWindowPrivPriv->pBackBuffer  = pBackBuffer;
 | ||
| 
 | ||
| 	/* Make sure all XID are associated with the new back pixmap. */
 | ||
|         miDbeAliasBuffers(pDbeWindowPriv);
 | ||
| 
 | ||
|         FreeScratchGC(pGC);
 | ||
|     }
 | ||
| 
 | ||
|     return(ret);
 | ||
| 
 | ||
| } /* miDbePositionWindow() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miDbeResetProc
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is called from DbeResetProc(), which is called at the end
 | ||
|  *     of every server generation.  This function peforms any MI-specific
 | ||
|  *     shutdown tasks.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static void
 | ||
| miDbeResetProc(ScreenPtr pScreen)
 | ||
| {
 | ||
|     DbeScreenPrivPtr    pDbeScreenPriv;
 | ||
| 
 | ||
| 
 | ||
|     pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
| 
 | ||
|     /* Unwrap wrappers */
 | ||
|     pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
 | ||
| 
 | ||
| } /* miDbeResetProc() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE MI Procedure: miDbeInit
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the MI initialization function called by DbeExtensionInit().
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| Bool
 | ||
| miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv)
 | ||
| {
 | ||
|     /* Copy resource types created by DIX */
 | ||
|     dbeDrawableResType   = pDbeScreenPriv->dbeDrawableResType;
 | ||
|     dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType;
 | ||
| 
 | ||
|     /* Copy private indices created by DIX */
 | ||
|     dbeScreenPrivKey = pDbeScreenPriv->dbeScreenPrivKey;
 | ||
|     dbeWindowPrivKey = pDbeScreenPriv->dbeWindowPrivKey;
 | ||
| 
 | ||
|     if (!dixRequestPrivate(miDbeWindowPrivPrivKey,
 | ||
| 			   sizeof(MiDbeWindowPrivPrivRec)))
 | ||
|         return(FALSE);
 | ||
| 
 | ||
|     /* Wrap functions. */
 | ||
|     pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
 | ||
|     pScreen->PositionWindow        = miDbePositionWindow;
 | ||
| 
 | ||
|     /* Initialize the per-screen DBE function pointers. */
 | ||
|     pDbeScreenPriv->GetVisualInfo         = miDbeGetVisualInfo;
 | ||
|     pDbeScreenPriv->AllocBackBufferName   = miDbeAllocBackBufferName;
 | ||
|     pDbeScreenPriv->SwapBuffers           = miDbeSwapBuffers;
 | ||
|     pDbeScreenPriv->BeginIdiom            = 0;
 | ||
|     pDbeScreenPriv->EndIdiom              = 0;
 | ||
|     pDbeScreenPriv->ResetProc             = miDbeResetProc;
 | ||
|     pDbeScreenPriv->WinPrivDelete         = miDbeWinPrivDelete;
 | ||
| 
 | ||
|     return(TRUE);
 | ||
| 
 | ||
| } /* miDbeInit() */
 |