Use XAddExtension() to register an XCloseDisplay() callback function.
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 30 Aug 2006 21:17:51 +0000 (21:17 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 30 Aug 2006 21:17:51 +0000 (21:17 +0000)
When the callback is called, free all Mesa's private visual and buffer
data structures which are tied to the display.
Fixes problems reported by Kitware.

src/mesa/drivers/x11/fakeglx.c
src/mesa/drivers/x11/glxheader.h
src/mesa/drivers/x11/xm_api.c
src/mesa/drivers/x11/xmesaP.h

index 39469aec9254bea172341668ef5f18b3a4b2000e..7f132eb049a97f6535fe02e2b5839aba38e29326 100644 (file)
@@ -915,6 +915,81 @@ choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag,
 }
 
 
+/**********************************************************************/
+/***             Display-related functions                          ***/
+/**********************************************************************/
+
+
+/**
+ * Free all XMesaVisuals which are associated with the given display.
+ */
+static void
+destroy_visuals_on_display(Display *dpy)
+{
+   int i;
+   for (i = 0; i < NumVisuals; i++) {
+      if (VisualTable[i]->display == dpy) {
+         /* remove this visual */
+         int j;
+         free(VisualTable[i]);
+         for (j = i; j < NumVisuals - 1; j++)
+            VisualTable[j] = VisualTable[j + 1];
+         NumVisuals--;
+      }
+   }
+}
+
+
+/**
+ * Called from XCloseDisplay() to let us free our display-related data.
+ */
+static int
+close_display_callback(Display *dpy, XExtCodes *codes)
+{
+   destroy_visuals_on_display(dpy);
+   xmesa_destroy_buffers_on_display(dpy);
+   return 0;
+}
+
+
+/**
+ * Look for the named extension on given display and return a pointer
+ * to the _XExtension data, or NULL if extension not found.
+ */
+static _XExtension *
+lookup_extension(Display *dpy, const char *extName)
+{
+   _XExtension *ext;
+   for (ext = dpy->ext_procs; ext; ext = ext->next) {
+      if (strcmp(ext->name, extName) == 0) {
+         return ext;
+      }
+   }
+   return NULL;
+}
+
+
+/**
+ * Whenever we're given a new Display pointer, call this function to
+ * register our close_display_callback function.
+ */
+static void
+register_with_display(Display *dpy)
+{
+   const char *extName = "MesaGLX";
+   _XExtension *ext;
+
+   ext = lookup_extension(dpy, extName);
+   if (!ext) {
+      XExtCodes *c = XAddExtension(dpy);
+      ext = dpy->ext_procs;  /* new extension is at head of list */
+      assert(c->extension == ext->codes.extension);
+      ext->name = _mesa_strdup(extName);
+      ext->close_display = close_display_callback;
+   }
+}
+
+
 /**********************************************************************/
 /***                  Begin Fake GLX API Functions                  ***/
 /**********************************************************************/
@@ -1264,7 +1339,12 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
 static XVisualInfo *
 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
 {
-   XMesaVisual xmvis = choose_visual(dpy, screen, list, GL_FALSE);
+   XMesaVisual xmvis;
+
+   /* register ourselves as an extension on this display */
+   register_with_display(dpy);
+
+   xmvis = choose_visual(dpy, screen, list, GL_FALSE);
    if (xmvis) {
 #if 0
       return xmvis->vishandle;
@@ -1298,7 +1378,9 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
       return 0;
 
    /* deallocate unused windows/buffers */
+#if 0
    XMesaGarbageCollect();
+#endif
 
    xmvis = find_glx_visual( dpy, visinfo );
    if (!xmvis) {
index f2881707058ad98e031372d8983cb82d4fed8a1d..844a7838da35cbaa7eafcaeea12c97d74e3f8325 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  6.5.1
  * 
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -43,6 +42,7 @@
 #else
 
 # include <X11/Xlib.h>
+# include <X11/Xlibint.h>
 # include <X11/Xutil.h>
 # ifdef USE_XSHM  /* was SHM */
 #  include <sys/ipc.h>
index d2e2c7137b5411c777022fef21f847304330a719..dea23fcf59ba4ca7eac5d09e65fdea19aa2bf0da 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  6.5.1
  *
  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  *
@@ -2553,6 +2553,20 @@ XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
 }
 
 
+/**
+ * Free/destroy all XMesaBuffers associated with given display.
+ */
+void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy)
+{
+   XMesaBuffer b, next;
+   for (b = XMesaBufferList; b; b = next) {
+      next = b->Next;
+      if (b->display == dpy) {
+         free_xmesa_buffer(0, b);
+      }
+   }
+}
+
 
 /*
  * Look for XMesaBuffers whose X window has been destroyed.
index d7b772c9b1b9028002f9cc530a7fcc55e9b01453..4db0872621f12634f0ff8dcafe1d79309507f0d2 100644 (file)
@@ -520,6 +520,8 @@ extern void
 xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
                              enum pixel_format pixelformat, GLint depth);
 
+extern void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy);
+
 
 /**
  * Using a function instead of an ordinary cast is safer.