[Commit] Xrender Xrender.c,1.17,1.18

Keith Packard commit at keithp.com
Mon Jun 23 15:12:11 PDT 2003


Committed by: keithp

Update of /local/src/CVS/Xrender
In directory home.keithp.com:/tmp/cvs-serv8469

Modified Files:
	Xrender.c 
Log Message:
Make Xrender depth checks work with broken Xinerama code

Index: Xrender.c
===================================================================
RCS file: /local/src/CVS/Xrender/Xrender.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- Xrender.c	8 Jun 2003 17:56:37 -0000	1.17
+++ Xrender.c	23 Jun 2003 21:12:08 -0000	1.18
@@ -80,6 +80,33 @@
 			 DEPTH_MASK(24) | \
 			 DEPTH_MASK(32))
     
+typedef struct _DepthCheckRec {
+    struct _DepthCheckRec *next;
+    Display *dpy;
+    CARD32  missing;
+    unsigned long serial;
+} DepthCheckRec, *DepthCheckPtr;
+
+static DepthCheckPtr	depthChecks;
+
+static int
+XRenderDepthCheckErrorHandler (Display *dpy, XErrorEvent *evt)
+{
+    if (evt->request_code == X_CreatePixmap && evt->error_code == BadValue)
+    {
+	DepthCheckPtr	d;
+	_XLockMutex(_Xglobal_lock);
+	for (d = depthChecks; d; d = d->next)
+	    if (d->dpy == dpy)
+	    {
+		if ((long) (evt->serial - d->serial) >= 0)
+		    d->missing |= DEPTH_MASK(evt->resourceid);
+		break;
+	    }
+	_XUnlockMutex (_Xglobal_lock);
+    }
+}
+
 static Bool
 XRenderHasDepths (Display *dpy)
 {
@@ -88,13 +115,66 @@
     for (s = 0; s < ScreenCount (dpy); s++)
     {
 	CARD32		    depths = 0;
+	CARD32		    missing;
 	Screen		    *scr = ScreenOfDisplay (dpy, s);
 	int		    d;
 
 	for (d = 0; d < scr->ndepths; d++)
 	    depths |= DEPTH_MASK(scr->depths[d].depth);
-	if (~depths & REQUIRED_DEPTHS)
-	    return False;
+	missing = ~depths & REQUIRED_DEPTHS;
+	if (missing)
+	{
+	    DepthCheckRec   dc, **dp;
+	    XErrorHandler   previousHandler;
+
+	    /*
+	     * Ok, this is ugly.  It should be sufficient at this
+	     * point to just return False, but Xinerama is broken at
+	     * this point and only advertises depths which have an
+	     * associated visual.  Of course, the other depths still
+	     * work, but the only way to find out is to try them.
+	     */
+	    dc.dpy = dpy;
+	    dc.missing = 0;
+	    dc.serial = XNextRequest (dpy);
+	    _XLockMutex(_Xglobal_lock);
+	    dc.next = depthChecks;
+	    depthChecks = &dc;
+	    _XUnlockMutex (_Xglobal_lock);
+	    /*
+	     * I suspect this is not really thread safe, but Xlib doesn't
+	     * provide a lot of options here
+	     */
+	    previousHandler = XSetErrorHandler (XRenderDepthCheckErrorHandler);
+	    /*
+	     * Try each missing depth and see if pixmap creation succeeds
+	     */
+	    for (d = 1; d <= 32; d++)
+		/* don't check depth 1 == Xcursor recurses... */
+		if ((missing & DEPTH_MASK(d)) && d != 1)
+		{
+		    Pixmap  p;
+		    p = XCreatePixmap (dpy, RootWindow (dpy, s), 1, 1, d);
+		    XFreePixmap (dpy, p);
+		}
+	    XSync (dpy, False);
+	    XSetErrorHandler (previousHandler);
+	    /*
+	     * Unhook from the list of depth check records
+	     */
+	    _XLockMutex(_Xglobal_lock);
+	    for (dp = &depthChecks; *dp; dp = &(*dp)->next)
+	    {
+		if (*dp == &dc)
+		{
+		    *dp = dc.next;
+		    break;
+		}
+	    }
+	    _XUnlockMutex (_Xglobal_lock);
+	    if (dc.missing)
+		return False;
+	}
     }
     return True;
 }




More information about the Commit mailing list