dbe: use window destructor hook instead of wrapping ScreenRec's DestroyWindow

Wrapping ScreenRec's function pointers is problematic for many reasons, so
use the new window destructor hook instead.
This commit is contained in:
Enrico Weigelt, metux IT consult 2024-09-20 14:50:24 +02:00
parent 2649cf825b
commit 263bb37c2c
3 changed files with 21 additions and 82 deletions

View File

@ -81,11 +81,8 @@ DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
/* 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.
*/
/* Do not unwrap PositionWindow. If the DDX initialization function failed,
we assume that it did not wrap PositionWindow. */
/* Stub DDX. */
pDbeScreenPriv->GetVisualInfo = NULL;
@ -1201,7 +1198,9 @@ DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
return Success;
} /* DbeWindowPrivDelete() */
static void miDbeWindowDestroy(ScreenPtr pScreen, WindowPtr pWin, void *closure);
/******************************************************************************
*
* DBE DIX Procedure: DbeResetProc
@ -1225,55 +1224,30 @@ DbeResetProc(ExtensionEntry * extEntry)
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
if (pDbeScreenPriv) {
/* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */
pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
dixScreenUnhookWindowDestroy(pScreen, miDbeWindowDestroy, NULL);
pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
free(pDbeScreenPriv);
}
}
} /* 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.
**************************************************************************
/**
* @brief window destroy callback
*
* Called by DIX when window is being destroyed.
*
*/
pScreen = pWin->drawable.pScreen;
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
static void miDbeWindowDestroy(ScreenPtr pScreen, WindowPtr pWin, void *closure)
{
/*
**************************************************************************
** 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) {
DbeWindowPrivPtr pDbeWindowPriv;
while ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) {
/* *DbeWinPrivDelete() will free the window private and set it to
* NULL if there are no more buffer IDs associated with this
* window.
@ -1283,36 +1257,6 @@ DbeDestroyWindow(WindowPtr 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
@ -1395,12 +1339,10 @@ DbeExtensionInit(void)
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
if (ddxInitSuccess) {
/* Wrap DestroyWindow. The DDX initialization function
/* Hook in our window destructor. The DDX initialization function
* already wrapped PositionWindow for us.
*/
pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
pScreen->DestroyWindow = DbeDestroyWindow;
dixScreenHookWindowDestroy(pScreen, miDbeWindowDestroy, NULL);
}
else {
/* DDX initialization failed. Stub the screen. */

View File

@ -171,10 +171,8 @@ typedef struct _DbeWindowPrivRec {
typedef struct _DbeScreenPrivRec {
/* Wrapped functions
* It is the responsibility of the DDX layer to wrap PositionWindow().
* DbeExtensionInit wraps DestroyWindow().
*/
PositionWindowProcPtr PositionWindow;
DestroyWindowProcPtr DestroyWindow;
/* Per-screen DIX routines */
Bool (*SetupBackgroundPainter) (WindowPtr /*pWin */ ,

View File

@ -375,9 +375,8 @@ miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
* the resources associated with a DBE buffer ID. There are 5 ways that
* miDbeWinPrivDelete() can be called by FreeResource(). They are:
*
* - A DBE window is destroyed, in which case the DbeDestroyWindow()
* wrapper is invoked. The wrapper calls FreeResource() for all DBE
* buffer IDs.
* - A DBE window is destroyed, in which case the DbeWindowDestroy()
* callback is invoked. It calls FreeResource() for all DBE buffer IDs.
*
* - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
* after a buffer allocation failure.