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

View File

@ -2,13 +2,15 @@
#include <dix-config.h>
#include <X11/X.h>
#include <X11/Xmd.h>
#include <X11/extensions/shapeproto.h>
#include "dix/cursor_priv.h"
#include "dix/dix_priv.h"
#include "dix/screen_hooks_priv.h"
#include "mi/mi_priv.h"
#include "scrnintstr.h"
#include <X11/extensions/shapeproto.h>
#include "validate.h"
#include "windowstr.h"
#include "gcstruct.h"
@ -45,7 +47,6 @@ typedef struct {
} miOverlayWindowRec, *miOverlayWindowPtr;
typedef struct {
CloseScreenProcPtr CloseScreen;
CreateWindowProcPtr CreateWindow;
DestroyWindowProcPtr DestroyWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
@ -68,7 +69,7 @@ static Bool HasUnderlayChildren(WindowPtr);
static void MarkUnderlayWindow(WindowPtr);
static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
static Bool miOverlayCloseScreen(ScreenPtr);
static void miOverlayCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused);
static Bool miOverlayCreateWindow(WindowPtr);
static Bool miOverlayDestroyWindow(WindowPtr);
static Bool miOverlayUnrealizeWindow(WindowPtr);
@ -127,18 +128,17 @@ miInitOverlay(ScreenPtr pScreen,
return FALSE;
dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv);
dixScreenHookClose(pScreen, miOverlayCloseScreen);
pScreenPriv->InOverlay = inOverlayFunc;
pScreenPriv->MakeTransparent = transFunc;
pScreenPriv->underlayMarked = FALSE;
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreenPriv->CreateWindow = pScreen->CreateWindow;
pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
pScreen->CloseScreen = miOverlayCloseScreen;
pScreen->CreateWindow = miOverlayCreateWindow;
pScreen->DestroyWindow = miOverlayDestroyWindow;
pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
@ -161,20 +161,21 @@ miInitOverlay(ScreenPtr pScreen,
return TRUE;
}
static Bool
miOverlayCloseScreen(ScreenPtr pScreen)
static void miOverlayCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
{
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->DestroyWindow = pScreenPriv->DestroyWindow;
pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
free(pScreenPriv);
return (*pScreen->CloseScreen) (pScreen);
dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, NULL);
}
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/dix_priv.h"
#include "dix/input_priv.h"
#include "dix/screen_hooks_priv.h"
#include "mi/mi_priv.h"
#include "mi/mipointer_priv.h"
@ -107,7 +108,7 @@ static void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen,
BoxPtr pTopLeftBox);
static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
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 Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
@ -140,8 +141,7 @@ miPointerInitialize(ScreenPtr pScreen,
pScreenPriv->screenFuncs = screenFuncs;
pScreenPriv->waitForUpdate = waitForUpdate;
pScreenPriv->showTransparent = FALSE;
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = miPointerCloseScreen;
dixScreenHookClose(pScreen, miPointerCloseScreen);
dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, pScreenPriv);
/*
* set up screen cursor method table
@ -163,19 +163,17 @@ miPointerInitialize(ScreenPtr pScreen,
/**
* Destroy screen-specific information.
*
* @param index Screen index of the screen in screenInfo.screens[]
* @param pScreen The actual screen pointer
*/
static Bool
miPointerCloseScreen(ScreenPtr pScreen)
static void miPointerCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
{
SetupScreen(pScreen);
pScreen->CloseScreen = pScreenPriv->CloseScreen;
dixScreenUnhookClose(pScreen, miPointerCloseScreen);
free((void *) pScreenPriv);
dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, NULL);
FreeEventList(mipointermove_events, GetMaximumEventsNum());
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/dix_priv.h"
#include "dix/screen_hooks_priv.h"
#include "mi/mipointer_priv.h"
#include "misc.h"
@ -72,7 +73,6 @@ typedef struct {
typedef struct {
/* screen procedures */
CloseScreenProcPtr CloseScreen;
SourceValidateProcPtr SourceValidate;
/* window procedures */
@ -190,7 +190,7 @@ miSpriteIsDown(miCursorInfoPtr pDevCursor)
* 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,
int width, int height,
unsigned int subWindowMode);
@ -309,7 +309,6 @@ miSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
for (pVisual = pScreen->visuals;
pVisual->vid != pScreen->rootVisual; pVisual++);
pScreenPriv->pVisual = pVisual;
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreenPriv->SourceValidate = pScreen->SourceValidate;
pScreenPriv->CopyWindow = pScreen->CopyWindow;
@ -332,7 +331,7 @@ miSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
dixSetPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec, pScreenPriv);
pScreen->CloseScreen = miSpriteCloseScreen;
dixScreenHookClose(pScreen, miSpriteCloseScreen);
pScreen->SourceValidate = miSpriteSourceValidate;
pScreen->CopyWindow = miSpriteCopyWindow;
@ -346,26 +345,22 @@ miSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
* Screen wrappers
*/
/*
* CloseScreen wrapper -- unwrap everything, free the private data
* and call the wrapped function
*/
static Bool
miSpriteCloseScreen(ScreenPtr pScreen)
static void miSpriteCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
{
miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen);
dixScreenUnhookClose(pScreen, miSpriteCloseScreen);
miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen);
if (!pScreenPriv)
return;
pScreen->CloseScreen = pScreenPriv->CloseScreen;
pScreen->SourceValidate = pScreenPriv->SourceValidate;
pScreen->InstallColormap = pScreenPriv->InstallColormap;
pScreen->StoreColors = pScreenPriv->StoreColors;
DamageDestroy(pScreenPriv->pDamage);
dixSetPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec, NULL);
free(pScreenPriv);
return (*pScreen->CloseScreen) (pScreen);
}
static void