xserver-multidpi/dbe/dbe.c

1643 lines
46 KiB
C
Raw Normal View History

2003-11-14 16:54:54 +01:00
/******************************************************************************
*
* 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 */
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <string.h>
#include <stdint.h>
#include <X11/X.h>
#include <X11/Xproto.h>
2003-11-14 16:54:54 +01:00
#include "scrnintstr.h"
#include "extnsionst.h"
#include "gcstruct.h"
#include "dixstruct.h"
#define NEED_DBE_PROTOCOL
#include "dbestruct.h"
#include "midbe.h"
#include "xace.h"
2003-11-14 16:54:54 +01:00
/* GLOBALS */
/* These are globals for use by DDX */
DevPrivateKeyRec dbeScreenPrivKeyRec;
DevPrivateKeyRec dbeWindowPrivKeyRec;
2003-11-14 16:54:54 +01:00
/* These are globals for use by DDX */
RESTYPE dbeDrawableResType;
RESTYPE dbeWindowPrivResType;
2003-11-14 16:54:54 +01:00
/* Used to generate DBE's BadBuffer error. */
static int dbeErrorBase;
/******************************************************************************
*
* 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
2006-03-28 03:21:00 +02:00
DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
2003-11-14 16:54:54 +01:00
{
/* Stub DIX. */
pDbeScreenPriv->SetupBackgroundPainter = 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
2006-03-28 03:21:00 +02:00
ProcDbeGetVersion(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
2003-11-14 17:49:22 +01:00
/* REQUEST(xDbeGetVersionReq); */
2003-11-14 16:54:54 +01:00
xDbeGetVersionReply rep;
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);
2003-11-14 16:54:54 +01:00
}
WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep);
return Success;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
ProcDbeAllocateBackBufferName(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeAllocateBackBufferNameReq);
WindowPtr pWin;
DbeScreenPrivPtr pDbeScreenPriv;
DbeWindowPrivPtr pDbeWindowPriv;
XdbeScreenVisualInfo scrVisInfo;
register int i;
Bool visualMatched = FALSE;
xDbeSwapAction swapAction;
VisualID visual;
int status;
int add_index;
2003-11-14 16:54:54 +01:00
REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
/* The window must be valid. */
status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
if (status != Success)
return status;
2003-11-14 16:54:54 +01:00
/* The window must be InputOutput. */
if (pWin->drawable.class != InputOutput)
{
return BadMatch;
2003-11-14 16:54:54 +01:00
}
/* 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;
2003-11-14 16:54:54 +01:00
}
/* 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 */
2003-11-14 16:54:54 +01:00
if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
{
/* GetVisualInfo() failed to allocate visual info data. */
return BadAlloc;
2003-11-14 16:54:54 +01:00
}
/* 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. */
free(scrVisInfo.visinfo);
2003-11-14 16:54:54 +01:00
if (!visualMatched)
{
return BadMatch;
2003-11-14 16:54:54 +01:00
}
if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
{
/* There is no buffer associated with the window.
* Allocate a window priv.
*/
pDbeWindowPriv = dixAllocateObjectWithPrivates(DbeWindowPrivRec, PRIVATE_DBE_WINDOW);
if (!pDbeWindowPriv)
return BadAlloc;
2003-11-14 16:54:54 +01:00
/* 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;
add_index = 0;
for (i = 0; i < DBE_INIT_MAX_IDS; i++)
2003-11-14 16:54:54 +01:00
{
pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
}
/* Actually connect the window priv to the window. */
dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
2003-11-14 16:54:54 +01:00
} /* 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 *)realloc(pIDs,
2003-11-14 16:54:54 +01:00
(pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID));
if (!pDbeWindowPriv->IDs)
{
return BadAlloc;
2003-11-14 16:54:54 +01:00
}
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;
}
add_index = i;
2003-11-14 16:54:54 +01:00
} /* 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)
2003-11-14 16:54:54 +01:00
{
pDbeWindowPriv->IDs[add_index] = stuff->buffer;
if (!AddResource(stuff->buffer, dbeWindowPrivResType,
(pointer)pDbeWindowPriv))
{
pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
if (pDbeWindowPriv->nBufferIDs == 0) {
status = BadAlloc;
goto out_free;
}
}
} else {
2003-11-14 16:54:54 +01:00
/* The DDX buffer allocation routine failed for the first buffer of
* this window.
*/
if (pDbeWindowPriv->nBufferIDs == 0) {
goto out_free;
}
2003-11-14 16:54:54 +01:00
}
/* Increment the number of buffers (XIDs) associated with this window. */
pDbeWindowPriv->nBufferIDs++;
/* Set swap action on all calls. */
pDbeWindowPriv->swapAction = stuff->swapAction;
return status;
2003-11-14 16:54:54 +01:00
out_free:
dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
free(pDbeWindowPriv);
return status;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
ProcDbeDeallocateBackBufferName(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeDeallocateBackBufferNameReq);
DbeWindowPrivPtr pDbeWindowPriv;
int rc, i;
pointer val;
2003-11-14 16:54:54 +01:00
REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
/* Buffer name must be valid */
rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
dbeWindowPrivResType, client,
DixDestroyAccess);
if (rc != Success)
return rc;
rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
client, DixDestroyAccess);
if (rc != Success)
return rc;
2003-11-14 16:54:54 +01:00
/* 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;
2003-11-14 16:54:54 +01:00
}
FreeResource(stuff->buffer, RT_NONE);
return Success;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
ProcDbeSwapBuffers(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
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;
2003-11-14 16:54:54 +01:00
}
if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
return BadAlloc;
2003-11-14 16:54:54 +01:00
/* Get to the swap info appended to the end of the request. */
dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
/* Allocate array to record swap information. */
swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec));
2003-11-14 16:54:54 +01:00
if (swapInfo == NULL)
{
return BadAlloc;
2003-11-14 16:54:54 +01:00
}
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) {
free(swapInfo);
return error;
2003-11-14 16:54:54 +01:00
}
/* Each window must be double-buffered - BadMatch. */
if (DBE_WINDOW_PRIV(pWin) == NULL)
{
free(swapInfo);
return BadMatch;
2003-11-14 16:54:54 +01:00
}
/* Each window must only be specified once - BadMatch. */
for (j = i + 1; j < nStuff; j++)
{
if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
{
free(swapInfo);
return BadMatch;
2003-11-14 16:54:54 +01:00
}
}
/* Each swap action must be valid - BadValue. */
if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) &&
(dbeSwapInfo[i].swapAction != XdbeBackground) &&
(dbeSwapInfo[i].swapAction != XdbeUntouched ) &&
(dbeSwapInfo[i].swapAction != XdbeCopied ))
{
free(swapInfo);
return BadValue;
2003-11-14 16:54:54 +01:00
}
/* 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)
{
free(swapInfo);
return error;
2003-11-14 16:54:54 +01:00
}
}
free(swapInfo);
return Success;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
ProcDbeBeginIdiom(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
2003-11-14 17:49:22 +01:00
/* REQUEST(xDbeBeginIdiomReq); */
2003-11-14 16:54:54 +01:00
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;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
ProcDbeGetVisualInfo(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeGetVisualInfoReq);
DbeScreenPrivPtr pDbeScreenPriv;
xDbeGetVisualInfoReply rep;
Drawable *drawables;
DrawablePtr *pDrawables = NULL;
register int i, j, rc;
2003-11-14 16:54:54 +01:00
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;
2003-11-14 16:54:54 +01:00
/* Make sure any specified drawables are valid. */
if (stuff->n != 0)
{
if (!(pDrawables = (DrawablePtr *)malloc(stuff->n *
2003-11-14 16:54:54 +01:00
sizeof(DrawablePtr))))
{
return BadAlloc;
2003-11-14 16:54:54 +01:00
}
drawables = (Drawable *)&stuff[1];
for (i = 0; i < stuff->n; i++)
{
rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0,
DixGetAttrAccess);
if (rc != Success) {
free(pDrawables);
return rc;
2003-11-14 16:54:54 +01:00
}
}
}
count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo))))
2003-11-14 16:54:54 +01:00
{
free(pDrawables);
2003-11-14 16:54:54 +01:00
return BadAlloc;
2003-11-14 16:54:54 +01:00
}
length = 0;
for (i = 0; i < count; i++)
{
pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
pDrawables[i]->pScreen;
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
if (rc != Success)
goto freeScrVisInfo;
if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
2003-11-14 16:54:54 +01:00
{
/* We failed to alloc pScrVisInfo[i].visinfo. */
rc = BadAlloc;
2003-11-14 16:54:54 +01:00
/* Free visinfos that we allocated for previous screen infos.*/
goto freeScrVisInfo;
2003-11-14 16:54:54 +01:00
}
/* 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 = bytes_to_int32(length);
2003-11-14 16:54:54 +01:00
rep.m = count;
if (client->swapped)
{
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.m);
2003-11-14 16:54:54 +01:00
}
/* 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);
2003-11-14 16:54:54 +01:00
}
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);
2003-11-14 16:54:54 +01:00
/* 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);
}
}
rc = Success;
freeScrVisInfo:
2003-11-14 16:54:54 +01:00
/* Clean up memory. */
for (i = 0; i < count; i++)
{
free(pScrVisInfo[i].visinfo);
2003-11-14 16:54:54 +01:00
}
free(pScrVisInfo);
2003-11-14 16:54:54 +01:00
free(pDrawables);
2003-11-14 16:54:54 +01:00
return rc;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
ProcDbeGetBackBufferAttributes(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeGetBackBufferAttributesReq);
xDbeGetBackBufferAttributesReply rep;
DbeWindowPrivPtr pDbeWindowPriv;
int rc;
2003-11-14 16:54:54 +01:00
REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
dbeWindowPrivResType, client,
DixGetAttrAccess);
if (rc == Success)
2003-11-14 16:54:54 +01:00
{
rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
2003-11-14 16:54:54 +01:00
}
else
{
rep.attributes = None;
2003-11-14 16:54:54 +01:00
}
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
if (client->swapped)
{
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.attributes);
2003-11-14 16:54:54 +01:00
}
WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
(char *)&rep);
return Success;
2003-11-14 16:54:54 +01:00
} /* ProcDbeGetbackBufferAttributes() */
/******************************************************************************
*
* DBE DIX Procedure: ProcDbeDispatch
*
* Description:
*
* This function dispatches DBE requests.
*
*****************************************************************************/
static int
2006-03-28 03:21:00 +02:00
ProcDbeDispatch(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
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;
2003-11-14 16:54:54 +01:00
case X_DbeGetVisualInfo:
return(ProcDbeGetVisualInfo(client));
case X_DbeGetBackBufferAttributes:
return(ProcDbeGetBackBufferAttributes(client));
default:
return BadRequest;
2003-11-14 16:54:54 +01:00
}
} /* 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
2006-03-28 03:21:00 +02:00
SProcDbeGetVersion(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeGetVersionReq);
swaps(&stuff->length);
2003-11-14 16:54:54 +01:00
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
2006-03-28 03:21:00 +02:00
SProcDbeAllocateBackBufferName(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeAllocateBackBufferNameReq);
swaps(&stuff->length);
2003-11-14 16:54:54 +01:00
REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
swapl(&stuff->window);
swapl(&stuff->buffer);
2003-11-14 16:54:54 +01:00
/* 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
2006-03-28 03:21:00 +02:00
SProcDbeDeallocateBackBufferName(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST (xDbeDeallocateBackBufferNameReq);
swaps(&stuff->length);
2003-11-14 16:54:54 +01:00
REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
swapl(&stuff->buffer);
2003-11-14 16:54:54 +01:00
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
2006-03-28 03:21:00 +02:00
SProcDbeSwapBuffers(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeSwapBuffersReq);
register int i;
2003-11-14 16:54:54 +01:00
xDbeSwapInfo *pSwapInfo;
swaps(&stuff->length);
2003-11-14 16:54:54 +01:00
REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
swapl(&stuff->n);
2003-11-14 16:54:54 +01:00
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);
2003-11-14 16:54:54 +01:00
}
}
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
2006-03-28 03:21:00 +02:00
SProcDbeBeginIdiom(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeBeginIdiomReq);
swaps(&stuff->length);
2003-11-14 16:54:54 +01:00
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
2006-03-28 03:21:00 +02:00
SProcDbeGetVisualInfo(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST(xDbeGetVisualInfoReq);
swaps(&stuff->length);
2003-11-14 16:54:54 +01:00
REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
swapl(&stuff->n);
2003-11-14 16:54:54 +01:00
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
2006-03-28 03:21:00 +02:00
SProcDbeGetBackBufferAttributes(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
REQUEST (xDbeGetBackBufferAttributesReq);
swaps(&stuff->length);
2003-11-14 16:54:54 +01:00
REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
swapl(&stuff->buffer);
2003-11-14 16:54:54 +01:00
return(ProcDbeGetBackBufferAttributes(client));
} /* SProcDbeGetBackBufferAttributes() */
/******************************************************************************
*
* DBE DIX Procedure: SProcDbeDispatch
*
* Description:
*
* This function dispatches DBE requests on a swapped server.
*
*****************************************************************************/
static int
2006-03-28 03:21:00 +02:00
SProcDbeDispatch(ClientPtr client)
2003-11-14 16:54:54 +01:00
{
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;
2003-11-14 16:54:54 +01:00
case X_DbeGetVisualInfo:
return(SProcDbeGetVisualInfo(client));
case X_DbeGetBackBufferAttributes:
return(SProcDbeGetBackBufferAttributes(client));
default:
return BadRequest;
2003-11-14 16:54:54 +01:00
}
} /* 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
2006-03-28 03:21:00 +02:00
DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
2003-11-14 16:54:54 +01:00
{
ChangeGCVal gcvalues[4];
2003-11-14 16:54:54 +01:00
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].val = background.pixel;
gcvalues[1].val = FillSolid;
2003-11-14 16:54:54 +01:00
gcmask = GCForeground|GCFillStyle;
break;
case BackgroundPixmap:
gcvalues[0].val = FillTiled;
gcvalues[1].ptr = background.pixmap;
gcvalues[2].val = ts_x_origin;
gcvalues[3].val = ts_y_origin;
2003-11-14 16:54:54 +01:00
gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
break;
default:
/* pWin->backgroundState == None */
return FALSE;
2003-11-14 16:54:54 +01:00
}
return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
DbeDrawableDelete(pointer pDrawable, XID id)
2003-11-14 16:54:54 +01:00
{
return Success;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
DbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
2003-11-14 16:54:54 +01:00
{
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;
2003-11-14 16:54:54 +01:00
}
/* 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. */
free(pDbeWindowPriv->IDs);
2003-11-14 16:54:54 +01:00
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. */
dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
NULL);
2003-11-14 16:54:54 +01:00
/* We are done with the window priv. */
dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW);
2003-11-14 16:54:54 +01:00
}
return Success;
2003-11-14 16:54:54 +01:00
} /* 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
2006-03-28 03:21:00 +02:00
DbeResetProc(ExtensionEntry *extEntry)
2003-11-14 16:54:54 +01:00
{
int i;
ScreenPtr pScreen;
DbeScreenPrivPtr pDbeScreenPriv;
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);
free(pDbeScreenPriv);
2003-11-14 16:54:54 +01:00
}
}
} /* 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
2006-03-28 03:21:00 +02:00
DbeDestroyWindow(WindowPtr pWin)
2003-11-14 16:54:54 +01:00
{
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.
**************************************************************************
*/
2003-11-14 17:49:22 +01:00
if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
2003-11-14 16:54:54 +01:00
{
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;
2003-11-14 16:54:54 +01:00
} /* DbeDestroyWindow() */
/******************************************************************************
*
* DBE DIX Procedure: DbeExtensionInit
*
* Description:
*
* Called from InitExtensions in main()
*
*****************************************************************************/
void
2006-03-28 03:21:00 +02:00
DbeExtensionInit(void)
2003-11-14 16:54:54 +01:00
{
ExtensionEntry *extEntry;
register int i, j;
2003-11-14 17:49:22 +01:00
ScreenPtr pScreen = NULL;
2003-11-14 16:54:54 +01:00
DbeScreenPrivPtr pDbeScreenPriv;
int nStubbedScreens = 0;
Bool ddxInitSuccess;
2003-11-14 17:49:22 +01:00
#ifdef PANORAMIX
if(!noPanoramiXExtension) return;
#endif
2003-11-14 16:54:54 +01:00
/* Create the resource types. */
dbeDrawableResType =
CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
if (!dbeDrawableResType)
return;
dbeDrawableResType |= RC_DRAWABLE;
2003-11-14 16:54:54 +01:00
dbeWindowPrivResType =
CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
if (!dbeWindowPrivResType)
return;
if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0))
return;
if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0))
return;
2003-11-14 16:54:54 +01:00
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 (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec))))
2003-11-14 16:54:54 +01:00
{
/* 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++)
{
free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates,
dbeScreenPrivKey));
dixSetPrivate(&screenInfo.screens[j]->devPrivates,
dbeScreenPrivKey, NULL);
2003-11-14 16:54:54 +01:00
}
return;
}
dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv);
2003-11-14 16:54:54 +01:00
{
/* We don't have DDX support for DBE anymore */
2003-11-14 16:54:54 +01:00
#ifndef DISABLE_MI_DBE_BY_DEFAULT
/* Setup DIX. */
pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
/* 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
}
2003-11-14 16:54:54 +01:00
} /* 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++)
{
free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates,
dbeScreenPrivKey));
dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
2003-11-14 16:54:54 +01:00
}
return;
}
/* Now add the extension. */
extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
DbeResetProc, StandardMinorOpcode);
dbeErrorBase = extEntry->errorBase;
SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer);
SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer);
2003-11-14 16:54:54 +01:00
} /* DbeExtensionInit() */