mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-25 12:49:21 +00:00
Right now, extension specific pixmap destruction procedures are implemented by wrapping the ScreenRec's DestroyPixmap() 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. It's even getting worse: the proc also has to do ref counting, and only destroy the pixmap if refconter reaching zero - that's all done in the individual screen drivers. Therefore, all extensions must check for refcnt == 1, in order to know when to really act. This commit introduces a simple approach for letting extension hook into the pixmap destruction safely, w/o having to care much about side effects with the call chain. Extensions now can simply register their destructor proc (and an opaque pointer) and get called back - w/o ever having to mess with the ScreenRec's internal structures. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
180 lines
6.9 KiB
C
180 lines
6.9 KiB
C
/* SPDX-License-Identifier: MIT OR X11
|
|
*
|
|
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
|
|
*
|
|
* @brief exported API entry points for hooking into screen operations
|
|
*
|
|
* These hooks are replacing the old, complicated approach of wrapping
|
|
* ScreenRec's proc vectors. Unlike the wrapping, these hooks are designed
|
|
* to be safe against changes in setup/teardown order and are called
|
|
* independently of the ScreenProc call vectors. It is guaranteed that the
|
|
* objects to operate on already/still exist (eg. destructors are callled
|
|
* before the object is actually destroyed, while post-create hooks are
|
|
* called after the object is created)
|
|
*
|
|
* Main consumers are extensions that need to associate extra data or
|
|
* doing other things additional to the original operation. In some cases
|
|
* they might even be used in drivers (in order to split device specific
|
|
* from generic logic)
|
|
*/
|
|
#ifndef DIX_SCREEN_HOOKS_H
|
|
#define DIX_SCREEN_HOOKS_H
|
|
|
|
#include <X11/Xfuncproto.h>
|
|
|
|
#include "screenint.h" /* ScreenPtr */
|
|
#include "window.h" /* WindowPtr */
|
|
|
|
/* prototype of a window destructor */
|
|
typedef void (*XorgWindowDestroyProcPtr)(ScreenPtr pScreen,
|
|
WindowPtr pWindow,
|
|
void *arg);
|
|
|
|
/**
|
|
* @brief register a window on the given screen
|
|
*
|
|
* @param pScreen pointer to the screen to register the destructor into
|
|
* @param func pointer to the window destructor function
|
|
* @param arg opaque pointer passed to the destructor
|
|
*
|
|
* Window destructors are the replacement for fragile and complicated wrapping of
|
|
* pScreen->DestroyWindow(): extensions can safely register there custom destructors
|
|
* here, without ever caring about anybody else.
|
|
+
|
|
* The destructors are run right before pScreen->DestroyWindow() - when the window
|
|
* is already removed from hierarchy (thus cannot receive any events anymore) and
|
|
* most of it's data already destroyed - and supposed to do necessary per-extension
|
|
* cleanup duties. Their execution order is *unspecified*.
|
|
*
|
|
* Screen drivers (DDX'es, xf86 video drivers, ...) shall not use these, but still
|
|
* set the pScreen->DestroyWindow pointer - and these should be the *only* ones
|
|
* ever setting it.
|
|
*
|
|
* When registration fails, the server aborts.
|
|
*
|
|
**/
|
|
_X_EXPORT void dixScreenHookWindowDestroy(ScreenPtr pScreen,
|
|
XorgWindowDestroyProcPtr func,
|
|
void *arg);
|
|
|
|
/**
|
|
* @brief unregister a window destructor on the given screen
|
|
*
|
|
* @param pScreen pointer to the screen to unregister the destructor from
|
|
* @param func pointer to the window destructor function
|
|
* @param arg opaque pointer passed to the destructor
|
|
*
|
|
* @see dixScreenHookWindowDestroy
|
|
*
|
|
* Unregister a window destructor hook registered via @ref dixScreenHookWindowDestroy
|
|
**/
|
|
_X_EXPORT void dixScreenUnhookWindowDestroy(ScreenPtr pScreen,
|
|
XorgWindowDestroyProcPtr func,
|
|
void *arg);
|
|
|
|
/* prototype of a window move notification handler */
|
|
typedef void (*XorgWindowPositionProcPtr)(ScreenPtr pScreen,
|
|
WindowPtr pWindow,
|
|
void *arg,
|
|
int32_t x,
|
|
int32_t y);
|
|
|
|
/**
|
|
* @brief register a position notify hook on the given screen
|
|
*
|
|
* @param pScreen pointer to the screen to register the notify hook into
|
|
* @param func pointer to the window hook function
|
|
* @param arg opaque pointer passed to the hook
|
|
*
|
|
* When registration fails, the server aborts.
|
|
*
|
|
**/
|
|
_X_EXPORT void dixScreenHookWindowPosition(ScreenPtr pScreen,
|
|
XorgWindowPositionProcPtr func,
|
|
void *arg);
|
|
|
|
/**
|
|
* @brief unregister a window position 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 dixScreenHookWindowPosition
|
|
*
|
|
* Unregister a window position notify hook registered via @ref dixScreenHookWindowPosition
|
|
**/
|
|
_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);
|
|
|
|
/* prototype of pixmap destroy notification handler */
|
|
typedef void (*XorgScreenPixmapDestroyProcPtr)(ScreenPtr pScreen,
|
|
PixmapPtr pPixmap,
|
|
void *arg);
|
|
|
|
/**
|
|
* @brief register a pixmap destroy 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.
|
|
* This hook is called only when the pixmap is really to be destroyed,
|
|
* (unlike ScreenRec->DestroyPixmap())
|
|
*
|
|
**/
|
|
_X_EXPORT void dixScreenHookPixmapDestroy(ScreenPtr pScreen,
|
|
XorgScreenPixmapDestroyProcPtr func,
|
|
void *arg);
|
|
|
|
/**
|
|
* @brief unregister a pixmap destroy 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 dixScreenHookPixmapDestroy
|
|
**/
|
|
_X_EXPORT void dixScreenUnhookPixmapDestroy(ScreenPtr pScreen,
|
|
XorgScreenPixmapDestroyProcPtr func,
|
|
void *arg);
|
|
|
|
#endif /* DIX_SCREEN_HOOKS_H */
|