1 /* xlock-gl.c --- xscreensaver compatibility layer for xlockmore GL modules.
2 * xscreensaver, Copyright (c) 1997, 1998, 1999 Jamie Zawinski <jwz@jwz.org>
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation. No representations are made about the suitability of this
9 * software for any purpose. It is provided "as is" without express or
12 * This file, along with xlockmore.h, make it possible to compile an xlockmore
13 * GL module into a standalone program, and thus use it with xscreensaver.
14 * By Jamie Zawinski <jwz@jwz.org> on 31-May-97.
18 #include "screenhack.h"
19 #include "xlockmoreI.h"
25 /* Gag -- we use this to turn X errors from glXCreateContext() into
26 something that will actually make sense to the user.
28 static XErrorHandler orig_ehandler = 0;
29 static Bool got_error = 0;
32 BadValue_ehandler (Display *dpy, XErrorEvent *error)
34 if (error->error_code == BadValue)
40 return orig_ehandler (dpy, error);
45 init_GL(ModeInfo * mi)
47 Display *dpy = mi->dpy;
48 Window window = mi->window;
49 Screen *screen = mi->xgwa.screen;
50 Visual *visual = mi->xgwa.visual;
51 GLXContext glx_context = 0;
52 XVisualInfo vi_in, *vi_out;
55 vi_in.screen = screen_number (screen);
56 vi_in.visualid = XVisualIDFromVisual (visual);
57 vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
59 if (! vi_out) abort ();
63 orig_ehandler = XSetErrorHandler (BadValue_ehandler);
64 glx_context = glXCreateContext (dpy, vi_out, 0, GL_TRUE);
66 XSetErrorHandler (orig_ehandler);
71 XFree((char *) vi_out);
75 fprintf(stderr, "%s: couldn't create GL context for visual 0x%x.\n",
76 progname, (unsigned int) XVisualIDFromVisual (visual));
80 glXMakeCurrent (dpy, window, glx_context);
83 GLboolean rgba_mode = 0;
84 glGetBooleanv(GL_RGBA_MODE, &rgba_mode);
87 glIndexi (WhitePixelOfScreen (screen));
88 glClearIndex (BlackPixelOfScreen (screen));
92 /* GLXContext is already a pointer type.
93 Why this function returns a pointer to a pointer, I have no idea...
96 GLXContext *ptr = (GLXContext *) malloc(sizeof(GLXContext));
105 /* clear away any lingering error codes */
107 clear_gl_error (void)
109 while (glGetError() != GL_NO_ERROR)
113 /* report a GL error. */
115 check_gl_error (const char *type)
120 switch ((i = glGetError())) {
121 case GL_NO_ERROR: return;
122 case GL_INVALID_ENUM: e = "invalid enum"; break;
123 case GL_INVALID_VALUE: e = "invalid value"; break;
124 case GL_INVALID_OPERATION: e = "invalid operation"; break;
125 case GL_STACK_OVERFLOW: e = "stack overflow"; break;
126 case GL_STACK_UNDERFLOW: e = "stack underflow"; break;
127 case GL_OUT_OF_MEMORY: e = "out of memory"; break;
128 #ifdef GL_TABLE_TOO_LARGE_EXT
129 case GL_TABLE_TOO_LARGE_EXT: e = "table too large"; break;
131 #ifdef GL_TEXTURE_TOO_LARGE_EXT
132 case GL_TEXTURE_TOO_LARGE_EXT: e = "texture too large"; break;
135 e = buf; sprintf (buf, "unknown error %d", (int) i); break;
137 fprintf (stderr, "%s: %s error: %s\n", progname, type, e);