summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/x11/fakeglx.c
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2006-08-30 21:17:51 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2006-08-30 21:17:51 +0000
commit6c06ce281aa7a7e20eab1934f573bc5c673d41cb (patch)
tree497ad65b4f600466db26ed9dab093ffd76764177 /src/mesa/drivers/x11/fakeglx.c
parent12a5f812fcf00708ea2b6501e7adcdd5e7a47fac (diff)
Use XAddExtension() to register an XCloseDisplay() callback function.
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.
Diffstat (limited to 'src/mesa/drivers/x11/fakeglx.c')
-rw-r--r--src/mesa/drivers/x11/fakeglx.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
index 39469aec92..7f132eb049 100644
--- a/src/mesa/drivers/x11/fakeglx.c
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -916,6 +916,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) {