File compiz-ldpreload-indirect.diff of Package compiz

diff --git a/src/display.c b/src/display.c
index 72515b6..99d3e96 100644
--- a/src/display.c
+++ b/src/display.c
@@ -30,6 +30,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
 #include <sys/poll.h>
 #include <assert.h>
 
@@ -44,6 +46,8 @@
 
 #include <compiz-core.h>
 
+extern int libGLFallback;
+
 static unsigned int virtualModMask[] = {
     CompAltMask, CompMetaMask, CompSuperMask, CompHyperMask,
     CompModeSwitchMask, CompNumLockMask, CompScrollLockMask
@@ -2048,6 +2052,29 @@ addDisplay (const char *name)
 					     COMP_DISPLAY_OPTION_NUM))
 	return FALSE;
 
+    if (strstr (ServerVendor (dpy), "DMX"))
+	libGLFallback = 0;
+
+    if (libGLFallback)
+    {
+	const char *vendor;
+	if (! (vendor = glXGetClientString (dpy, GLX_VENDOR)))
+            return FALSE;
+	if (strstr (vendor, "NVIDIA") != NULL) {
+	    if ((vendor = glXQueryServerString (dpy, DefaultScreen (dpy),
+						  GLX_VENDOR)) &&
+		(strstr (vendor, "NVIDIA") == NULL)) {
+		/* Remove CLOSE_ON_EXEC flag to avoid server resets during
+		 * re-exec with LD_PRELOAD */
+		fcntl (ConnectionNumber(dpy), F_SETFD,
+		       fcntl (ConnectionNumber(dpy), F_GETFD) & ~FD_CLOEXEC);
+		/* dpy is never closed, in this case this is a blessing */
+		libGLFallback = 2;
+		return FALSE;
+	    }
+        }
+    }
+
     d->opt[COMP_DISPLAY_OPTION_ABI].value.i = CORE_ABIVERSION;
 
     snprintf (d->displayString, 255, "DISPLAY=%s", DisplayString (dpy));
diff --git a/src/main.c b/src/main.c
index ec76311..20893b3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -71,6 +71,8 @@ Bool useCow = TRUE;
 Bool windowManagement = FALSE;
 Bool manualCompositeManagement = FALSE;
 
+int libGLFallback = 1;		/* 0: --no-*fallback  1: possible   2: do it */
+
 CompMetadata coreMetadata;
 
 static void
@@ -266,6 +268,11 @@ main (int argc, char **argv)
     signal (SIGINT, signalHandler);
     signal (SIGTERM, signalHandler);
 
+    /* Except for native NVidia libGL (which doesn't know this ENV var),
+     * GLX_EXT_texture_from_pixmap is only available on purely indirect
+     * contexts. Specifying indirect rendering per context isn't enough. */
+    putenv ("LIBGL_ALWAYS_INDIRECT=1");
+
     emptyRegion.rects = &emptyRegion.extents;
     emptyRegion.numRects = 0;
     emptyRegion.extents.x1 = 0;
@@ -361,6 +368,10 @@ main (int argc, char **argv)
 	    if (i + 1 < argc)
 		backgroundImage = argv[++i];
 	}
+	else if (!strcmp (argv[i], "--no-libgl-fallback"))
+	{
+	    libGLFallback = 0;
+	}
 	else if (*argv[i] == '-')
 	{
 	    compLogMessage ("core", CompLogLevelWarn,
@@ -445,7 +456,23 @@ main (int argc, char **argv)
     }
 
     if (!manageDisplay (core.displays))
+    {
+	if (libGLFallback == 2)
+	{
+	    char *arg[argc + 2];
+	    static const char *libindirect_libgl = "/usr/$LIB/libIndirectGL.so.1";
+	    memcpy (arg, argv, sizeof (char *) * argc);
+
+	    arg[argc] = "--no-libgl-fallback";
+	    arg[argc + 1] = NULL;
+
+	    fprintf (stderr, "%s: Trying '%s'\n", programName, libindirect_libgl);
+
+	    setenv ("LD_PRELOAD", libindirect_libgl, TRUE);
+	    execvp (arg[0], arg);
+	}
 	return 1;
+    }
 
     eventLoop ();
 
openSUSE Build Service is sponsored by