diff options
| author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
| commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
| tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/xlock-gl-utils.c | |
| parent | Delete pre-6.00 files (diff) | |
| download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip | |
Diffstat (limited to 'hacks/glx/xlock-gl-utils.c')
| -rw-r--r-- | hacks/glx/xlock-gl-utils.c | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/hacks/glx/xlock-gl-utils.c b/hacks/glx/xlock-gl-utils.c deleted file mode 100644 index 0d017b8..0000000 --- a/hacks/glx/xlock-gl-utils.c +++ /dev/null @@ -1,379 +0,0 @@ -/* xlock-gl.c --- xscreensaver compatibility layer for xlockmore GL modules. - * xscreensaver, Copyright (c) 1997-2021 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 - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * This file, along with xlockmore.h, make it possible to compile an xlockmore - * GL module into a standalone program, and thus use it with xscreensaver. - * By Jamie Zawinski <jwz@jwz.org> on 31-May-97. - */ - -#include "xlockmoreI.h" - -#ifdef HAVE_GL /* whole file */ - -#include "texfont.h" - -#ifndef isupper -# define isupper(c) ((c) >= 'A' && (c) <= 'Z') -#endif -#ifndef _tolower -# define _tolower(c) ((c) - 'A' + 'a') -#endif - - -# ifndef HAVE_EGL -/* Gag -- we use this to turn X errors from glXCreateContext() into - something that will actually make sense to the user. - */ -static XErrorHandler orig_ehandler = 0; -static Bool got_error = 0; - -static int -BadValue_ehandler (Display *dpy, XErrorEvent *error) -{ - if (error->error_code == BadValue) - { - got_error = True; - return 0; - } - else - return orig_ehandler (dpy, error); -} -#endif /* !HAVE_EGL */ - - -GLXContext * -init_GL(ModeInfo * mi) -{ - /* The Android version of this function is in android/screenhack-android.c */ - Display *dpy = mi->dpy; - Window window = mi->window; - Screen *screen = mi->xgwa.screen; - Visual *visual = mi->xgwa.visual; - XVisualInfo vi_in, *vi_out; - int out_count; - - if (mi->glx_context) { - glXMakeCurrent (dpy, window, mi->glx_context); - return &mi->glx_context; - } - -# ifdef HAVE_JWZGLES - mi->jwzgles_state = jwzgles_make_state(); - mi->xlmft->jwzgles_make_current = jwzgles_make_current; - mi->xlmft->jwzgles_free = jwzgles_free_state; - mi->xlmft->jwzgles_make_current (mi->jwzgles_state); -# endif - - vi_in.screen = screen_number (screen); - vi_in.visualid = XVisualIDFromVisual (visual); - vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask, - &vi_in, &out_count); - if (! vi_out) abort (); - -# ifdef HAVE_EGL - { - egl_data *d = (egl_data *) calloc (1, sizeof(*d)); - - /* The correct EGL config has been selected by utils/visual-gl.c - (via hacks/glx/xscreensaver-gl-visual) by calling get_egl_config() - from get_gl_visual and returning the corresponding X11 Visual. - That visual is the one that was used to create our window. We will - pass the corresponding visual ID to get_egl_config() to obtain the - same configuration here. */ - unsigned int vid = XVisualIDFromVisual (visual); - - const EGLint ctxattr1[] = { -# ifdef HAVE_JWZGLES - EGL_CONTEXT_MAJOR_VERSION, 1, /* Request an OpenGL ES 1.1 context. */ - EGL_CONTEXT_MINOR_VERSION, 1, -# else - EGL_CONTEXT_MAJOR_VERSION, 1, /* Request an OpenGL 1.3 context. */ - EGL_CONTEXT_MINOR_VERSION, 3, -# endif - EGL_NONE - }; - const EGLint *ctxattr = ctxattr1; - -# ifdef HAVE_GLES3 - const EGLint ctxattr3[] = { - EGL_CONTEXT_MAJOR_VERSION, 3, /* Request an OpenGL ES 3.0 context. */ - EGL_CONTEXT_MINOR_VERSION, 0, - EGL_NONE - }; - - if (get_boolean_resource (dpy, "prefersGLSL", "PrefersGLSL")) - ctxattr = ctxattr3; -# endif /* HAVE_GLES3 */ - - /* This is re-used, no need to close it. */ - d->egl_display = eglGetPlatformDisplay (EGL_PLATFORM_X11_KHR, - (EGLNativeDisplayType) dpy, NULL); - if (!d->egl_display) - { - fprintf (stderr, "%s: eglGetPlatformDisplay failed\n", progname); - abort(); - } - - get_egl_config (dpy, d->egl_display, vid, &d->egl_config); - if (!d->egl_config) - { - fprintf (stderr, "%s: no matching EGL config for X11 visual 0x%lx\n", - progname, vi_out->visualid); - abort(); - } - - d->egl_surface = eglCreatePlatformWindowSurface (d->egl_display, - d->egl_config, - &window, NULL); - if (! d->egl_surface) - { - fprintf (stderr, "%s: eglCreatePlatformWindowSurface failed:" - " window 0x%lx visual 0x%x\n", progname, window, vid); - abort(); - } - -#ifdef HAVE_JWZGLES - /* This call is not strictly necessary to get an OpenGL ES context - since the default API is EGL_OPENGL_ES_API, but it makes our - intention clear. - */ - if (!eglBindAPI (EGL_OPENGL_ES_API)) - { - fprintf (stderr, "%s: eglBindAPI failed\n", progname); - } -#else /* !HAVE_JWZGLES */ - /* This is necessary to get a OpenGL context instead of an OpenGLES - context. - */ - if (!eglBindAPI (EGL_OPENGL_API)) - { - fprintf (stderr, "%s: eglBindAPI failed\n", progname); - } -#endif /* !HAVE_JWZGLES */ - - d->egl_context = eglCreateContext (d->egl_display, d->egl_config, - EGL_NO_CONTEXT, ctxattr); - -# ifdef HAVE_GLES3 - /* If creation of a GLES 3.0 context failed, fall back to GLES 1.x. */ - if (!d->egl_context && ctxattr != ctxattr1) - { - /* fprintf (stderr, "%s: eglCreateContext 3.0 failed\n", progname); */ - d->egl_context = eglCreateContext (d->egl_display, d->egl_config, - EGL_NO_CONTEXT, ctxattr1); - } -# endif /* HAVE_GLES3 */ - - if (!d->egl_context) - { - fprintf (stderr, "%s: eglCreateContext failed\n", progname); - abort(); - } - - /* describe_gl_visual (stderr, screen, visual, False); */ - - mi->glx_context = d; /* #### leaked */ - - glXMakeCurrent (dpy, window, mi->glx_context); - } -# else /* GLX */ - { - XSync (dpy, False); - orig_ehandler = XSetErrorHandler (BadValue_ehandler); - mi->glx_context = glXCreateContext (dpy, vi_out, 0, GL_TRUE); - XSync (dpy, False); - XSetErrorHandler (orig_ehandler); - if (got_error) - mi->glx_context = 0; - } - - if (!mi->glx_context) - { - fprintf(stderr, "%s: couldn't create GL context for visual 0x%x.\n", - progname, (unsigned int) XVisualIDFromVisual (visual)); - exit(1); - } - - glXMakeCurrent (dpy, window, mi->glx_context); - - { - GLboolean rgba_mode = 0; - glGetBooleanv(GL_RGBA_MODE, &rgba_mode); - if (!rgba_mode) - { - glIndexi (WhitePixelOfScreen (screen)); - glClearIndex (BlackPixelOfScreen (screen)); - } - } -# endif /* GLX */ - - XFree((char *) vi_out); - - - /* 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); - } - - /* Sometimes glDrawBuffer() throws "invalid op". Dunno why. Ignore. */ - clear_gl_error (); - - /* Process the -background argument. */ - { - char *s = get_string_resource(mi->dpy, "background", "Background"); - XColor c = { 0, }; - if (! XParseColor (dpy, mi->xgwa.colormap, s, &c)) - fprintf (stderr, "%s: can't parse color %s; using black.\n", - progname, s); - if (s) free (s); - glClearColor (c.red / 65535.0, - c.green / 65535.0, - c.blue / 65535.0, - 1.0); - } - - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* GLXContext is already a pointer type. - Why this function returns a pointer to a pointer, I have no idea... - */ - return &mi->glx_context; -} - - - -/* 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_INVALID_FRAMEBUFFER_OPERATION - case GL_INVALID_FRAMEBUFFER_OPERATION: - e = "invalid framebuffer operation"; - break; -#endif -#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); -} - - -/* Callback in xscreensaver_function_table, via xlockmore.c. - */ -Visual * -xlockmore_pick_gl_visual (Screen *screen) -{ - /* pick the "best" visual by interrogating the GL library instead of - by asking Xlib. GL knows better. - */ - Visual *v = 0; - Display *dpy = DisplayOfScreen (screen); - char *string = get_string_resource (dpy, "visualID", "VisualID"); - char *s; - - if (string) - for (s = string; *s; s++) - if (isupper (*s)) *s = _tolower (*s); - - if (!string || !*string || - !strcmp (string, "gl") || - !strcmp (string, "best") || - !strcmp (string, "color") || - !strcmp (string, "default")) - v = get_gl_visual (screen); /* from ../utils/visual-gl.c */ - - if (string) - free (string); - - return v; -} - - -/* Callback in xscreensaver_function_table, via xlockmore.c. - */ -Bool -xlockmore_validate_gl_visual (Screen *screen, const char *name, Visual *visual) -{ - return validate_gl_visual (stderr, screen, name, visual); -} - - -#ifdef HAVE_EGL - -static egl_data *global_egl_kludge = 0; - -Bool -glXMakeCurrent (Display *dpy, GLXDrawable window, egl_data *d) -{ - if (!d) abort(); - if (! eglMakeCurrent (d->egl_display, d->egl_surface, d->egl_surface, - d->egl_context)) - abort(); - - global_egl_kludge = d; - - return True; -} - -void -glXSwapBuffers (Display *dpy, GLXDrawable win) -{ - egl_data *d = global_egl_kludge; - if (!d) abort(); - if (! eglSwapBuffers (d->egl_display, d->egl_surface)) - abort(); -} - -#endif /* HAVE_EGL */ - - -#endif /* HAVE_GL -- whole file */ |
