mi: use CloseScreen hook

Wrapping ScreenRec's function pointers is problematic for many reasons,
so use the new screen close notify hook instead.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-04-28 13:00:41 +02:00
parent 5a4656a731
commit 56aad1434b
4 changed files with 37 additions and 45 deletions

View File

@ -35,6 +35,7 @@ in this Software without prior written authorization from The Open Group.
#include "dix/dix_priv.h" #include "dix/dix_priv.h"
#include "dix/gc_priv.h" #include "dix/gc_priv.h"
#include "dix/screen_hooks_priv.h"
#include "misc.h" #include "misc.h"
#include "input.h" #include "input.h"
@ -59,7 +60,7 @@ static DevScreenPrivateKeyRec miDCDeviceKeyRec;
#define miDCDeviceKey (&miDCDeviceKeyRec) #define miDCDeviceKey (&miDCDeviceKeyRec)
static Bool miDCCloseScreen(ScreenPtr pScreen); static void miDCCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused);
/* per device private data */ /* per device private data */
typedef struct { typedef struct {
@ -79,7 +80,6 @@ typedef struct {
* in the pCursorBuffers array. * in the pCursorBuffers array.
*/ */
typedef struct { typedef struct {
CloseScreenProcPtr CloseScreen;
PixmapPtr sourceBits; /* source bits */ PixmapPtr sourceBits; /* source bits */
PixmapPtr maskBits; /* mask bits */ PixmapPtr maskBits; /* mask bits */
PicturePtr pPicture; PicturePtr pPicture;
@ -102,9 +102,7 @@ miDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
if (!pScreenPriv) if (!pScreenPriv)
return FALSE; return FALSE;
pScreenPriv->CloseScreen = pScreen->CloseScreen; dixScreenHookClose(pScreen, miDCCloseScreen);
pScreen->CloseScreen = miDCCloseScreen;
dixSetPrivate(&pScreen->devPrivates, miDCScreenKey, pScreenPriv); dixSetPrivate(&pScreen->devPrivates, miDCScreenKey, pScreenPriv);
if (!miSpriteInitialize(pScreen, screenFuncs)) { if (!miSpriteInitialize(pScreen, screenFuncs)) {
@ -118,6 +116,8 @@ static void
miDCSwitchScreenCursor(ScreenPtr pScreen, CursorPtr pCursor, PixmapPtr sourceBits, PixmapPtr maskBits, PicturePtr pPicture) miDCSwitchScreenCursor(ScreenPtr pScreen, CursorPtr pCursor, PixmapPtr sourceBits, PixmapPtr maskBits, PicturePtr pPicture)
{ {
miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey); miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
if (!pScreenPriv)
return;
dixDestroyPixmap(pScreenPriv->sourceBits, 0); dixDestroyPixmap(pScreenPriv->sourceBits, 0);
pScreenPriv->sourceBits = sourceBits; pScreenPriv->sourceBits = sourceBits;
@ -133,18 +133,16 @@ miDCSwitchScreenCursor(ScreenPtr pScreen, CursorPtr pCursor, PixmapPtr sourceBit
pScreenPriv->pCursor = pCursor; pScreenPriv->pCursor = pCursor;
} }
static Bool static void miDCCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
miDCCloseScreen(ScreenPtr pScreen)
{ {
miDCScreenPtr pScreenPriv; dixScreenUnhookClose(pScreen, miDCCloseScreen);
miDCScreenPtr pScreenPriv;
pScreenPriv = (miDCScreenPtr) dixLookupPrivate(&pScreen->devPrivates, pScreenPriv = (miDCScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
miDCScreenKey); miDCScreenKey);
pScreen->CloseScreen = pScreenPriv->CloseScreen;
miDCSwitchScreenCursor(pScreen, NULL, NULL, NULL, NULL); miDCSwitchScreenCursor(pScreen, NULL, NULL, NULL, NULL);
free((void *) pScreenPriv); free((void *) pScreenPriv);
return (*pScreen->CloseScreen) (pScreen); dixSetPrivate(&pScreen->devPrivates, miDCScreenKey, NULL); /* clear it, just for sure */
} }
Bool Bool

View File

@ -2,13 +2,15 @@
#include <dix-config.h> #include <dix-config.h>
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xmd.h>
#include <X11/extensions/shapeproto.h>
#include "dix/cursor_priv.h" #include "dix/cursor_priv.h"
#include "dix/dix_priv.h" #include "dix/dix_priv.h"
#include "dix/screen_hooks_priv.h"
#include "mi/mi_priv.h" #include "mi/mi_priv.h"
#include "scrnintstr.h" #include "scrnintstr.h"
#include <X11/extensions/shapeproto.h>
#include "validate.h" #include "validate.h"
#include "windowstr.h" #include "windowstr.h"
#include "gcstruct.h" #include "gcstruct.h"
@ -45,7 +47,6 @@ typedef struct {
} miOverlayWindowRec, *miOverlayWindowPtr; } miOverlayWindowRec, *miOverlayWindowPtr;
typedef struct { typedef struct {
CloseScreenProcPtr CloseScreen;
CreateWindowProcPtr CreateWindow; CreateWindowProcPtr CreateWindow;
DestroyWindowProcPtr DestroyWindow; DestroyWindowProcPtr DestroyWindow;
UnrealizeWindowProcPtr UnrealizeWindow; UnrealizeWindowProcPtr UnrealizeWindow;
@ -68,7 +69,7 @@ static Bool HasUnderlayChildren(WindowPtr);
static void MarkUnderlayWindow(WindowPtr); static void MarkUnderlayWindow(WindowPtr);
static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr); static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
static Bool miOverlayCloseScreen(ScreenPtr); static void miOverlayCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused);
static Bool miOverlayCreateWindow(WindowPtr); static Bool miOverlayCreateWindow(WindowPtr);
static Bool miOverlayDestroyWindow(WindowPtr); static Bool miOverlayDestroyWindow(WindowPtr);
static Bool miOverlayUnrealizeWindow(WindowPtr); static Bool miOverlayUnrealizeWindow(WindowPtr);
@ -127,18 +128,17 @@ miInitOverlay(ScreenPtr pScreen,
return FALSE; return FALSE;
dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv); dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv);
dixScreenHookClose(pScreen, miOverlayCloseScreen);
pScreenPriv->InOverlay = inOverlayFunc; pScreenPriv->InOverlay = inOverlayFunc;
pScreenPriv->MakeTransparent = transFunc; pScreenPriv->MakeTransparent = transFunc;
pScreenPriv->underlayMarked = FALSE; pScreenPriv->underlayMarked = FALSE;
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreenPriv->CreateWindow = pScreen->CreateWindow; pScreenPriv->CreateWindow = pScreen->CreateWindow;
pScreenPriv->DestroyWindow = pScreen->DestroyWindow; pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow; pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
pScreenPriv->RealizeWindow = pScreen->RealizeWindow; pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
pScreen->CloseScreen = miOverlayCloseScreen;
pScreen->CreateWindow = miOverlayCreateWindow; pScreen->CreateWindow = miOverlayCreateWindow;
pScreen->DestroyWindow = miOverlayDestroyWindow; pScreen->DestroyWindow = miOverlayDestroyWindow;
pScreen->UnrealizeWindow = miOverlayUnrealizeWindow; pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
@ -161,20 +161,21 @@ miInitOverlay(ScreenPtr pScreen,
return TRUE; return TRUE;
} }
static Bool static void miOverlayCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
miOverlayCloseScreen(ScreenPtr pScreen)
{ {
miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); dixScreenUnhookClose(pScreen, miOverlayCloseScreen);
miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
if (!pScreenPriv)
return;
pScreen->CloseScreen = pScreenPriv->CloseScreen;
pScreen->CreateWindow = pScreenPriv->CreateWindow; pScreen->CreateWindow = pScreenPriv->CreateWindow;
pScreen->DestroyWindow = pScreenPriv->DestroyWindow; pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow; pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
pScreen->RealizeWindow = pScreenPriv->RealizeWindow; pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
free(pScreenPriv); free(pScreenPriv);
dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, NULL);
return (*pScreen->CloseScreen) (pScreen);
} }
static Bool static Bool

View File

@ -55,6 +55,7 @@ in this Software without prior written authorization from The Open Group.
#include "dix/cursor_priv.h" #include "dix/cursor_priv.h"
#include "dix/dix_priv.h" #include "dix/dix_priv.h"
#include "dix/input_priv.h" #include "dix/input_priv.h"
#include "dix/screen_hooks_priv.h"
#include "mi/mi_priv.h" #include "mi/mi_priv.h"
#include "mi/mipointer_priv.h" #include "mi/mipointer_priv.h"
@ -107,7 +108,7 @@ static void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen,
BoxPtr pTopLeftBox); BoxPtr pTopLeftBox);
static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
int x, int y, Bool generateEvent); int x, int y, Bool generateEvent);
static Bool miPointerCloseScreen(ScreenPtr pScreen); static void miPointerCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused);
static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
@ -140,8 +141,7 @@ miPointerInitialize(ScreenPtr pScreen,
pScreenPriv->screenFuncs = screenFuncs; pScreenPriv->screenFuncs = screenFuncs;
pScreenPriv->waitForUpdate = waitForUpdate; pScreenPriv->waitForUpdate = waitForUpdate;
pScreenPriv->showTransparent = FALSE; pScreenPriv->showTransparent = FALSE;
pScreenPriv->CloseScreen = pScreen->CloseScreen; dixScreenHookClose(pScreen, miPointerCloseScreen);
pScreen->CloseScreen = miPointerCloseScreen;
dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, pScreenPriv); dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, pScreenPriv);
/* /*
* set up screen cursor method table * set up screen cursor method table
@ -163,19 +163,17 @@ miPointerInitialize(ScreenPtr pScreen,
/** /**
* Destroy screen-specific information. * Destroy screen-specific information.
* *
* @param index Screen index of the screen in screenInfo.screens[]
* @param pScreen The actual screen pointer * @param pScreen The actual screen pointer
*/ */
static Bool static void miPointerCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
miPointerCloseScreen(ScreenPtr pScreen)
{ {
SetupScreen(pScreen); SetupScreen(pScreen);
pScreen->CloseScreen = pScreenPriv->CloseScreen; dixScreenUnhookClose(pScreen, miPointerCloseScreen);
free((void *) pScreenPriv); free((void *) pScreenPriv);
dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, NULL);
FreeEventList(mipointermove_events, GetMaximumEventsNum()); FreeEventList(mipointermove_events, GetMaximumEventsNum());
mipointermove_events = NULL; mipointermove_events = NULL;
return (*pScreen->CloseScreen) (pScreen);
} }
/* /*

View File

@ -38,6 +38,7 @@ in this Software without prior written authorization from The Open Group.
#include "dix/colormap_priv.h" #include "dix/colormap_priv.h"
#include "dix/dix_priv.h" #include "dix/dix_priv.h"
#include "dix/screen_hooks_priv.h"
#include "mi/mipointer_priv.h" #include "mi/mipointer_priv.h"
#include "misc.h" #include "misc.h"
@ -72,7 +73,6 @@ typedef struct {
typedef struct { typedef struct {
/* screen procedures */ /* screen procedures */
CloseScreenProcPtr CloseScreen;
SourceValidateProcPtr SourceValidate; SourceValidateProcPtr SourceValidate;
/* window procedures */ /* window procedures */
@ -190,7 +190,7 @@ miSpriteIsDown(miCursorInfoPtr pDevCursor)
* screen wrappers * screen wrappers
*/ */
static Bool miSpriteCloseScreen(ScreenPtr pScreen); static void miSpriteCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused);
static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
int width, int height, int width, int height,
unsigned int subWindowMode); unsigned int subWindowMode);
@ -309,7 +309,6 @@ miSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
for (pVisual = pScreen->visuals; for (pVisual = pScreen->visuals;
pVisual->vid != pScreen->rootVisual; pVisual++); pVisual->vid != pScreen->rootVisual; pVisual++);
pScreenPriv->pVisual = pVisual; pScreenPriv->pVisual = pVisual;
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreenPriv->SourceValidate = pScreen->SourceValidate; pScreenPriv->SourceValidate = pScreen->SourceValidate;
pScreenPriv->CopyWindow = pScreen->CopyWindow; pScreenPriv->CopyWindow = pScreen->CopyWindow;
@ -332,7 +331,7 @@ miSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
dixSetPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec, pScreenPriv); dixSetPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec, pScreenPriv);
pScreen->CloseScreen = miSpriteCloseScreen; dixScreenHookClose(pScreen, miSpriteCloseScreen);
pScreen->SourceValidate = miSpriteSourceValidate; pScreen->SourceValidate = miSpriteSourceValidate;
pScreen->CopyWindow = miSpriteCopyWindow; pScreen->CopyWindow = miSpriteCopyWindow;
@ -346,26 +345,22 @@ miSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
* Screen wrappers * Screen wrappers
*/ */
/* static void miSpriteCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
* CloseScreen wrapper -- unwrap everything, free the private data
* and call the wrapped function
*/
static Bool
miSpriteCloseScreen(ScreenPtr pScreen)
{ {
miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); dixScreenUnhookClose(pScreen, miSpriteCloseScreen);
miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen);
if (!pScreenPriv)
return;
pScreen->CloseScreen = pScreenPriv->CloseScreen;
pScreen->SourceValidate = pScreenPriv->SourceValidate; pScreen->SourceValidate = pScreenPriv->SourceValidate;
pScreen->InstallColormap = pScreenPriv->InstallColormap; pScreen->InstallColormap = pScreenPriv->InstallColormap;
pScreen->StoreColors = pScreenPriv->StoreColors; pScreen->StoreColors = pScreenPriv->StoreColors;
DamageDestroy(pScreenPriv->pDamage); DamageDestroy(pScreenPriv->pDamage);
dixSetPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec, NULL);
free(pScreenPriv); free(pScreenPriv);
return (*pScreen->CloseScreen) (pScreen);
} }
static void static void