diff --git a/dix/dispatch.c b/dix/dispatch.c index 8d6a3addb..2ae5304de 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -111,6 +111,7 @@ Equipment Corporation. #include "dix/registry_priv.h" #include "dix/screenint_priv.h" #include "dix/selection_priv.h" +#include "include/dix_pixmap.h" #include "include/resource.h" #include "miext/extinit_priv.h" #include "os/auth.h" @@ -1470,11 +1471,7 @@ ProcListFontsWithInfo(ClientPtr client) int dixDestroyPixmap(void *value, XID pid) { - PixmapPtr pPixmap = (PixmapPtr) value; - if (pPixmap && pPixmap->refcnt == 1) - dixScreenRaisePixmapDestroy(pPixmap); - if (pPixmap && pPixmap->drawable.pScreen && pPixmap->drawable.pScreen->DestroyPixmap) - return pPixmap->drawable.pScreen->DestroyPixmap(pPixmap); + dixPixmapPut((PixmapPtr) value); return TRUE; } diff --git a/dix/meson.build b/dix/meson.build index 8d4c28494..8a10ab164 100644 --- a/dix/meson.build +++ b/dix/meson.build @@ -21,6 +21,7 @@ srcs_dix = [ 'inpututils.c', 'lookup.c', 'pixmap.c', + 'pixmap_api.c', 'privates.c', 'property.c', 'ptrveloc.c', diff --git a/dix/pixmap_api.c b/dix/pixmap_api.c new file mode 100644 index 000000000..e8cb38cd0 --- /dev/null +++ b/dix/pixmap_api.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: MIT OR X11 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + * + * @brief pixmap lifecycle API + */ +#include + +#include "dix/dix_priv.h" +#include "include/dix_pixmap.h" +#include "include/pixmapstr.h" +#include "include/scrnintstr.h" + +PixmapPtr dixPixmapCreate(ScreenPtr pScreen, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t usage_hint) +{ + if (!pScreen) { + LogMessage(X_ERROR, "dixCreatePixmap() called on NULL screen\n"); + return NULL; + } + + if (!pScreen->CreatePixmap) { + LogMessage(X_ERROR, "dixCreatePixmap() screen->CreatePixmap is NULL\n"); + return NULL; + } + + return pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); +} + +PixmapPtr dixPixmapGet(PixmapPtr pPixmap) +{ + if (pPixmap) + pPixmap->refcnt++; + return pPixmap; +} + +void dixPixmapPut(PixmapPtr pPixmap) +{ + if (pPixmap && pPixmap->refcnt == 1) + dixScreenRaisePixmapDestroy(pPixmap); + if (pPixmap && pPixmap->drawable.pScreen && pPixmap->drawable.pScreen->DestroyPixmap) + pPixmap->drawable.pScreen->DestroyPixmap(pPixmap); +} diff --git a/doc/Xserver-spec.xml b/doc/Xserver-spec.xml index 8be223e07..914282072 100644 --- a/doc/Xserver-spec.xml +++ b/doc/Xserver-spec.xml @@ -3057,7 +3057,7 @@ must deallocate the PixmapRec and all attached devPrivate blocks. If successful, it returns TRUE. See Xserver/fb/fbpixmap.c for the sample server implementation. -Consumers should never ever call that proc directly, but call dixDestroyPixmap() instead. +Consumers should never ever call that proc directly, but call dixPixmapPut() instead.
diff --git a/include/dix_pixmap.h b/include/dix_pixmap.h new file mode 100644 index 000000000..0490ad50f --- /dev/null +++ b/include/dix_pixmap.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: MIT OR X11 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + * + * @brief generic pixmap functions + * + * These functions replacing directly calling into ScreenRec vectors and also + * take care of calling hooks. + + * NOTE: The ScreenProc vectors should never be called directly anymore, + * otherwise hooks might not be called. + */ +#ifndef DIX_PIXMAP_H +#define DIX_PIXMAP_H + +#include + +#include "pixmap.h" /* PixmapPtr */ +#include "screenint.h" /* ScreenPtr */ +#include "window.h" /* WindowPtr */ + +/* + * @brief create a pixmap on specified screen + * + * Call into driver and hooks for creating a pixmap with given geometry. + * + * @param pScreen the screen to create the pixmap on + * @param width width of the new pixmap + * @param height height of the new pixmap + * @param depth color depth of the new pixmap + * @param usage_hints allocation hints - see CREATE_PIXMAP_USAGE_* defines + * @result pointer to new pixmap or NULL on failure + */ +_X_EXPORT PixmapPtr dixPixmapCreate(ScreenPtr pScreen, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t usage_hint); + +/* + * @brief increase pixmap reference counter + * + * Increase the pixmap's reference counter. + * + * @param pPixmap the pixmap who's reference counter is increased + * @return the original pPixmap value (for function chaining) + */ +_X_EXPORT PixmapPtr dixPixmapGet(PixmapPtr pPixmap); + +/* + * @brief decrease reference counter and potentially release it + * + * Decrease the pixmap's reference counter. If it reaches zero, destroy it. + * + * @param pPixmap the pixmap to release (NULL protected) + */ +_X_EXPORT void dixPixmapPut(PixmapPtr pPixmap); + +#endif /* DIX_PIXMAP_H */ diff --git a/include/meson.build b/include/meson.build index 677c22a74..1e71afe26 100644 --- a/include/meson.build +++ b/include/meson.build @@ -437,6 +437,7 @@ if build_xorg 'cursorstr.h', 'dix.h', 'dix_screen_hooks.h', + 'dix_pixmap.h', 'dixaccess.h', 'dixevents.h', 'dixfont.h', diff --git a/include/xorg-server.h.meson.in b/include/xorg-server.h.meson.in index 60dbb5dbe..839c7f41e 100644 --- a/include/xorg-server.h.meson.in +++ b/include/xorg-server.h.meson.in @@ -215,5 +215,6 @@ #define XORG_API_DIX_SCREEN_HOOK_WINDOW_POSITION 1 #define XORG_API_DIX_SCREEN_HOOK_CLOSE 1 #define XORG_API_DIX_SCREEN_HOOK_PIXMAP_DESTROY 1 +#define XORG_API_DIX_PIXMAP_LIFETIME 1 #endif /* _XORG_SERVER_H_ */