Merge remote branch 'origin/gallium-0.2' into gallium-0.2
[mesa.git] / src / glx / x11 / XF86dri.c
index 0ce588276be70dafd3919000fc31f56216bde8a8..cd0adc3930f155584029396698e88beeb4ef7f0c 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
 /**************************************************************************
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -43,9 +42,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <X11/Xlibint.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
-#include "glheader.h"
 #include "xf86dristr.h"
 
+
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+#  define PUBLIC __attribute__((visibility("default")))
+#  define USED __attribute__((used))
+#else
+#  define PUBLIC
+#  define USED
+#endif
+
+
+
 static XExtensionInfo _xf86dri_info_data;
 static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
 static char xf86dri_extension_name[] = XF86DRINAME;
@@ -203,7 +212,7 @@ PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
 
     *hSAREA = rep.hSAREALow;
     if (sizeof(drm_handle_t) == 8) {
-       const int shift = 32; /* var to prevent warning on next line */
+       int shift = 32; /* var to prevent warning on next line */
        *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
     }
 
@@ -375,10 +384,9 @@ PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
                                           context, hHWContext );
 }
 
-PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, 
-    __DRIid context )
+PUBLIC Bool XF86DRIDestroyContext(Display *dpy, int screen, 
+    XID context )
 {
-    Display * const dpy = (Display *) ndpy;
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIDestroyContextReq *req;
 
@@ -397,10 +405,9 @@ PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
     return True;
 }
 
-PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, 
-    __DRIid drawable, drm_drawable_t * hHWDrawable )
+PUBLIC Bool XF86DRICreateDrawable(Display *dpy, int screen, 
+    XID drawable, drm_drawable_t * hHWDrawable )
 {
-    Display * const dpy = (Display *) ndpy;
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRICreateDrawableReply rep;
     xXF86DRICreateDrawableReq *req;
@@ -427,16 +434,36 @@ PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
     return True;
 }
 
-PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
-    __DRIid drawable )
+static int noopErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+    return 0;
+}
+
+PUBLIC Bool XF86DRIDestroyDrawable(Display *dpy, int screen,
+    XID drawable )
 {
-    Display * const dpy = (Display *) ndpy;
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIDestroyDrawableReq *req;
+    int (*oldXErrorHandler)(Display *, XErrorEvent *);
 
     TRACE("DestroyDrawable...");
     XF86DRICheckExtension (dpy, info, False);
 
+    /* This is called from the DRI driver, which used call it like this
+     *
+     *   if (windowExists(drawable))
+     *     destroyDrawable(drawable);
+     *
+     * which is a textbook race condition - the window may disappear
+     * from the server between checking for its existance and
+     * destroying it.  Instead we change the semantics of
+     * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
+     * the windows is gone, by wrapping the destroy call in an error
+     * handler. */
+
+    XSync(dpy, False);
+    oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
+
     LockDisplay(dpy);
     GetReq(XF86DRIDestroyDrawable, req);
     req->reqType = info->codes->major_opcode;
@@ -445,6 +472,9 @@ PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
     req->drawable = drawable;
     UnlockDisplay(dpy);
     SyncHandle();
+
+    XSetErrorHandler(oldXErrorHandler);
+
     TRACE("DestroyDrawable... return True");
     return True;
 }
@@ -566,7 +596,7 @@ PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer,
 
     *hFrameBuffer = rep.hFrameBufferLow;
     if (sizeof(drm_handle_t) == 8) {
-       const int shift = 32; /* var to prevent warning on next line */
+       int shift = 32; /* var to prevent warning on next line */
        *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
     }