diff --git a/dix/dix_priv.h b/dix/dix_priv.h index bcf150355..3e85cb17a 100644 --- a/dix/dix_priv.h +++ b/dix/dix_priv.h @@ -282,4 +282,16 @@ int dixScreenRaiseWindowDestroy(WindowPtr pWin); */ void dixScreenRaiseWindowPosition(WindowPtr pWin, uint32_t x, uint32_t y); +/* + * @brief call screen's close hooks + * @see dixScreenHookClose + * @param pScreen the screen being closed + * + * Call the pluggable screen close hooks that extensions might have registered on + * the screen, and finally call ScreenRec's CloseScreen proc. + * + * Should only be called by DIX itself. + */ +void dixScreenRaiseClose(ScreenPtr pScreen); + #endif /* _XSERVER_DIX_PRIV_H */ diff --git a/dix/screen.c b/dix/screen.c index 4458c7250..4b3a25ea0 100644 --- a/dix/screen.c +++ b/dix/screen.c @@ -22,5 +22,6 @@ void dixFreeScreen(ScreenPtr pScreen) dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); DeleteCallbackList(&pScreen->hookWindowDestroy); DeleteCallbackList(&pScreen->hookWindowPosition); + DeleteCallbackList(&pScreen->hookClose); free(pScreen); } diff --git a/dix/screen_hooks.c b/dix/screen_hooks.c index 608e0457d..2b6417245 100644 --- a/dix/screen_hooks.c +++ b/dix/screen_hooks.c @@ -24,6 +24,7 @@ DECLARE_HOOK_PROC(WindowDestroy, hookWindowDestroy, XorgScreenWindowDestroyProcPtr); DECLARE_HOOK_PROC(WindowPosition, hookWindowPosition, XorgScreenWindowPositionProcPtr); +DECLARE_HOOK_PROC(Close, hookClose, XorgScreenCloseProcPtr); int dixScreenRaiseWindowDestroy(WindowPtr pWin) { @@ -55,3 +56,13 @@ void dixScreenRaiseWindowPosition(WindowPtr pWin, uint32_t x, uint32_t y) if (pScreen->PositionWindow) pScreen->PositionWindow(pWin, x, y); } + +void dixScreenRaiseClose(ScreenPtr pScreen) { + if (!pScreen) + return; + + CallCallbacks(&pScreen->hookClose, NULL); + + if (pScreen->CloseScreen) + pScreen->CloseScreen(pScreen); +} diff --git a/include/dix_screen_hooks.h b/include/dix_screen_hooks.h index b322a727c..6ea5bcb00 100644 --- a/include/dix_screen_hooks.h +++ b/include/dix_screen_hooks.h @@ -22,6 +22,8 @@ #include +#include "include/callback.h" + #include "screenint.h" /* ScreenPtr */ #include "window.h" /* WindowPtr */ @@ -108,4 +110,35 @@ _X_EXPORT void dixScreenHookWindowPosition(ScreenPtr pScreen, _X_EXPORT void dixScreenUnhookWindowPosition(ScreenPtr pScreen, XorgScreenWindowPositionProcPtr func); +/* prototype of screen close notification handler */ +typedef void (*XorgScreenCloseProcPtr)(CallbackListPtr *pcbl, + ScreenPtr pScreen, + void *unused); + +/** + * @brief register a screen close notify hook on the given screen + * + * @param pScreen pointer to the screen to register the notify hook into + * @param func pointer to the hook function + * + * When registration fails, the server aborts. + * + **/ +_X_EXPORT void dixScreenHookClose(ScreenPtr pScreen, + XorgScreenCloseProcPtr func); + +/** + * @brief unregister a screen close notify hook on the given screen + * + * @param pScreen pointer to the screen to unregister the hook from + * @param func pointer to the hook function + * @param arg opaque pointer passed to the destructor + * + * @see dixScreenHookClose + * + * Unregister a screen close notify hook registered via @ref dixScreenHookClose + **/ +_X_EXPORT void dixScreenUnhookClose(ScreenPtr pScreen, + XorgScreenCloseProcPtr func); + #endif /* DIX_SCREEN_HOOKS_H */ diff --git a/include/scrnintstr.h b/include/scrnintstr.h index ae543536a..ce8898f69 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -677,6 +677,10 @@ typedef struct _Screen { /* additional window position notify hooks (replaces wrapping PositionWindow) should NOT be touched outside of DIX core */ CallbackListPtr hookWindowPosition; + + /* additional screen close notify hooks (replaces wrapping CloseScreen) + should NOT be touched outside of DIX core */ + CallbackListPtr hookClose; } ScreenRec; static inline RegionPtr diff --git a/include/xorg-server.h.meson.in b/include/xorg-server.h.meson.in index 58bada923..179e31a31 100644 --- a/include/xorg-server.h.meson.in +++ b/include/xorg-server.h.meson.in @@ -217,5 +217,6 @@ /* announce server API features */ #define XORG_API_DIX_SCREEN_HOOK_WINDOW_DESTROY 1 #define XORG_API_DIX_SCREEN_HOOK_WINDOW_POSITION 1 +#define XORG_API_DIX_SCREEN_HOOK_CLOSE 1 #endif /* _XORG_SERVER_H_ */