1928 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1928 lines
		
	
	
		
			54 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.
 | ||
|  * 
 | ||
|  *     DIX DBE code
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| 
 | ||
| /* INCLUDES */
 | ||
| 
 | ||
| #define NEED_EVENTS
 | ||
| #ifdef HAVE_DIX_CONFIG_H
 | ||
| #include <dix-config.h>
 | ||
| #endif
 | ||
| 
 | ||
| #include <string.h>
 | ||
| #if HAVE_STDINT_H
 | ||
| #include <stdint.h>
 | ||
| #elif !defined(UINT32_MAX)
 | ||
| #define UINT32_MAX 0xffffffffU
 | ||
| #endif
 | ||
| 
 | ||
| #include <X11/X.h>
 | ||
| #include <X11/Xproto.h>
 | ||
| #include "scrnintstr.h"
 | ||
| #include "extnsionst.h"
 | ||
| #include "gcstruct.h"
 | ||
| #include "dixstruct.h"
 | ||
| #define NEED_DBE_PROTOCOL
 | ||
| #include "dbestruct.h"
 | ||
| #include "midbe.h"
 | ||
| 
 | ||
| /* GLOBALS */
 | ||
| 
 | ||
| /* Per-screen initialization functions [init'ed by DbeRegisterFunction()] */
 | ||
| static Bool	(* DbeInitFunct[MAXSCREENS])();	/* pScreen, pDbeScreenPriv */
 | ||
| 
 | ||
| /* These are static globals copied to DBE's screen private for use by DDX */
 | ||
| static int	dbeScreenPrivIndex;
 | ||
| static int	dbeWindowPrivIndex;
 | ||
| 
 | ||
| /* These are static globals copied to DBE's screen private for use by DDX */
 | ||
| static RESTYPE	dbeDrawableResType;
 | ||
| static RESTYPE	dbeWindowPrivResType;
 | ||
| 
 | ||
| /* This global is used by DbeAllocWinPrivPrivIndex() */
 | ||
| static int	winPrivPrivCount = 0;
 | ||
| 
 | ||
| /* Used to generate DBE's BadBuffer error. */
 | ||
| static int	dbeErrorBase;
 | ||
| 
 | ||
| /* Used by DbeRegisterFunction() to initialize the initialization function
 | ||
|  * table only once per server lifetime.
 | ||
|  */
 | ||
| static Bool	firstRegistrationPass = TRUE;
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeRegisterFunction
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function registers the DBE init function for the specified screen.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| void
 | ||
| DbeRegisterFunction(ScreenPtr pScreen, Bool (*funct) (/* ??? */))
 | ||
| {
 | ||
|     int	i;
 | ||
| 
 | ||
|     /* Initialize the initialization function table if it has not been
 | ||
|      * initialized already.
 | ||
|      */
 | ||
|     if (firstRegistrationPass)
 | ||
|     {
 | ||
|         for (i = 0; i < MAXSCREENS; i++)
 | ||
|         {
 | ||
|             DbeInitFunct[i] = NULL;
 | ||
|         }
 | ||
| 
 | ||
|         firstRegistrationPass = FALSE;
 | ||
|     }
 | ||
| 
 | ||
|     DbeInitFunct[pScreen->myNum] = funct;
 | ||
| 
 | ||
| } /* DbeRegisterFunction() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeAllocWinPriv
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function was cloned from AllocateWindow() in window.c.
 | ||
|  *     This function allocates a window priv structure to be associated 
 | ||
|  *     with a double-buffered window.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| static DbeWindowPrivPtr
 | ||
| DbeAllocWinPriv(ScreenPtr pScreen)
 | ||
| {
 | ||
|     DbeWindowPrivPtr		pDbeWindowPriv;
 | ||
|     DbeScreenPrivPtr		pDbeScreenPriv;
 | ||
|     register char		*ptr;
 | ||
|     register DevUnion		*ppriv;
 | ||
|     register unsigned int	*sizes;
 | ||
|     register unsigned int	size;
 | ||
|     register int		i;
 | ||
| 
 | ||
|     pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
|     pDbeWindowPriv = (DbeWindowPrivPtr)xalloc(pDbeScreenPriv->totalWinPrivSize);
 | ||
| 
 | ||
|     if (pDbeWindowPriv)
 | ||
|     {
 | ||
|         ppriv = (DevUnion *)(pDbeWindowPriv + 1);
 | ||
|         pDbeWindowPriv->devPrivates = ppriv;
 | ||
|         sizes = pDbeScreenPriv->winPrivPrivSizes;
 | ||
|         ptr = (char *)(ppriv + pDbeScreenPriv->winPrivPrivLen);
 | ||
|         for (i = pDbeScreenPriv->winPrivPrivLen; --i >= 0; ppriv++, sizes++)
 | ||
|         {
 | ||
|             if ((size = *sizes))
 | ||
|             {
 | ||
|                 ppriv->ptr = (pointer)ptr;
 | ||
|                 ptr += size;
 | ||
|             }
 | ||
|             else
 | ||
|                 ppriv->ptr = (pointer)NULL;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     return(pDbeWindowPriv);
 | ||
| 
 | ||
| } /* DbeAllocWinPriv() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeFallbackAllocWinPriv
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is a fallback function for AllocWinPriv().
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| #if 0 /* NOT USED */
 | ||
| static DbeWindowPrivPtr
 | ||
| DbeFallbackAllocWinPriv(pScreen)
 | ||
|     ScreenPtr	pScreen;
 | ||
| {
 | ||
|     return (NULL);
 | ||
| } /* DbeFallbackAllocWinPriv() */
 | ||
| #endif
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeAllocWinPrivPrivIndex
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function was cloned from AllocateWindowPrivateIndex() in window.c.
 | ||
|  *     This function allocates a new window priv priv index by simply returning
 | ||
|  *     an incremented private counter.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| DbeAllocWinPrivPrivIndex(void)
 | ||
| {
 | ||
|     return winPrivPrivCount++;
 | ||
| 
 | ||
| } /* DbeAllocWinPrivPrivIndex() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeAllocWinPrivPriv
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function was cloned from AllocateWindowPrivate() in privates.c.
 | ||
|  *     This function allocates a private structure to be hung off
 | ||
|  *     a window private.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static Bool
 | ||
| DbeAllocWinPrivPriv(register ScreenPtr pScreen, int index, unsigned int amount)
 | ||
| {
 | ||
|     DbeScreenPrivPtr	pDbeScreenPriv;
 | ||
|     unsigned int	oldamount;
 | ||
| 
 | ||
| 
 | ||
|     pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
| 
 | ||
|     if (index >= pDbeScreenPriv->winPrivPrivLen)
 | ||
|     {
 | ||
| 	unsigned *nsizes;
 | ||
| 	nsizes = (unsigned *)xrealloc(pDbeScreenPriv->winPrivPrivSizes,
 | ||
| 				      (index + 1) * sizeof(unsigned));
 | ||
| 	if (!nsizes)
 | ||
|         {
 | ||
| 	    return(FALSE);
 | ||
|         }
 | ||
| 
 | ||
| 	while (pDbeScreenPriv->winPrivPrivLen <= index)
 | ||
| 	{
 | ||
| 	    nsizes[pDbeScreenPriv->winPrivPrivLen++] = 0;
 | ||
| 	    pDbeScreenPriv->totalWinPrivSize += sizeof(DevUnion);
 | ||
| 	}
 | ||
| 
 | ||
| 	pDbeScreenPriv->winPrivPrivSizes = nsizes;
 | ||
|     }
 | ||
| 
 | ||
|     oldamount = pDbeScreenPriv->winPrivPrivSizes[index];
 | ||
| 
 | ||
|     if (amount > oldamount)
 | ||
|     {
 | ||
| 	pDbeScreenPriv->winPrivPrivSizes[index] = amount;
 | ||
| 	pDbeScreenPriv->totalWinPrivSize += (amount - oldamount);
 | ||
|     }
 | ||
|     return(TRUE);
 | ||
| 
 | ||
| } /* DbeAllocWinPrivPriv() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeStubScreen
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is function stubs the function pointers in the given DBE screen
 | ||
|  *     private and increments the number of stubbed screens.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static void
 | ||
| DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
 | ||
| {
 | ||
|     /* Stub DIX. */
 | ||
|     pDbeScreenPriv->SetupBackgroundPainter = NULL;
 | ||
|     pDbeScreenPriv->AllocWinPriv           = NULL;
 | ||
|     pDbeScreenPriv->AllocWinPrivPrivIndex  = NULL;
 | ||
|     pDbeScreenPriv->AllocWinPrivPriv       = NULL;
 | ||
| 
 | ||
|     /* Do not unwrap PositionWindow nor DestroyWindow.  If the DDX
 | ||
|      * initialization function failed, we assume that it did not wrap
 | ||
|      * PositionWindow.  Also, DestroyWindow is only wrapped if the DDX
 | ||
|      * initialization function succeeded.
 | ||
|      */
 | ||
| 
 | ||
|     /* Stub DDX. */
 | ||
|     pDbeScreenPriv->GetVisualInfo       = NULL;
 | ||
|     pDbeScreenPriv->AllocBackBufferName = NULL;
 | ||
|     pDbeScreenPriv->SwapBuffers         = NULL;
 | ||
|     pDbeScreenPriv->BeginIdiom          = NULL;
 | ||
|     pDbeScreenPriv->EndIdiom            = NULL;
 | ||
|     pDbeScreenPriv->WinPrivDelete       = NULL;
 | ||
|     pDbeScreenPriv->ResetProc           = NULL;
 | ||
| 
 | ||
|     (*nStubbedScreens)++;
 | ||
| 
 | ||
| } /* DbeStubScreen() */
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeGetVersion
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeGetVersion request.
 | ||
|  *     This request returns the major and minor version numbers of this
 | ||
|  *     extension.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeGetVersion(ClientPtr client)
 | ||
| {
 | ||
|     /* REQUEST(xDbeGetVersionReq); */
 | ||
|     xDbeGetVersionReply	rep;
 | ||
|     register int	n;
 | ||
| 
 | ||
| 
 | ||
|     REQUEST_SIZE_MATCH(xDbeGetVersionReq);
 | ||
| 
 | ||
|     rep.type           = X_Reply;
 | ||
|     rep.length         = 0;
 | ||
|     rep.sequenceNumber = client->sequence;
 | ||
|     rep.majorVersion   = DBE_MAJOR_VERSION;
 | ||
|     rep.minorVersion   = DBE_MINOR_VERSION;
 | ||
| 
 | ||
|     if (client->swapped)
 | ||
|     {
 | ||
|         swaps(&rep.sequenceNumber, n);
 | ||
|     }
 | ||
| 
 | ||
|     WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep);
 | ||
| 
 | ||
|     return(client->noClientException);
 | ||
| 
 | ||
| } /* ProcDbeGetVersion() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeAllocateBackBufferName
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeAllocateBackBufferName request.
 | ||
|  *     This request allocates a drawable ID used to refer to the back buffer
 | ||
|  *     of a window.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadAlloc    - server can not allocate resources
 | ||
|  *     BadIDChoice - id is out of range for client; id is already in use
 | ||
|  *     BadMatch    - window is not an InputOutput window;
 | ||
|  *                   visual of window is not on list returned by
 | ||
|  *                   DBEGetVisualInfo; 
 | ||
|  *     BadValue    - invalid swap action is specified
 | ||
|  *     BadWindow   - window is not a valid window
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeAllocateBackBufferName(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeAllocateBackBufferNameReq);
 | ||
|     WindowPtr			pWin;
 | ||
|     DbeScreenPrivPtr		pDbeScreenPriv;
 | ||
|     DbeWindowPrivPtr		pDbeWindowPriv;
 | ||
|     XdbeScreenVisualInfo	scrVisInfo;
 | ||
|     register int		i;
 | ||
|     Bool			visualMatched = FALSE;
 | ||
|     xDbeSwapAction		swapAction;
 | ||
|     VisualID			visual;
 | ||
|     int				status;
 | ||
| 
 | ||
| 
 | ||
|     REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
 | ||
| 
 | ||
|     /* The window must be valid. */
 | ||
|     status = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
 | ||
|     if (status != Success)
 | ||
| 	return status;
 | ||
| 
 | ||
|     /* The window must be InputOutput. */
 | ||
|     if (pWin->drawable.class != InputOutput)
 | ||
|     {
 | ||
| 	return(BadMatch);
 | ||
|     }
 | ||
| 
 | ||
|     /* The swap action must be valid. */
 | ||
|     swapAction = stuff->swapAction;	/* use local var for performance. */
 | ||
|     if ((swapAction != XdbeUndefined ) &&
 | ||
|         (swapAction != XdbeBackground) &&
 | ||
|         (swapAction != XdbeUntouched ) &&
 | ||
|         (swapAction != XdbeCopied    ))
 | ||
|     {
 | ||
|         return(BadValue);
 | ||
|     }
 | ||
| 
 | ||
|     /* The id must be in range and not already in use. */
 | ||
|     LEGAL_NEW_RESOURCE(stuff->buffer, client);
 | ||
| 
 | ||
|     /* The visual of the window must be in the list returned by
 | ||
|      * GetVisualInfo.
 | ||
|      */
 | ||
|     pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
 | ||
|     if (!pDbeScreenPriv->GetVisualInfo)
 | ||
| 	return(BadMatch); /* screen doesn't support double buffering */
 | ||
| 
 | ||
|     if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
 | ||
|     {
 | ||
|         /* GetVisualInfo() failed to allocate visual info data. */
 | ||
|         return(BadAlloc);
 | ||
|     }
 | ||
| 
 | ||
|     /* See if the window's visual is on the list. */
 | ||
|     visual = wVisual(pWin);
 | ||
|     for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++)
 | ||
|     {
 | ||
|         if (scrVisInfo.visinfo[i].visual == visual)
 | ||
| 	{
 | ||
| 	    visualMatched = TRUE;
 | ||
| 	}
 | ||
|     }
 | ||
| 
 | ||
|     /* Free what was allocated by the GetVisualInfo() call above. */
 | ||
|     xfree(scrVisInfo.visinfo);
 | ||
| 
 | ||
|     if (!visualMatched)
 | ||
|     {
 | ||
| 	return(BadMatch);
 | ||
|     }
 | ||
| 
 | ||
|     if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
 | ||
|     {
 | ||
|         /* There is no buffer associated with the window.
 | ||
|          * Allocate a window priv.
 | ||
|          */
 | ||
| 
 | ||
|         if (!(pDbeWindowPriv =
 | ||
|             (*pDbeScreenPriv->AllocWinPriv)(pWin->drawable.pScreen)))
 | ||
|         {
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
|         /* Make the window priv a DBE window priv resource. */
 | ||
|         if (!AddResource(stuff->buffer, dbeWindowPrivResType,
 | ||
|             (pointer)pDbeWindowPriv))
 | ||
|         {
 | ||
|             xfree(pDbeWindowPriv);
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
|         /* Fill out window priv information. */
 | ||
|         pDbeWindowPriv->pWindow      = pWin;
 | ||
|         pDbeWindowPriv->width        = pWin->drawable.width;
 | ||
|         pDbeWindowPriv->height       = pWin->drawable.height;
 | ||
|         pDbeWindowPriv->x            = pWin->drawable.x;
 | ||
|         pDbeWindowPriv->y            = pWin->drawable.y;
 | ||
|         pDbeWindowPriv->nBufferIDs   = 0;
 | ||
| 
 | ||
|         /* Set the buffer ID array pointer to the initial (static) array). */
 | ||
|         pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
 | ||
| 
 | ||
|         /* Initialize the buffer ID list. */ 
 | ||
|         pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
 | ||
|         pDbeWindowPriv->IDs[0] = stuff->buffer;
 | ||
|         for (i = 1; i < DBE_INIT_MAX_IDS; i++)
 | ||
|         {
 | ||
|             pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /* Actually connect the window priv to the window. */
 | ||
|         pWin->devPrivates[dbeWindowPrivIndex].ptr = (pointer)pDbeWindowPriv;
 | ||
| 
 | ||
|     } /* if -- There is no buffer associated with the window. */
 | ||
| 
 | ||
|     else
 | ||
|     {
 | ||
|         /* A buffer is already associated with the window.
 | ||
|          * Add the new buffer ID to the array, reallocating the array memory
 | ||
|          * if necessary.
 | ||
|          */
 | ||
| 
 | ||
|         /* Determine if there is a free element in the ID array. */
 | ||
|         for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++)
 | ||
|         {
 | ||
|             if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT)
 | ||
|             {
 | ||
|                 /* There is still room in the ID array. */
 | ||
|                 break;
 | ||
|             }
 | ||
|         }
 | ||
|  
 | ||
|         if (i == pDbeWindowPriv->maxAvailableIDs)
 | ||
|         {
 | ||
|             /* No more room in the ID array -- reallocate another array. */
 | ||
|             XID	*pIDs;
 | ||
| 
 | ||
| 
 | ||
|             /* Setup an array pointer for the realloc operation below. */
 | ||
|             if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
 | ||
|             {
 | ||
|                 /* We will malloc a new array. */
 | ||
|                 pIDs = NULL;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 /* We will realloc a new array. */
 | ||
|                 pIDs = pDbeWindowPriv->IDs;
 | ||
|             }
 | ||
| 
 | ||
|             /* malloc/realloc a new array and initialize all elements to 0. */
 | ||
|             pDbeWindowPriv->IDs = (XID *)xrealloc(pIDs,
 | ||
|                 (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID));
 | ||
|             if (!pDbeWindowPriv->IDs)
 | ||
|             {
 | ||
|                 return(BadAlloc);
 | ||
|             }
 | ||
|             memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
 | ||
|                    (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
 | ||
|                     pDbeWindowPriv->nBufferIDs) * sizeof(XID));
 | ||
| 
 | ||
|             if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
 | ||
|             {
 | ||
|                 /* We just went from using the initial (static) array to a
 | ||
|                  * newly allocated array.  Copy the IDs from the initial array
 | ||
|                  * to the new array.
 | ||
|                  */
 | ||
|                 memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
 | ||
|                        DBE_INIT_MAX_IDS * sizeof(XID));
 | ||
|             }
 | ||
| 
 | ||
|             pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
 | ||
|         }
 | ||
| 
 | ||
|         /* Finally, record the buffer ID in the array. */
 | ||
|         pDbeWindowPriv->IDs[i] = stuff->buffer;
 | ||
| 
 | ||
|         /* Associate the new ID with an existing window priv. */
 | ||
|         if (!AddResource(stuff->buffer, dbeWindowPrivResType,
 | ||
|                          (pointer)pDbeWindowPriv))
 | ||
|         {
 | ||
|             pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
|     } /* else -- A buffer is already associated with the window. */
 | ||
| 
 | ||
| 
 | ||
|     /* Call the DDX routine to allocate the back buffer. */
 | ||
|     status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
 | ||
|                                                     stuff->swapAction);
 | ||
| 
 | ||
|     if ((status != Success) && (pDbeWindowPriv->nBufferIDs == 0))
 | ||
|     {
 | ||
|         /* The DDX buffer allocation routine failed for the first buffer of
 | ||
|          * this window.
 | ||
|          */
 | ||
|         xfree(pDbeWindowPriv);
 | ||
|         return(status);
 | ||
|     }
 | ||
| 
 | ||
|     /* Increment the number of buffers (XIDs) associated with this window. */
 | ||
|     pDbeWindowPriv->nBufferIDs++;
 | ||
| 
 | ||
|     /* Set swap action on all calls. */
 | ||
|     pDbeWindowPriv->swapAction = stuff->swapAction;
 | ||
| 
 | ||
| 
 | ||
|     return(status);
 | ||
| 
 | ||
| } /* ProcDbeAllocateBackBufferName() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeDeallocateBackBufferName request.
 | ||
|  *     This request frees a drawable ID that was obtained by a
 | ||
|  *     DbeAllocateBackBufferName request.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadBuffer - buffer to deallocate is not associated with a window
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeDeallocateBackBufferName(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeDeallocateBackBufferNameReq);
 | ||
|     DbeWindowPrivPtr	pDbeWindowPriv;
 | ||
|     int			i;
 | ||
| 
 | ||
| 
 | ||
|     REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
 | ||
| 
 | ||
|     /* Buffer name must be valid */
 | ||
|     if (!(pDbeWindowPriv = (DbeWindowPrivPtr)SecurityLookupIDByType(client,
 | ||
| 		stuff->buffer, dbeWindowPrivResType, DixDestroyAccess)) ||
 | ||
|         !(SecurityLookupIDByType(client, stuff->buffer, dbeDrawableResType,
 | ||
| 				 DixDestroyAccess)))
 | ||
|     {
 | ||
|         client->errorValue = stuff->buffer;
 | ||
|         return(dbeErrorBase + DbeBadBuffer);
 | ||
|     }
 | ||
| 
 | ||
|     /* Make sure that the id is valid for the window.
 | ||
|      * This is paranoid code since we already looked up the ID by type
 | ||
|      * above.
 | ||
|      */
 | ||
| 
 | ||
|     for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
 | ||
|     {
 | ||
|         /* Loop through the ID list to find the ID. */
 | ||
|         if (pDbeWindowPriv->IDs[i] == stuff->buffer)
 | ||
|         {
 | ||
|             break;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     if (i == pDbeWindowPriv->nBufferIDs)
 | ||
|     {
 | ||
|         /* We did not find the ID in the ID list. */
 | ||
|         client->errorValue = stuff->buffer;
 | ||
|         return(dbeErrorBase + DbeBadBuffer);
 | ||
|     }
 | ||
| 
 | ||
|     FreeResource(stuff->buffer, RT_NONE);
 | ||
| 
 | ||
|     return(Success);
 | ||
| 
 | ||
| } /* ProcDbeDeallocateBackBufferName() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeSwapBuffers
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeSwapBuffers request.
 | ||
|  *     This request swaps the buffers for all windows listed, applying the
 | ||
|  *     appropriate swap action for each window.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadAlloc  - local allocation failed; this return value is not defined
 | ||
|  *                 by the protocol
 | ||
|  *     BadMatch  - a window in request is not double-buffered; a window in
 | ||
|  *                 request is listed more than once
 | ||
|  *     BadValue  - invalid swap action is specified; no swap action is
 | ||
|  *                 specified
 | ||
|  *     BadWindow - a window in request is not valid
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeSwapBuffers(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeSwapBuffersReq);
 | ||
|     WindowPtr		pWin;
 | ||
|     DbeScreenPrivPtr	pDbeScreenPriv;
 | ||
|     DbeSwapInfoPtr	swapInfo;
 | ||
|     xDbeSwapInfo	*dbeSwapInfo;
 | ||
|     int			error;
 | ||
|     register int	i, j;
 | ||
|     int			nStuff;
 | ||
| 
 | ||
| 
 | ||
|     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
 | ||
|     nStuff = stuff->n;	/* use local variable for performance. */
 | ||
| 
 | ||
|     if (nStuff == 0)
 | ||
|     {
 | ||
|         return(Success);
 | ||
|     }
 | ||
| 
 | ||
|     if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
 | ||
| 	    return BadAlloc;
 | ||
| 
 | ||
|     /* Get to the swap info appended to the end of the request. */
 | ||
|     dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
 | ||
| 
 | ||
|     /* Allocate array to record swap information. */ 
 | ||
|     swapInfo = (DbeSwapInfoPtr)Xalloc(nStuff * sizeof(DbeSwapInfoRec));
 | ||
|     if (swapInfo == NULL)
 | ||
|     {
 | ||
|         return(BadAlloc);
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     for (i = 0; i < nStuff; i++)
 | ||
|     {
 | ||
|         /* Check all windows to swap. */
 | ||
| 
 | ||
|         /* Each window must be a valid window - BadWindow. */
 | ||
| 	error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
 | ||
| 				DixWriteAccess);
 | ||
| 	if (error != Success) {
 | ||
|             Xfree(swapInfo);
 | ||
| 	    return error;
 | ||
|         }
 | ||
| 
 | ||
|         /* Each window must be double-buffered - BadMatch. */
 | ||
|         if (DBE_WINDOW_PRIV(pWin) == NULL)
 | ||
|         {
 | ||
|             Xfree(swapInfo);
 | ||
|             return(BadMatch);
 | ||
|         }
 | ||
| 
 | ||
|         /* Each window must only be specified once - BadMatch. */
 | ||
|         for (j = i + 1; j < nStuff; j++)
 | ||
|         {
 | ||
|             if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
 | ||
|             {
 | ||
|                 Xfree(swapInfo);
 | ||
|                 return(BadMatch);
 | ||
| 	    }
 | ||
|         }
 | ||
| 
 | ||
|         /* Each swap action must be valid - BadValue. */
 | ||
|         if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) &&
 | ||
|             (dbeSwapInfo[i].swapAction != XdbeBackground) &&
 | ||
|             (dbeSwapInfo[i].swapAction != XdbeUntouched ) &&
 | ||
|             (dbeSwapInfo[i].swapAction != XdbeCopied    ))
 | ||
|         {
 | ||
|             Xfree(swapInfo);
 | ||
|             return(BadValue);
 | ||
|         }
 | ||
| 
 | ||
|         /* Everything checks out OK.  Fill in the swap info array. */
 | ||
|         swapInfo[i].pWindow    = pWin;     
 | ||
|         swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;     
 | ||
| 
 | ||
|     } /* for (i = 0; i < nStuff; i++) */
 | ||
| 
 | ||
| 
 | ||
|     /* Call the DDX routine to perform the swap(s).  The DDX routine should
 | ||
|      * scan the swap list (swap info), swap any buffers that it knows how to
 | ||
|      * handle, delete them from the list, and update nStuff to indicate how
 | ||
|      * many windows it did not handle.
 | ||
|      *
 | ||
|      * This scheme allows a range of sophistication in the DDX SwapBuffers()
 | ||
|      * implementation.  Naive implementations could just swap the first buffer
 | ||
|      * in the list, move the last buffer to the front, decrement nStuff, and
 | ||
|      * return.  The next level of sophistication could be to scan the whole
 | ||
|      * list for windows on the same screen.  Up another level, the DDX routine
 | ||
|      * could deal with cross-screen synchronization.
 | ||
|      */
 | ||
| 
 | ||
|     while (nStuff > 0)
 | ||
|     {
 | ||
|         pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
 | ||
|         error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo);
 | ||
|         if (error != Success)
 | ||
|         {
 | ||
|             Xfree(swapInfo);
 | ||
|             return(error);
 | ||
|         }
 | ||
|     }
 | ||
|     
 | ||
|     Xfree(swapInfo);
 | ||
|     return(Success);
 | ||
| 
 | ||
| } /* ProcDbeSwapBuffers() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeBeginIdiom
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeBeginIdiom request.
 | ||
|  *     This request informs the server that a complex swap will immediately
 | ||
|  *     follow this request.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeBeginIdiom(ClientPtr client)
 | ||
| {
 | ||
|     /* REQUEST(xDbeBeginIdiomReq); */
 | ||
|     DbeScreenPrivPtr	pDbeScreenPriv;
 | ||
|     register int	i;
 | ||
| 
 | ||
| 
 | ||
|     REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
 | ||
| 
 | ||
|     for (i = 0; i < screenInfo.numScreens; i++)
 | ||
|     {
 | ||
|         pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
 | ||
| 
 | ||
|         /* Call the DDX begin idiom procedure if there is one. */
 | ||
|         if (pDbeScreenPriv->BeginIdiom)
 | ||
|         {
 | ||
|            (*pDbeScreenPriv->BeginIdiom)(client);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     return(Success);
 | ||
| 
 | ||
| } /* ProcDbeBeginIdiom() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeGetVisualInfo
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a ProcDbeGetVisualInfo request.
 | ||
|  *     This request returns information about which visuals support
 | ||
|  *     double buffering.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadDrawable - value in screen specifiers is not a valid drawable
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeGetVisualInfo(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeGetVisualInfoReq);
 | ||
|     DbeScreenPrivPtr		pDbeScreenPriv;
 | ||
|     xDbeGetVisualInfoReply	rep;
 | ||
|     Drawable			*drawables;
 | ||
|     DrawablePtr			*pDrawables = NULL;
 | ||
|     register int		i, j, n, rc;
 | ||
|     register int		count;  /* number of visual infos in reply */
 | ||
|     register int		length; /* length of reply */
 | ||
|     ScreenPtr			pScreen;
 | ||
|     XdbeScreenVisualInfo	*pScrVisInfo;
 | ||
| 
 | ||
| 
 | ||
|     REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
 | ||
| 
 | ||
|     if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
 | ||
| 	    return BadAlloc;
 | ||
|     /* Make sure any specified drawables are valid. */
 | ||
|     if (stuff->n != 0)
 | ||
|     {
 | ||
|         if (!(pDrawables = (DrawablePtr *)Xalloc(stuff->n *
 | ||
|                                                  sizeof(DrawablePtr))))
 | ||
|         {
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
|         drawables = (Drawable *)&stuff[1];
 | ||
| 
 | ||
|         for (i = 0; i < stuff->n; i++)
 | ||
|         {
 | ||
| 	    rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0,
 | ||
| 				   DixReadAccess);
 | ||
| 	    if (rc != Success) {
 | ||
|                 Xfree(pDrawables);
 | ||
|                 return rc;
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
 | ||
|     if (!(pScrVisInfo = (XdbeScreenVisualInfo *)xalloc(count *
 | ||
|                         sizeof(XdbeScreenVisualInfo))))
 | ||
|     {
 | ||
|         if (pDrawables)
 | ||
|         {
 | ||
|             Xfree(pDrawables);
 | ||
|         }
 | ||
| 
 | ||
|         return(BadAlloc);
 | ||
|     }
 | ||
| 
 | ||
|     length = 0;
 | ||
| 
 | ||
|     for (i = 0; i < count; i++)
 | ||
|     {
 | ||
|         pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
 | ||
|                                     pDrawables[i]->pScreen;
 | ||
|         pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
| 
 | ||
|         if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
 | ||
|         {
 | ||
|             /* We failed to alloc pScrVisInfo[i].visinfo. */
 | ||
| 
 | ||
|             /* Free visinfos that we allocated for previous screen infos.*/
 | ||
|             for (j = 0; j < i; j++)
 | ||
|             {
 | ||
|                 xfree(pScrVisInfo[j].visinfo);
 | ||
|             }
 | ||
| 
 | ||
|             /* Free pDrawables if we needed to allocate it above. */
 | ||
|             if (pDrawables)
 | ||
|             {
 | ||
|                 Xfree(pDrawables);
 | ||
|             }
 | ||
| 
 | ||
|             return(BadAlloc);
 | ||
|         }
 | ||
| 
 | ||
|         /* Account for n, number of xDbeVisInfo items in list. */
 | ||
|         length += sizeof(CARD32);
 | ||
| 
 | ||
|         /* Account for n xDbeVisInfo items */
 | ||
|         length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
 | ||
|     }
 | ||
| 
 | ||
|     rep.type           = X_Reply;
 | ||
|     rep.sequenceNumber = client->sequence;
 | ||
|     rep.length         = length >> 2;
 | ||
|     rep.m              = count;
 | ||
| 
 | ||
|     if (client->swapped)
 | ||
|     {
 | ||
|         swaps(&rep.sequenceNumber, n);
 | ||
|         swapl(&rep.length, n);
 | ||
|         swapl(&rep.m, n);
 | ||
|     }
 | ||
| 
 | ||
|     /* Send off reply. */
 | ||
|     WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep);
 | ||
| 
 | ||
|     for (i = 0; i < count; i++)
 | ||
|     {
 | ||
|         CARD32	data32;
 | ||
| 
 | ||
|         /* For each screen in the reply, send off the visual info */
 | ||
| 
 | ||
|         /* Send off number of visuals. */
 | ||
|         data32 = (CARD32)pScrVisInfo[i].count;
 | ||
| 
 | ||
|         if (client->swapped)
 | ||
|         {
 | ||
|             swapl(&data32, n);
 | ||
|         }
 | ||
| 
 | ||
|         WriteToClient(client, sizeof(CARD32), (char *)&data32);
 | ||
| 
 | ||
|         /* Now send off visual info items. */
 | ||
|         for (j = 0; j < pScrVisInfo[i].count; j++)
 | ||
|         {
 | ||
|             xDbeVisInfo		visInfo;
 | ||
| 
 | ||
|             /* Copy the data in the client data structure to a protocol
 | ||
|              * data structure.  We will send data to the client from the
 | ||
|              * protocol data structure.
 | ||
|              */
 | ||
| 
 | ||
|             visInfo.visualID  = (CARD32)pScrVisInfo[i].visinfo[j].visual;
 | ||
|             visInfo.depth     = (CARD8) pScrVisInfo[i].visinfo[j].depth;
 | ||
|             visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
 | ||
| 
 | ||
|             if (client->swapped)
 | ||
|             {
 | ||
|                 swapl(&visInfo.visualID, n);
 | ||
| 
 | ||
|                 /* We do not need to swap depth and perfLevel since they are
 | ||
|                  * already 1 byte quantities.
 | ||
|                  */
 | ||
|             }
 | ||
| 
 | ||
|             /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
 | ||
|             WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /* Clean up memory. */
 | ||
|     for (i = 0; i < count; i++)
 | ||
|     {
 | ||
|         xfree(pScrVisInfo[i].visinfo);
 | ||
|     }
 | ||
|     xfree(pScrVisInfo);
 | ||
| 
 | ||
|     if (pDrawables)
 | ||
|     {
 | ||
|         Xfree(pDrawables);
 | ||
|     }
 | ||
| 
 | ||
|     return(client->noClientException);
 | ||
| 
 | ||
| } /* ProcDbeGetVisualInfo() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a ProcDbeGetbackBufferAttributes
 | ||
|  *     request.  This request returns information about a back buffer.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeGetBackBufferAttributes(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeGetBackBufferAttributesReq);
 | ||
|     xDbeGetBackBufferAttributesReply	rep;
 | ||
|     DbeWindowPrivPtr			pDbeWindowPriv;
 | ||
|     int					n;
 | ||
| 
 | ||
| 
 | ||
|     REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
 | ||
| 
 | ||
|     if (!(pDbeWindowPriv = (DbeWindowPrivPtr)SecurityLookupIDByType(client,
 | ||
| 		stuff->buffer, dbeWindowPrivResType, DixReadAccess)))
 | ||
|     {
 | ||
|         rep.attributes = None;
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|         rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
 | ||
|     }
 | ||
|         
 | ||
|     rep.type           = X_Reply;
 | ||
|     rep.sequenceNumber = client->sequence;
 | ||
|     rep.length         = 0;
 | ||
|     
 | ||
|     if (client->swapped)
 | ||
|     {
 | ||
|         swaps(&rep.sequenceNumber, n);
 | ||
|         swapl(&rep.length, n);
 | ||
|         swapl(&rep.attributes, n);
 | ||
|     }
 | ||
| 
 | ||
|     WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
 | ||
|                   (char *)&rep);
 | ||
|     return(client->noClientException);
 | ||
| 
 | ||
| } /* ProcDbeGetbackBufferAttributes() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: ProcDbeDispatch
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function dispatches DBE requests.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| ProcDbeDispatch(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xReq);
 | ||
| 
 | ||
| 
 | ||
|     switch (stuff->data)
 | ||
|     {
 | ||
|         case X_DbeGetVersion:
 | ||
|             return(ProcDbeGetVersion(client));
 | ||
| 
 | ||
|         case X_DbeAllocateBackBufferName:
 | ||
|             return(ProcDbeAllocateBackBufferName(client));
 | ||
| 
 | ||
|         case X_DbeDeallocateBackBufferName:
 | ||
|             return(ProcDbeDeallocateBackBufferName(client));
 | ||
| 
 | ||
|         case X_DbeSwapBuffers:
 | ||
|             return(ProcDbeSwapBuffers(client));
 | ||
| 
 | ||
|         case X_DbeBeginIdiom:
 | ||
|             return(ProcDbeBeginIdiom(client));
 | ||
| 
 | ||
|         case X_DbeEndIdiom:
 | ||
|             return(Success);
 | ||
| 
 | ||
|         case X_DbeGetVisualInfo:
 | ||
|             return(ProcDbeGetVisualInfo(client));
 | ||
| 
 | ||
|         case X_DbeGetBackBufferAttributes:
 | ||
|             return(ProcDbeGetBackBufferAttributes(client));
 | ||
| 
 | ||
|         default:
 | ||
|             return(BadRequest);
 | ||
|     }
 | ||
| 
 | ||
| } /* ProcDbeDispatch() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeGetVersion
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeGetVersion request on a swapped
 | ||
|  *     server.  This request returns the major and minor version numbers of
 | ||
|  *     this extension.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeGetVersion(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeGetVersionReq);
 | ||
|     register int	n;
 | ||
| 
 | ||
| 
 | ||
|     swaps(&stuff->length, n);
 | ||
|     return(ProcDbeGetVersion(client));
 | ||
| 
 | ||
| } /* SProcDbeGetVersion() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeAllocateBackBufferName
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeAllocateBackBufferName request on
 | ||
|  *     a swapped server.  This request allocates a drawable ID used to refer
 | ||
|  *     to the back buffer of a window.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadAlloc    - server can not allocate resources
 | ||
|  *     BadIDChoice - id is out of range for client; id is already in use
 | ||
|  *     BadMatch    - window is not an InputOutput window;
 | ||
|  *                   visual of window is not on list returned by
 | ||
|  *                   DBEGetVisualInfo; 
 | ||
|  *     BadValue    - invalid swap action is specified
 | ||
|  *     BadWindow   - window is not a valid window
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeAllocateBackBufferName(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeAllocateBackBufferNameReq);
 | ||
|     register int	n;
 | ||
| 
 | ||
|     swaps(&stuff->length, n);
 | ||
|     REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
 | ||
| 
 | ||
|     swapl(&stuff->window, n);
 | ||
|     swapl(&stuff->buffer, n);
 | ||
|     /* stuff->swapAction is a byte.  We do not need to swap this field. */
 | ||
| 
 | ||
|     return(ProcDbeAllocateBackBufferName(client));
 | ||
| 
 | ||
| } /* SProcDbeAllocateBackBufferName() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeDeallocateBackBufferName request
 | ||
|  *     on a swapped server.  This request frees a drawable ID that was
 | ||
|  *     obtained by a DbeAllocateBackBufferName request.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadBuffer - buffer to deallocate is not associated with a window
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeDeallocateBackBufferName(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST (xDbeDeallocateBackBufferNameReq);
 | ||
|     register int	n;
 | ||
| 
 | ||
| 
 | ||
|     swaps(&stuff->length, n);
 | ||
|     REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
 | ||
| 
 | ||
|     swapl(&stuff->buffer, n);
 | ||
| 
 | ||
|     return(ProcDbeDeallocateBackBufferName(client));
 | ||
| 
 | ||
| } /* SProcDbeDeallocateBackBufferName() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeSwapBuffers
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeSwapBuffers request on a swapped
 | ||
|  *     server.  This request swaps the buffers for all windows listed,
 | ||
|  *     applying the appropriate swap action for each window.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadMatch  - a window in request is not double-buffered; a window in
 | ||
|  *                 request is listed more than once; all windows in request do
 | ||
|  *                 not have the same root
 | ||
|  *     BadValue  - invalid swap action is specified
 | ||
|  *     BadWindow - a window in request is not valid
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeSwapBuffers(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeSwapBuffersReq);
 | ||
|     register int	i, n;
 | ||
|     xDbeSwapInfo	*pSwapInfo;
 | ||
| 
 | ||
| 
 | ||
|     swaps(&stuff->length, n);
 | ||
|     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
 | ||
| 
 | ||
|     swapl(&stuff->n, n);
 | ||
| 
 | ||
|     if (stuff->n != 0)
 | ||
|     { 
 | ||
|         pSwapInfo = (xDbeSwapInfo *)stuff+1;
 | ||
| 
 | ||
|         /* The swap info following the fix part of this request is a window(32)
 | ||
|          * followed by a 1 byte swap action and then 3 pad bytes.  We only need
 | ||
|          * to swap the window information.
 | ||
|          */
 | ||
|         for (i = 0; i < stuff->n; i++)
 | ||
|         {
 | ||
|             swapl(&pSwapInfo->window, n);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     return(ProcDbeSwapBuffers(client));
 | ||
| 
 | ||
| } /* SProcDbeSwapBuffers() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeBeginIdiom
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a DbeBeginIdiom request on a swapped
 | ||
|  *     server.  This request informs the server that a complex swap will
 | ||
|  *     immediately follow this request.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeBeginIdiom(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeBeginIdiomReq);
 | ||
|     register int	n;
 | ||
| 
 | ||
|     swaps(&stuff->length, n);
 | ||
|     return(ProcDbeBeginIdiom(client));
 | ||
| 
 | ||
| } /* SProcDbeBeginIdiom() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeGetVisualInfo
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a ProcDbeGetVisualInfo request on a
 | ||
|  *     swapped server.  This request returns information about which visuals
 | ||
|  *     support double buffering.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     BadDrawable - value in screen specifiers is not a valid drawable
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeGetVisualInfo(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xDbeGetVisualInfoReq);
 | ||
|     register int	n;
 | ||
| 
 | ||
| 
 | ||
|     swaps(&stuff->length, n);
 | ||
|     REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
 | ||
| 
 | ||
|     swapl(&stuff->n, n);
 | ||
|     SwapRestL(stuff);
 | ||
| 
 | ||
|     return(ProcDbeGetVisualInfo(client));
 | ||
| 
 | ||
| } /* SProcDbeGetVisualInfo() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function is for processing a ProcDbeGetbackBufferAttributes
 | ||
|  *     request on a swapped server.  This request returns information about a
 | ||
|  *     back buffer.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     Success
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeGetBackBufferAttributes(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST (xDbeGetBackBufferAttributesReq);
 | ||
|     register int	n;
 | ||
| 
 | ||
|     swaps(&stuff->length, n);
 | ||
|     REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
 | ||
| 
 | ||
|     swapl(&stuff->buffer, n);
 | ||
| 
 | ||
|     return(ProcDbeGetBackBufferAttributes(client));
 | ||
| 
 | ||
| } /* SProcDbeGetBackBufferAttributes() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: SProcDbeDispatch
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function dispatches DBE requests on a swapped server.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static int
 | ||
| SProcDbeDispatch(ClientPtr client)
 | ||
| {
 | ||
|     REQUEST(xReq);
 | ||
| 
 | ||
| 
 | ||
|     switch (stuff->data)
 | ||
|     {
 | ||
|         case X_DbeGetVersion:
 | ||
|             return(SProcDbeGetVersion(client));
 | ||
| 
 | ||
|         case X_DbeAllocateBackBufferName:
 | ||
|             return(SProcDbeAllocateBackBufferName(client));
 | ||
| 
 | ||
|         case X_DbeDeallocateBackBufferName:
 | ||
|             return(SProcDbeDeallocateBackBufferName(client));
 | ||
| 
 | ||
|         case X_DbeSwapBuffers:
 | ||
|             return(SProcDbeSwapBuffers(client));
 | ||
| 
 | ||
|         case X_DbeBeginIdiom:
 | ||
|             return(SProcDbeBeginIdiom(client));
 | ||
| 
 | ||
|         case X_DbeEndIdiom:
 | ||
|             return(Success);
 | ||
| 
 | ||
|         case X_DbeGetVisualInfo:
 | ||
|             return(SProcDbeGetVisualInfo(client));
 | ||
| 
 | ||
|         case X_DbeGetBackBufferAttributes:
 | ||
|             return(SProcDbeGetBackBufferAttributes(client));
 | ||
| 
 | ||
|         default:
 | ||
|             return (BadRequest);
 | ||
|     }
 | ||
| 
 | ||
| } /* SProcDbeDispatch() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeSetupBackgroundPainter
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This function sets up pGC to clear pixmaps.
 | ||
|  *
 | ||
|  * Return Values:
 | ||
|  *
 | ||
|  *     TRUE  - setup was successful
 | ||
|  *     FALSE - the window's background state is NONE
 | ||
|  * 
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static Bool
 | ||
| DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
 | ||
| {
 | ||
|     pointer	gcvalues[4];
 | ||
|     int		ts_x_origin, ts_y_origin;
 | ||
|     PixUnion	background;
 | ||
|     int		backgroundState;
 | ||
|     Mask	gcmask;
 | ||
| 
 | ||
| 
 | ||
|     /* First take care of any ParentRelative stuff by altering the
 | ||
|      * tile/stipple origin to match the coordinates of the upper-left
 | ||
|      * corner of the first ancestor without a ParentRelative background.
 | ||
|      * This coordinate is, of course, negative.
 | ||
|      */
 | ||
|     ts_x_origin = ts_y_origin = 0;
 | ||
|     while (pWin->backgroundState == ParentRelative)
 | ||
|     {
 | ||
|         ts_x_origin -= pWin->origin.x;
 | ||
|         ts_y_origin -= pWin->origin.y;
 | ||
| 
 | ||
|         pWin = pWin->parent;
 | ||
|     }
 | ||
|     backgroundState = pWin->backgroundState;
 | ||
|     background      = pWin->background;
 | ||
| 
 | ||
|     switch (backgroundState)
 | ||
|     {
 | ||
|         case BackgroundPixel:
 | ||
|             gcvalues[0] = (pointer)background.pixel;
 | ||
|             gcvalues[1] = (pointer)FillSolid;
 | ||
|             gcmask = GCForeground|GCFillStyle;
 | ||
|             break;
 | ||
| 
 | ||
|         case BackgroundPixmap:
 | ||
|             gcvalues[0] = (pointer)FillTiled;
 | ||
|             gcvalues[1] = (pointer)background.pixmap;
 | ||
|             gcvalues[2] = (pointer)(long)ts_x_origin;
 | ||
|             gcvalues[3] = (pointer)(long)ts_y_origin;
 | ||
|             gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
 | ||
|             break;
 | ||
| 
 | ||
|         default:
 | ||
|             /* pWin->backgroundState == None */
 | ||
|             return(FALSE);
 | ||
|     }
 | ||
| 
 | ||
|     if (DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE) != 0)
 | ||
|     {
 | ||
|         return(FALSE);
 | ||
|     }
 | ||
| 
 | ||
|     return(TRUE);
 | ||
| 
 | ||
| } /* DbeSetupBackgroundPainter() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeDrawableDelete
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the resource delete function for dbeDrawableResType.
 | ||
|  *     It is registered when the drawable resource type is created in
 | ||
|  *     DbeExtensionInit().
 | ||
|  *
 | ||
|  *     To make resource deletion simple, we do not do anything in this function
 | ||
|  *     and leave all resource deleteion to DbeWindowPrivDelete(), which will
 | ||
|  *     eventually be called or already has been called.  Deletion functions are
 | ||
|  *     not guaranteed to be called in any particular order.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| static int
 | ||
| DbeDrawableDelete(pointer pDrawable, XID id)
 | ||
| {
 | ||
|     return(Success);
 | ||
| 
 | ||
| } /* DbeDrawableDelete() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeWindowPrivDelete
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the resource delete function for dbeWindowPrivResType.
 | ||
|  *     It is registered when the drawable resource type is created in
 | ||
|  *     DbeExtensionInit().
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| static int
 | ||
| DbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
 | ||
| {
 | ||
|     DbeScreenPrivPtr	pDbeScreenPriv;
 | ||
|     DbeWindowPrivPtr	pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv;
 | ||
|     int			i;
 | ||
| 
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** Remove the buffer ID from the ID array.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     /* Find the ID in the ID array. */
 | ||
|     i = 0;
 | ||
|     while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id))
 | ||
|     {
 | ||
|         i++;
 | ||
|     }
 | ||
| 
 | ||
|     if (i == pDbeWindowPriv->nBufferIDs)
 | ||
|     {
 | ||
|         /* We did not find the ID in the array.  We should never get here. */
 | ||
|         return(BadValue);
 | ||
|     }
 | ||
| 
 | ||
|     /* Remove the ID from the array. */
 | ||
| 
 | ||
|     if (i < (pDbeWindowPriv->nBufferIDs - 1))
 | ||
|     {
 | ||
|         /* Compress the buffer ID array, overwriting the ID in the process. */
 | ||
|         memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1],
 | ||
|             (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|         /* We are removing the last ID in the array, in which case, the
 | ||
|          * assignement below is all that we need to do.
 | ||
|          */
 | ||
|     }
 | ||
|     pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
 | ||
| 
 | ||
|     pDbeWindowPriv->nBufferIDs--;
 | ||
| 
 | ||
|     /* If an extended array was allocated, then check to see if the remaining
 | ||
|      * buffer IDs will fit in the static array.
 | ||
|      */
 | ||
| 
 | ||
|     if ((pDbeWindowPriv->maxAvailableIDs >  DBE_INIT_MAX_IDS) &&
 | ||
|         (pDbeWindowPriv->nBufferIDs      == DBE_INIT_MAX_IDS))
 | ||
|     {
 | ||
|         /* Copy the IDs back into the static array. */
 | ||
|         memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
 | ||
|                DBE_INIT_MAX_IDS * sizeof(XID));
 | ||
| 
 | ||
|         /* Free the extended array; use the static array. */
 | ||
|         xfree(pDbeWindowPriv->IDs);
 | ||
|         pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
 | ||
|         pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** Perform DDX level tasks.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(
 | ||
|                          (DbeWindowPrivPtr)pDbeWindowPriv);
 | ||
|     (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id);
 | ||
| 
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** Perform miscellaneous tasks if this is the last buffer associated
 | ||
|      ** with the window.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     if (pDbeWindowPriv->nBufferIDs == 0)
 | ||
|     {
 | ||
|         /* Reset the DBE window priv pointer. */
 | ||
|         pDbeWindowPriv->pWindow->devPrivates[dbeWindowPrivIndex].ptr =
 | ||
|             (pointer)NULL;
 | ||
| 
 | ||
|         /* We are done with the window priv. */
 | ||
|         xfree(pDbeWindowPriv);
 | ||
|     }
 | ||
| 
 | ||
|     return(Success);
 | ||
| 
 | ||
| } /* DbeWindowPrivDelete() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeResetProc
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This routine is called at the end of every server generation.
 | ||
|  *     It deallocates any memory reserved for the extension and performs any
 | ||
|  *     other tasks related to shutting down the extension.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| static void
 | ||
| DbeResetProc(ExtensionEntry *extEntry)
 | ||
| {
 | ||
|     int			i;
 | ||
|     ScreenPtr		pScreen;
 | ||
|     DbeScreenPrivPtr	pDbeScreenPriv;
 | ||
|     
 | ||
| 
 | ||
|     if (dbeScreenPrivIndex < 0)
 | ||
|     {
 | ||
| 	return;
 | ||
|     }
 | ||
| 
 | ||
|     for (i = 0; i < screenInfo.numScreens; i++)
 | ||
|     {
 | ||
| 	pScreen = screenInfo.screens[i];
 | ||
| 	pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
| 
 | ||
| 	if (pDbeScreenPriv)
 | ||
| 	{
 | ||
|             /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/
 | ||
|             pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
 | ||
| 
 | ||
| 	    if (pDbeScreenPriv->ResetProc)
 | ||
| 		(*pDbeScreenPriv->ResetProc)(pScreen);
 | ||
| 
 | ||
|             if (pDbeScreenPriv->winPrivPrivSizes)
 | ||
|             {
 | ||
| 	        xfree(pDbeScreenPriv->winPrivPrivSizes);
 | ||
|             }
 | ||
| 
 | ||
| 	    xfree(pDbeScreenPriv);
 | ||
| 	}
 | ||
|     }
 | ||
| 
 | ||
|     /* We want to init the initialization function table after every server
 | ||
|      * reset in DbeRegisterFunction().
 | ||
|      */
 | ||
|     firstRegistrationPass = TRUE;
 | ||
| 
 | ||
| } /* DbeResetProc() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeDestroyWindow
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     This is the wrapper for pScreen->DestroyWindow.
 | ||
|  *     This function frees buffer resources for a window before it is
 | ||
|  *     destroyed.
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| static Bool
 | ||
| DbeDestroyWindow(WindowPtr pWin)
 | ||
| {
 | ||
|     DbeScreenPrivPtr	pDbeScreenPriv;
 | ||
|     DbeWindowPrivPtr	pDbeWindowPriv;
 | ||
|     ScreenPtr		pScreen;
 | ||
|     Bool		ret;
 | ||
| 
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 1. Unwrap the member routine.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     pScreen                = pWin->drawable.pScreen;
 | ||
|     pDbeScreenPriv         = DBE_SCREEN_PRIV(pScreen);
 | ||
|     pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 2. Do any work necessary before the member routine is called.
 | ||
|      **
 | ||
|      **    Call the window priv delete function for all buffer IDs associated
 | ||
|      **    with this window.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
 | ||
|     {
 | ||
|         while (pDbeWindowPriv)
 | ||
|         {
 | ||
|             /* *DbeWinPrivDelete() will free the window private and set it to
 | ||
|              * NULL if there are no more buffer IDs associated with this
 | ||
|              * window.
 | ||
|              */
 | ||
|             FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
 | ||
|             pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 3. Call the member routine, saving its result if necessary.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     ret = (*pScreen->DestroyWindow)(pWin);
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 4. Rewrap the member routine, restoring the wrapper value first in case
 | ||
|      **    the wrapper (or something that it wrapped) change this value.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
 | ||
|     pScreen->DestroyWindow = DbeDestroyWindow;
 | ||
| 
 | ||
|     /*
 | ||
|      **************************************************************************
 | ||
|      ** 5. Do any work necessary after the member routine has been called.
 | ||
|      **
 | ||
|      **    In this case we do not need to do anything.
 | ||
|      **************************************************************************
 | ||
|      */
 | ||
| 
 | ||
|     return(ret);
 | ||
| 
 | ||
| } /* DbeDestroyWindow() */
 | ||
| 
 | ||
| 
 | ||
| /******************************************************************************
 | ||
|  *
 | ||
|  * DBE DIX Procedure: DbeExtensionInit
 | ||
|  *
 | ||
|  * Description:
 | ||
|  *
 | ||
|  *     Called from InitExtensions in main()
 | ||
|  *
 | ||
|  *****************************************************************************/
 | ||
| 
 | ||
| void
 | ||
| DbeExtensionInit(void)
 | ||
| {
 | ||
|     ExtensionEntry	*extEntry;
 | ||
|     register int	i, j;
 | ||
|     ScreenPtr		pScreen = NULL;
 | ||
|     DbeScreenPrivPtr	pDbeScreenPriv;
 | ||
|     int			nStubbedScreens = 0;
 | ||
|     Bool		ddxInitSuccess;
 | ||
| 
 | ||
| #ifdef PANORAMIX
 | ||
|     if(!noPanoramiXExtension) return;
 | ||
| #endif
 | ||
| 
 | ||
|     /* Allocate private pointers in windows and screens. */
 | ||
| 
 | ||
|     if ((dbeScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
 | ||
|     {
 | ||
| 	return;
 | ||
|     }
 | ||
| 
 | ||
|     if ((dbeWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
 | ||
|     {
 | ||
| 	return;
 | ||
|     }
 | ||
| 
 | ||
|     /* Initialize the priv priv counts between server generations. */
 | ||
|     winPrivPrivCount  = 0;
 | ||
| 
 | ||
|     /* Create the resource types. */
 | ||
|     dbeDrawableResType =
 | ||
|         CreateNewResourceType(DbeDrawableDelete) | RC_CACHED | RC_DRAWABLE;
 | ||
|     dbeWindowPrivResType =
 | ||
|         CreateNewResourceType(DbeWindowPrivDelete);
 | ||
| 
 | ||
|     for (i = 0; i < screenInfo.numScreens; i++)
 | ||
|     {
 | ||
|         /* For each screen, set up DBE screen privates and init DIX and DDX
 | ||
|          * interface.
 | ||
|          */
 | ||
| 
 | ||
| 	pScreen = screenInfo.screens[i];
 | ||
| 
 | ||
| 	if (!AllocateWindowPrivate(pScreen, dbeWindowPrivIndex, 0) ||
 | ||
| 	    !(pDbeScreenPriv =
 | ||
|              (DbeScreenPrivPtr)Xcalloc(sizeof(DbeScreenPrivRec))))
 | ||
| 	{
 | ||
|             /* If we can not alloc a window or screen private,
 | ||
|              * then free any privates that we already alloc'ed and return
 | ||
|              */
 | ||
| 
 | ||
| 	    for (j = 0; j < i; j++)
 | ||
| 	    {
 | ||
| 	      xfree(screenInfo.screens[j]->devPrivates[dbeScreenPrivIndex].ptr);
 | ||
|               screenInfo.screens[j]->devPrivates[dbeScreenPrivIndex].ptr = NULL;
 | ||
| 	    }
 | ||
| 	    return;
 | ||
| 	}
 | ||
| 
 | ||
| 	pScreen->devPrivates[dbeScreenPrivIndex].ptr = (pointer)pDbeScreenPriv;
 | ||
| 
 | ||
|         /* Store the DBE priv priv size info for later use when allocating
 | ||
|          * priv privs at the driver level.
 | ||
|          */
 | ||
|         pDbeScreenPriv->winPrivPrivLen   = 0;
 | ||
|         pDbeScreenPriv->winPrivPrivSizes = (unsigned *)NULL;
 | ||
|         pDbeScreenPriv->totalWinPrivSize = sizeof(DbeWindowPrivRec);
 | ||
| 
 | ||
|         /* Copy the resource types */
 | ||
|         pDbeScreenPriv->dbeDrawableResType   = dbeDrawableResType;
 | ||
|         pDbeScreenPriv->dbeWindowPrivResType = dbeWindowPrivResType;
 | ||
| 
 | ||
|         /* Copy the private indices */
 | ||
|         pDbeScreenPriv->dbeScreenPrivIndex = dbeScreenPrivIndex;
 | ||
|         pDbeScreenPriv->dbeWindowPrivIndex = dbeWindowPrivIndex;
 | ||
| 
 | ||
|         if(DbeInitFunct[i])
 | ||
|         {
 | ||
|             /* This screen supports DBE. */
 | ||
| 
 | ||
|             /* Setup DIX. */
 | ||
|             pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; 
 | ||
|             pDbeScreenPriv->AllocWinPriv           = DbeAllocWinPriv;
 | ||
|             pDbeScreenPriv->AllocWinPrivPrivIndex  = DbeAllocWinPrivPrivIndex;
 | ||
|             pDbeScreenPriv->AllocWinPrivPriv       = DbeAllocWinPrivPriv;
 | ||
| 
 | ||
|             /* Setup DDX. */
 | ||
|             ddxInitSuccess = (*DbeInitFunct[i])(pScreen, pDbeScreenPriv);
 | ||
| 
 | ||
|             /* DDX DBE initialization may have the side affect of
 | ||
|              * reallocating pDbeScreenPriv, so we need to update it.
 | ||
|              */
 | ||
|             pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
| 
 | ||
|             if (ddxInitSuccess)
 | ||
|             {
 | ||
|                 /* Wrap DestroyWindow.  The DDX initialization function
 | ||
|                  * already wrapped PositionWindow for us.
 | ||
|                  */
 | ||
| 
 | ||
|                 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
 | ||
|                 pScreen->DestroyWindow        = DbeDestroyWindow;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 /* DDX initialization failed.  Stub the screen. */
 | ||
|                 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
 | ||
|             }
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|             /* This screen does not support DBE. */
 | ||
| 
 | ||
| #ifndef DISABLE_MI_DBE_BY_DEFAULT
 | ||
|             /* Setup DIX. */
 | ||
|             pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; 
 | ||
|             pDbeScreenPriv->AllocWinPriv           = DbeAllocWinPriv;
 | ||
|             pDbeScreenPriv->AllocWinPrivPrivIndex  = DbeAllocWinPrivPrivIndex;
 | ||
|             pDbeScreenPriv->AllocWinPrivPriv       = DbeAllocWinPrivPriv;
 | ||
| 
 | ||
|             /* Setup DDX. */
 | ||
|             ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
 | ||
| 
 | ||
|             /* DDX DBE initialization may have the side affect of
 | ||
|              * reallocating pDbeScreenPriv, so we need to update it.
 | ||
|              */
 | ||
|             pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 | ||
| 
 | ||
|             if (ddxInitSuccess)
 | ||
|             {
 | ||
|                 /* Wrap DestroyWindow.  The DDX initialization function
 | ||
|                  * already wrapped PositionWindow for us.
 | ||
|                  */
 | ||
| 
 | ||
|                 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
 | ||
|                 pScreen->DestroyWindow        = DbeDestroyWindow;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 /* DDX initialization failed.  Stub the screen. */
 | ||
|                 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
 | ||
|             }
 | ||
| #else
 | ||
|             DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
 | ||
| #endif
 | ||
| 
 | ||
|         } /* else -- this screen does not support DBE. */
 | ||
| 
 | ||
|     } /* for (i = 0; i < screenInfo.numScreens; i++) */
 | ||
| 
 | ||
| 
 | ||
|     if (nStubbedScreens == screenInfo.numScreens)
 | ||
|     {
 | ||
| 	/* All screens stubbed.  Clean up and return. */
 | ||
| 
 | ||
|         for (i = 0; i < screenInfo.numScreens; i++)
 | ||
|         {
 | ||
|              xfree(screenInfo.screens[i]->devPrivates[dbeScreenPrivIndex].ptr);
 | ||
|              pScreen->devPrivates[dbeScreenPrivIndex].ptr = NULL;
 | ||
|         }
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /* Now add the extension. */
 | ||
|     extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, 
 | ||
|                             DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
 | ||
|                             DbeResetProc, StandardMinorOpcode);
 | ||
| 
 | ||
|     dbeErrorBase = extEntry->errorBase;
 | ||
| 
 | ||
| } /* DbeExtensionInit() */
 | ||
| 
 |