diff options
author | Kyle Brenneman <kbrenneman@nvidia.com> | 2016-03-07 13:52:19 -0700 |
---|---|---|
committer | Kyle Brenneman <kbrenneman@nvidia.com> | 2016-03-24 12:44:25 -0600 |
commit | 3f4674f8f66bf9dfa897e182f7936c2ae47e3850 (patch) | |
tree | cf81ab0c3d44a779805fd3290728b7a18fcf9d70 | |
parent | af2aeb0b4293e085ad61eae08be34e52f9d7b389 (diff) |
GLX: Use XESetCloseDisplay for the close display callback.
libGLX will now use XAddExtension and XESetCloseDisplay to register a callback
when a display is closed.
Removed XGLVRegisterCloseDisplayCallback and
XGLVUnregisterCloseDisplayCallbacks from the x11glvnd client library.
This is in preparation for removing the x11glvnd extension.
-rw-r--r-- | src/GLX/libglx.c | 10 | ||||
-rw-r--r-- | src/GLX/libglxmapping.c | 29 | ||||
-rw-r--r-- | src/GLX/libglxmapping.h | 6 | ||||
-rw-r--r-- | src/x11glvnd/x11glvnd.h | 14 | ||||
-rw-r--r-- | src/x11glvnd/x11glvndclient.c | 59 |
5 files changed, 37 insertions, 81 deletions
diff --git a/src/GLX/libglx.c b/src/GLX/libglx.c index 3c19831..4344231 100644 --- a/src/GLX/libglx.c +++ b/src/GLX/libglx.c @@ -549,10 +549,9 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext context) } } -void DisplayClosed(Display *dpy) +void __glXDisplayClosed(Display *dpy, __GLXdisplayInfo *dpyInfo) { __GLXAPIState *apiState; - __glXFreeDisplay(dpy); apiState = __glXGetCurrentAPIState(); if (apiState != NULL && apiState->currentDisplay == dpy) { @@ -2026,9 +2025,6 @@ void _init(void) /* TODO install fork handlers using __register_atfork */ - /* Register our XCloseDisplay() callback */ - XGLVRegisterCloseDisplayCallback(DisplayClosed); - DBG_PRINTF(0, "Loading GLX...\n"); } @@ -2053,10 +2049,6 @@ void _fini(void) __glDispatchLoseCurrent(); } - - /* Unregister all XCloseDisplay() callbacks */ - XGLVUnregisterCloseDisplayCallbacks(); - /* Tear down all GLX API state */ __glXAPITeardown(False); diff --git a/src/GLX/libglxmapping.c b/src/GLX/libglxmapping.c index 67d5d7d..48add91 100644 --- a/src/GLX/libglxmapping.c +++ b/src/GLX/libglxmapping.c @@ -722,6 +722,25 @@ static void CleanupDisplayInfoEntry(void *unused, __GLXdisplayInfoHash *pEntry) pEntry->info.xidVendorHash, NULL, NULL, False); } +static int OnDisplayClosed(Display *dpy, XExtCodes *codes) +{ + __GLXdisplayInfoHash *pEntry = NULL; + + LKDHASH_WRLOCK(__glXDisplayInfoHash); + + HASH_FIND_PTR(_LH(__glXDisplayInfoHash), &dpy, pEntry); + if (pEntry != NULL) { + __glXDisplayClosed(dpy, &pEntry->info); + HASH_DEL(_LH(__glXDisplayInfoHash), pEntry); + } + LKDHASH_UNLOCK(__glXDisplayInfoHash); + + CleanupDisplayInfoEntry(NULL, pEntry); + free(pEntry); + + return 0; +} + __GLXdisplayInfo *__glXLookupDisplay(Display *dpy) { __GLXdisplayInfoHash *pEntry = NULL; @@ -750,9 +769,19 @@ __GLXdisplayInfo *__glXLookupDisplay(Display *dpy) LKDHASH_WRLOCK(__glXDisplayInfoHash); HASH_FIND_PTR(_LH(__glXDisplayInfoHash), &dpy, foundEntry); if (foundEntry == NULL) { + XExtCodes *extCodes = XAddExtension(dpy); + if (extCodes == NULL) { + CleanupDisplayInfoEntry(NULL, pEntry); + free(pEntry); + LKDHASH_UNLOCK(__glXDisplayInfoHash); + return NULL; + } + + XESetCloseDisplay(dpy, extCodes->extension, OnDisplayClosed); HASH_ADD_PTR(_LH(__glXDisplayInfoHash), dpy, pEntry); } else { // Another thread already created the hashtable entry. + CleanupDisplayInfoEntry(NULL, pEntry); free(pEntry); pEntry = foundEntry; } diff --git a/src/GLX/libglxmapping.h b/src/GLX/libglxmapping.h index 984b374..8ae8844 100644 --- a/src/GLX/libglxmapping.h +++ b/src/GLX/libglxmapping.h @@ -135,6 +135,12 @@ __GLXdisplayInfo *__glXLookupDisplay(Display *dpy); */ void __glXFreeDisplay(Display *dpy); +/*! + * This is called to perform any context-related cleanup when a display is + * closed. + */ +void __glXDisplayClosed(Display *dpy, __GLXdisplayInfo *dpyInfo); + /* * Close the vendor library and perform any relevant teardown. This should * be called when the API library is unloaded. diff --git a/src/x11glvnd/x11glvnd.h b/src/x11glvnd/x11glvnd.h index 6b9f3c7..e9d5aa1 100644 --- a/src/x11glvnd/x11glvnd.h +++ b/src/x11glvnd/x11glvnd.h @@ -78,18 +78,4 @@ char *XGLVQueryScreenVendorMapping( int screen ); -/* - * Registers a callback with x11glvnd which is fired whenever XCloseDisplay() - * is called. This gives x11glvnd clients a lightweight alternative to - * declaring themselves an X11 extension and using XESetCloseDisplay(). - * - * This is NOT a thread-safe operation. - */ -void XGLVRegisterCloseDisplayCallback(void (*callback)(Display *)); - -/* - * Unregisters all registered callbacks. - */ -void XGLVUnregisterCloseDisplayCallbacks(void); - #endif // __X11GLVND_H__ diff --git a/src/x11glvnd/x11glvndclient.c b/src/x11glvnd/x11glvndclient.c index acbb182..d01ccab 100644 --- a/src/x11glvnd/x11glvndclient.c +++ b/src/x11glvnd/x11glvndclient.c @@ -41,8 +41,6 @@ const char *xglv_ext_name = XGLV_EXTENSION_NAME; static XExtensionInfo *xglv_ext_info = NULL; -static int close_display(Display *dpy, XExtCodes *codes); - static /* const */ XExtensionHooks xglv_ext_hooks = { NULL, /* create_gc */ NULL, /* copy_gc */ @@ -50,7 +48,7 @@ static /* const */ XExtensionHooks xglv_ext_hooks = { NULL, /* free_gc */ NULL, /* create_font */ NULL, /* free_font */ - close_display, /* close_display */ + NULL, /* close_display */ NULL, /* wire_to_event */ NULL, /* event_to_wire */ NULL, /* error */ @@ -63,61 +61,6 @@ static XEXT_GENERATE_FIND_DISPLAY(find_display, xglv_ext_info, &xglv_ext_hooks, XGLV_NUM_EVENTS, NULL); -typedef struct CloseDisplayHookRec { - /* - * Callback function - */ - void (*callback)(Display *); - - /* - * List entry - */ - struct glvnd_list entry; -} CloseDisplayHook; - -static int closeDisplayHookListInitialized; -static struct glvnd_list closeDisplayHookList; - -void XGLVRegisterCloseDisplayCallback(void (*callback)(Display *)) -{ - CloseDisplayHook *hook = malloc(sizeof(*hook)); - hook->callback = callback; - - if (!closeDisplayHookListInitialized) { - glvnd_list_init(&closeDisplayHookList); - } - - glvnd_list_add(&hook->entry, &closeDisplayHookList); -} - -void XGLVUnregisterCloseDisplayCallbacks(void) -{ - CloseDisplayHook *curHook, *tmpHook; - glvnd_list_for_each_entry_safe(curHook, tmpHook, &closeDisplayHookList, entry) { - glvnd_list_del(&curHook->entry); - free(curHook); - } - assert(glvnd_list_is_empty(&closeDisplayHookList)); - closeDisplayHookListInitialized = False; -} - -static XEXT_GENERATE_CLOSE_DISPLAY(close_display_internal, xglv_ext_info); - -static XEXT_CLOSE_DISPLAY_PROTO(close_display) -{ - CloseDisplayHook *curHook; - - /* - * Call any registered hooks before calling into the - * generated close_display() hook. - */ - glvnd_list_for_each_entry(curHook, &closeDisplayHookList, entry) { - curHook->callback(dpy); - } - - return close_display_internal(dpy, codes); -} - #define CHECK_EXTENSION(dpy, i, val) \ do { \ if (!XextHasExtension(i)) { \ |