dbe: use window destructor hook

Wrapping ScreenRec's function pointers is problematic for many reasons,
so use the new window destructor hook instead.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2024-09-20 14:50:24 +02:00
parent 3a0edc36b6
commit 0b0cabb505
3 changed files with 22 additions and 82 deletions

View File

@ -40,6 +40,7 @@
#include <X11/Xproto.h> #include <X11/Xproto.h>
#include "dix/dix_priv.h" #include "dix/dix_priv.h"
#include "dix/screen_hooks_priv.h"
#include "scrnintstr.h" #include "scrnintstr.h"
#include "extnsionst.h" #include "extnsionst.h"
@ -81,11 +82,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 +1199,9 @@ DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
return Success; return Success;
} /* DbeWindowPrivDelete() */ } /* DbeWindowPrivDelete() */
static void miDbeWindowDestroy(CallbackListPtr *pcbl, ScreenPtr pScreen, WindowPtr pWin);
/****************************************************************************** /******************************************************************************
* *
* DBE DIX Procedure: DbeResetProc * DBE DIX Procedure: DbeResetProc
@ -1225,55 +1225,30 @@ 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);
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
{ *
DbeScreenPrivPtr pDbeScreenPriv; * Called by DIX when window is being destroyed.
DbeWindowPrivPtr pDbeWindowPriv; *
ScreenPtr pScreen;
Bool ret;
/*
**************************************************************************
** 1. Unwrap the member routine.
**************************************************************************
*/ */
static void miDbeWindowDestroy(CallbackListPtr *pcbl, ScreenPtr pScreen, WindowPtr pWin)
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.
@ -1283,36 +1258,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 * DBE DIX Procedure: DbeExtensionInit
@ -1395,12 +1340,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);
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.