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

View File

@ -171,10 +171,8 @@ typedef struct _DbeWindowPrivRec {
typedef struct _DbeScreenPrivRec { typedef struct _DbeScreenPrivRec {
/* Wrapped functions /* Wrapped functions
* It is the responsibility of the DDX layer to wrap PositionWindow(). * It is the responsibility of the DDX layer to wrap PositionWindow().
* DbeExtensionInit wraps DestroyWindow().
*/ */
PositionWindowProcPtr PositionWindow; PositionWindowProcPtr PositionWindow;
DestroyWindowProcPtr DestroyWindow;
/* Per-screen DIX routines */ /* Per-screen DIX routines */
Bool (*SetupBackgroundPainter) (WindowPtr /*pWin */ , 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 * the resources associated with a DBE buffer ID. There are 5 ways that
* miDbeWinPrivDelete() can be called by FreeResource(). They are: * miDbeWinPrivDelete() can be called by FreeResource(). They are:
* *
* - A DBE window is destroyed, in which case the DbeDestroyWindow() * - A DBE window is destroyed, in which case the DbeWindowDestroy()
* wrapper is invoked. The wrapper calls FreeResource() for all DBE * callback is invoked. It calls FreeResource() for all DBE buffer IDs.
* buffer IDs.
* *
* - miDbeAllocBackBufferName() calls FreeResource() to clean up resources * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
* after a buffer allocation failure. * after a buffer allocation failure.