summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Brenneman <kbrenneman@nvidia.com>2016-03-07 13:52:19 -0700
committerKyle Brenneman <kbrenneman@nvidia.com>2016-03-24 12:44:25 -0600
commit3f4674f8f66bf9dfa897e182f7936c2ae47e3850 (patch)
treecf81ab0c3d44a779805fd3290728b7a18fcf9d70
parentaf2aeb0b4293e085ad61eae08be34e52f9d7b389 (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.c10
-rw-r--r--src/GLX/libglxmapping.c29
-rw-r--r--src/GLX/libglxmapping.h6
-rw-r--r--src/x11glvnd/x11glvnd.h14
-rw-r--r--src/x11glvnd/x11glvndclient.c59
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)) { \