(!1714) dix: add per-screen close notify hook
Right now, extension specific actions on screen closing implemented by wrapping the ScreenRec's PositionWindow() proc pointer: the extensions are storing the original pointer in their private data and putting in their own one. On each call, their proc restores the original one, calls it, and switches back again. When multiple extensions doing so, they're forming a kind of daisy chain. (the same is done for lots of other procs) While that approach is looking nice and elegant on the drawing board, it's complicated, dangerous like a chainsaw and makes debugging hard, leading to pretty blurred API borders. This commit introduces a simple approach for letting extension hook into the screen closing path safely, w/o having to care much about side effects with the call chain. Extensions now can simply register their hook proc (and an opaque pointer) and get called back - w/o ever having to mess with the ScreenRec's internal structures. These hooks are called before the original vector (usually handled by DDX/screen driver directly) is called. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
parent
33abdc49cf
commit
11b536415c
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue