diff --git a/dix/dix_priv.h b/dix/dix_priv.h index 1ba1fc451..8e38b8517 100644 --- a/dix/dix_priv.h +++ b/dix/dix_priv.h @@ -323,6 +323,18 @@ void dixScreenRaiseClose(ScreenPtr pScreen); */ void dixScreenRaisePixmapDestroy(PixmapPtr pPixmap); +/* + * @brief call screen's CreateScreenResources chain + * @see dixScreenHookPostCreateResources + * @param pScreen the screen to run on + * + * Call the screen's CreateScreenResources() proc, and if it returns TRUE, + * run the installed hooks afterwards. + * + * Should only be called by DIX itself. + */ +Bool dixScreenRaiseCreateResources(ScreenPtr pScreen); + /* * @brief mark event ID as critical * @param event the event to add to the critical events bitmap diff --git a/dix/main.c b/dix/main.c index 759b8a2a2..55eeda7de 100644 --- a/dix/main.c +++ b/dix/main.c @@ -210,8 +210,7 @@ dix_main(int argc, char *argv[], char *envp[]) ScreenPtr pScreen = screenInfo.gpuscreens[i]; if (!PixmapScreenInit(pScreen)) FatalError("failed to create screen pixmap properties"); - if (pScreen->CreateScreenResources && - !(*pScreen->CreateScreenResources) (pScreen)) + if (!dixScreenRaiseCreateResources(pScreen)) FatalError("failed to create screen resources"); } @@ -220,8 +219,7 @@ dix_main(int argc, char *argv[], char *envp[]) if (!PixmapScreenInit(pScreen)) FatalError("failed to create screen pixmap properties"); - if (pScreen->CreateScreenResources && - !(*pScreen->CreateScreenResources) (pScreen)) + if (!dixScreenRaiseCreateResources(pScreen)) FatalError("failed to create screen resources"); if (!CreateGCperDepth(i)) FatalError("failed to create scratch GCs"); diff --git a/dix/screen_hooks.c b/dix/screen_hooks.c index 64d43ac7e..1c96fa211 100644 --- a/dix/screen_hooks.c +++ b/dix/screen_hooks.c @@ -5,6 +5,8 @@ #include +#include + #include "dix/dix_priv.h" #include "dix/screen_hooks_priv.h" #include "include/dix.h" @@ -27,6 +29,8 @@ DECLARE_HOOK_PROC(WindowDestroy, hookWindowDestroy, XorgScreenWindowDestroyProcP DECLARE_HOOK_PROC(WindowPosition, hookWindowPosition, XorgScreenWindowPositionProcPtr); DECLARE_HOOK_PROC(Close, hookClose, XorgScreenCloseProcPtr); DECLARE_HOOK_PROC(PixmapDestroy, hookPixmapDestroy, XorgScreenPixmapDestroyProcPtr); +DECLARE_HOOK_PROC(PostCreateResources, hookPostCreateResources, + XorgScreenPostCreateResourcesProcPtr); int dixScreenRaiseWindowDestroy(WindowPtr pWin) { @@ -78,3 +82,18 @@ void dixScreenRaisePixmapDestroy(PixmapPtr pPixmap) CallCallbacks(&pScreen->hookPixmapDestroy, pPixmap); /* we must not call the original ScreenRec->DestroyPixmap() here */ } + +Bool dixScreenRaiseCreateResources(ScreenPtr pScreen) +{ + if (!pScreen) + return FALSE; + + if (pScreen->CreateScreenResources) { + if (!pScreen->CreateScreenResources(pScreen)) + return FALSE; + } + + Bool ret = TRUE; + CallCallbacks(&pScreen->hookPostCreateResources, &ret); + return ret; +} diff --git a/dix/screen_hooks_priv.h b/dix/screen_hooks_priv.h index 17754f062..01e4d8d9b 100644 --- a/dix/screen_hooks_priv.h +++ b/dix/screen_hooks_priv.h @@ -20,6 +20,7 @@ #ifndef XORG_DIX_SCREEN_HOOKS_H #define XORG_DIX_SCREEN_HOOKS_H +#include #include #include "include/callback.h" /* CallbackListPtr */ @@ -185,4 +186,36 @@ _X_EXPORT void dixScreenUnhookPixmapDestroy(ScreenPtr pScreen, XorgScreenPixmapDestroyProcPtr func); +/* prototype of screen close notification handler */ +typedef void (*XorgScreenPostCreateResourcesProcPtr)(CallbackListPtr *pcbl, + ScreenPtr pScreen, + Bool *ret); + +/** + * @brief register post-CreateScreenResources 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 + * + * This hook is called when CreateScreenResources() had been called + * and returned TRUE. + **/ +_X_EXPORT +void dixScreenHookPostCreateResources(ScreenPtr pScreen, + XorgScreenPostCreateResourcesProcPtr func); + +/** + * @brief unregister a post-CreateScreenResources 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 dixScreenHookPostCreateResources + **/ +_X_EXPORT +void dixScreenUnhookPostCreateResources(ScreenPtr pScreen, + XorgScreenPostCreateResourcesProcPtr func); + #endif /* DIX_SCREEN_HOOKS_H */ diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index 8b499041b..b57620a58 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -725,8 +725,7 @@ xf86platformAddDevice(const char *driver_name, int index) PixmapScreenInit(xf86GPUScreens[i]->pScreen); - if (xf86GPUScreens[i]->pScreen->CreateScreenResources && - !(*xf86GPUScreens[i]->pScreen->CreateScreenResources) (xf86GPUScreens[i]->pScreen)) { + if (dixScreenRaiseCreateResources(xf86GPUScreens[i]->pScreen)) { RemoveGPUScreen(xf86GPUScreens[i]->pScreen); xf86DeleteScreen(xf86GPUScreens[i]); xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL); diff --git a/include/scrnintstr.h b/include/scrnintstr.h index df7b2d9cf..ebd336bb2 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -683,6 +683,10 @@ typedef struct _Screen { /* additional pixmap destroy notify hooks (replaces wrapping DestroyPixmap) should NOT be touched outside of DIX core */ CallbackListPtr hookPixmapDestroy; + + /* hooks run right after SUCCESSFUL CreateScreenResources + should NOT be touched outside of DIX core */ + CallbackListPtr hookPostCreateResources; } ScreenRec; static inline RegionPtr