diff --git a/dix/dix_priv.h b/dix/dix_priv.h index ed00e4f3a..b15fa1021 100644 --- a/dix/dix_priv.h +++ b/dix/dix_priv.h @@ -278,4 +278,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_hooks.c b/dix/screen_hooks.c index 2ac4ce3f6..164345f01 100644 --- a/dix/screen_hooks.c +++ b/dix/screen_hooks.c @@ -42,6 +42,7 @@ DECLARE_HOOK_LIST(WindowDestroy, _notify_window_destroy) DECLARE_HOOK_LIST(WindowPosition, _notify_window_position) +DECLARE_HOOK_LIST(Close, _notify_screen_close) int dixScreenRaiseWindowDestroy(WindowPtr pWin) { @@ -72,3 +73,17 @@ 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; + + ARRAY_FOR_EACH(pScreen->_notify_screen_close, walk) { + if (walk.ptr->func) + walk.ptr->func(pScreen, walk.ptr->arg); + } + + if (pScreen->CloseScreen) + (*pScreen->CloseScreen) (pScreen); +} diff --git a/include/dix_screen_hooks.h b/include/dix_screen_hooks.h index f896c21e6..3b641885d 100644 --- a/include/dix_screen_hooks.h +++ b/include/dix_screen_hooks.h @@ -108,4 +108,36 @@ _X_EXPORT void dixScreenUnhookWindowPosition(ScreenPtr pScreen, XorgWindowPositionProcPtr func, void *arg); +/* prototype of screen close notification handler */ +typedef void (*XorgScreenCloseProcPtr)(ScreenPtr pScreen, void *arg); + +/** + * @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 + * @param arg opaque pointer passed to the hook + * + * When registration fails, the server aborts. + * + **/ +_X_EXPORT void dixScreenHookClose(ScreenPtr pScreen, + XorgScreenCloseProcPtr func, + void *arg); + +/** + * @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, + void *arg); + #endif /* DIX_SCREEN_HOOKS_H */ diff --git a/include/scrnintstr.h b/include/scrnintstr.h index ae4059f93..b135851f9 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -565,6 +565,10 @@ typedef struct _Screen { should NOT be touched outside of DIX core */ _SCREEN_HOOK_TYPE(_notify_window_position, XorgWindowPositionProcPtr, 4); + /* additional screen close notify hooks (replaces wrapping CloseScreen) + should NOT be touched outside of DIX core */ + _SCREEN_HOOK_TYPE(_notify_screen_close, XorgScreenCloseProcPtr, 8); + /* Pixmap procedures */ CreatePixmapProcPtr CreatePixmap; 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_ */