http://ftp.ksu.edu.tw/FTP/FreeBSD/distfiles/xscreensaver-4.24.tar.gz
[xscreensaver] / hacks / glx / xlock-gl.c
index 0256cf0b7c9f0b0f1fde0e6778ae14672a8d0ce1..0f313e52946f94f4b2229c0061741723133293c3 100644 (file)
@@ -1,5 +1,5 @@
 /* xlock-gl.c --- xscreensaver compatibility layer for xlockmore GL modules.
- * xscreensaver, Copyright (c) 1997, 1998, 1999 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1997-2002 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -19,6 +19,7 @@
 #include "xlockmoreI.h"
 
 #include <GL/gl.h>
+#include <GL/glu.h>
 #include <GL/glx.h>
 
 /* Gag -- we use this to turn X errors from glXCreateContext() into
@@ -88,6 +89,28 @@ init_GL(ModeInfo * mi)
       }
   }
 
+
+  /* jwz: the doc for glDrawBuffer says "The initial value is GL_FRONT
+     for single-buffered contexts, and GL_BACK for double-buffered
+     contexts."  However, I find that this is not always the case,
+     at least with Mesa 3.4.2 -- sometimes the default seems to be
+     GL_FRONT even when glGet(GL_DOUBLEBUFFER) is true.  So, let's
+     make sure.
+
+     Oh, hmm -- maybe this only happens when we are re-using the
+     xscreensaver window, and the previous GL hack happened to die with
+     the other buffer selected?  I'm not sure.  Anyway, this fixes it.
+   */
+  {
+    GLboolean d = False;
+    glGetBooleanv (GL_DOUBLEBUFFER, &d);
+    if (d)
+      glDrawBuffer (GL_BACK);
+    else
+      glDrawBuffer (GL_FRONT);
+  }
+
+
   /* GLXContext is already a pointer type.
      Why this function returns a pointer to a pointer, I have no idea...
    */
@@ -97,3 +120,42 @@ init_GL(ModeInfo * mi)
     return ptr;
   }
 }
+
+
+\f
+
+/* clear away any lingering error codes */
+void
+clear_gl_error (void)
+{
+  while (glGetError() != GL_NO_ERROR)
+    ;
+}
+
+/* report a GL error. */
+void
+check_gl_error (const char *type)
+{
+  char buf[100];
+  GLenum i;
+  const char *e;
+  switch ((i = glGetError())) {
+  case GL_NO_ERROR: return;
+  case GL_INVALID_ENUM:          e = "invalid enum";      break;
+  case GL_INVALID_VALUE:         e = "invalid value";     break;
+  case GL_INVALID_OPERATION:     e = "invalid operation"; break;
+  case GL_STACK_OVERFLOW:        e = "stack overflow";    break;
+  case GL_STACK_UNDERFLOW:       e = "stack underflow";   break;
+  case GL_OUT_OF_MEMORY:         e = "out of memory";     break;
+#ifdef GL_TABLE_TOO_LARGE_EXT
+  case GL_TABLE_TOO_LARGE_EXT:   e = "table too large";   break;
+#endif
+#ifdef GL_TEXTURE_TOO_LARGE_EXT
+  case GL_TEXTURE_TOO_LARGE_EXT: e = "texture too large"; break;
+#endif
+  default:
+    e = buf; sprintf (buf, "unknown error %d", (int) i); break;
+  }
+  fprintf (stderr, "%s: %s error: %s\n", progname, type, e);
+  exit (1);
+}