From 0b0cabb505f7cbcc17537aac5d3ae32b1c13d708 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Fri, 20 Sep 2024 14:50:24 +0200 Subject: [PATCH] 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 --- dbe/dbe.c | 97 ++++++++++--------------------------------------- dbe/dbestruct.h | 2 - dbe/midbe.c | 5 +-- 3 files changed, 22 insertions(+), 82 deletions(-) diff --git a/dbe/dbe.c b/dbe/dbe.c index 0c1f2e589..0ac546ae1 100644 --- a/dbe/dbe.c +++ b/dbe/dbe.c @@ -40,6 +40,7 @@ #include #include "dix/dix_priv.h" +#include "dix/screen_hooks_priv.h" #include "scrnintstr.h" #include "extnsionst.h" @@ -81,11 +82,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 +1199,9 @@ DbeWindowPrivDelete(void *pDbeWinPriv, XID id) return Success; } /* DbeWindowPrivDelete() */ - + +static void miDbeWindowDestroy(CallbackListPtr *pcbl, ScreenPtr pScreen, WindowPtr pWin); + /****************************************************************************** * * DBE DIX Procedure: DbeResetProc @@ -1225,94 +1225,39 @@ DbeResetProc(ExtensionEntry * extEntry) pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); if (pDbeScreenPriv) { - /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */ - pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; + dixScreenUnhookWindowDestroy(pScreen, miDbeWindowDestroy); 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) +/** + * @brief window destroy callback + * + * Called by DIX when window is being destroyed. + * + */ +static void miDbeWindowDestroy(CallbackListPtr *pcbl, ScreenPtr pScreen, 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) { + 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. */ FreeResource(pDbeWindowPriv->IDs[0], X11_RESTYPE_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 @@ -1395,12 +1340,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); } else { /* DDX initialization failed. Stub the screen. */ diff --git a/dbe/dbestruct.h b/dbe/dbestruct.h index ef08118c0..bfecf0266 100644 --- a/dbe/dbestruct.h +++ b/dbe/dbestruct.h @@ -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 */ , diff --git a/dbe/midbe.c b/dbe/midbe.c index 3033062f8..f39a58b22 100644 --- a/dbe/midbe.c +++ b/dbe/midbe.c @@ -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.