-/* xscreensaver, Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
- * by Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ * by 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
static Visual *pick_best_visual (Screen *, Bool, Bool);
static Visual *pick_mono_visual (Screen *);
static Visual *pick_best_visual_of_class (Screen *, int);
-static Visual *id_to_visual (Screen *, int);
-static Visual *id_to_visual (Screen *screen, int id);
+static Visual *pick_best_gl_visual (Screen *);
#define DEFAULT_VISUAL -1
#define MONO_VISUAL -3
#define GRAY_VISUAL -4
#define COLOR_VISUAL -5
-#define SPECIFIC_VISUAL -6
+#define GL_VISUAL -6
+#define SPECIFIC_VISUAL -7
Visual *
get_visual (Screen *screen, const char *string, Bool prefer_writable_cells,
for (tmp = v; *tmp; tmp++)
if (isupper (*tmp)) *tmp = _tolower (*tmp);
- if (!v) vclass = BEST_VISUAL;
+ if (!v || !*v) vclass = BEST_VISUAL;
else if (!strcmp (v, "default")) vclass = DEFAULT_VISUAL;
else if (!strcmp (v, "best")) vclass = BEST_VISUAL;
else if (!strcmp (v, "mono")) vclass = MONO_VISUAL;
else if (!strcmp (v, "gray")) vclass = GRAY_VISUAL;
else if (!strcmp (v, "grey")) vclass = GRAY_VISUAL;
else if (!strcmp (v, "color")) vclass = COLOR_VISUAL;
+ else if (!strcmp (v, "gl")) vclass = GL_VISUAL;
else if (!strcmp (v, "staticgray")) vclass = StaticGray;
else if (!strcmp (v, "staticcolor")) vclass = StaticColor;
else if (!strcmp (v, "truecolor")) vclass = TrueColor;
if (!result && verbose_p)
fprintf (stderr, "%s: no color visuals.\n", progname);
}
+ else if (vclass == GL_VISUAL)
+ {
+ Visual *visual = pick_best_gl_visual (screen);
+ if (visual)
+ result = visual;
+ else if (verbose_p)
+ fprintf (stderr, "%s: no visual suitable for GL.\n", progname);
+ }
else if (vclass == SPECIFIC_VISUAL)
{
result = id_to_visual (screen, id);
/* choose the 'best' one, if multiple */
int i, best;
Visual *visual;
- for (i = 0, best = 0; i < out_count; i++)
+/* for (i = 0, best = 0; i < out_count; i++) */
+ for (i = out_count-1, best = i; i >= 0; i--) /* go backwards */
/* It's better if it's deeper, or if it's the same depth with
more cells (does that ever happen? Well, it could...) */
if ((vi_out [i].depth > vi_out [best].depth) ||
}
static Visual *
+pick_best_gl_visual (Screen *screen)
+{
+ /* The best visual for GL is a TrueColor visual that is half as deep as
+ the screen. If such a thing doesn't exist, then TrueColor is best.
+ Failing that, the deepest available color visual is best.
+
+ Compare this function to get_gl_visual() in visual-gl.c.
+ This function tries to find the best GL visual using Xlib calls,
+ whereas that function does the same thing using GLX calls.
+ */
+ Display *dpy = DisplayOfScreen (screen);
+ XVisualInfo vi_in, *vi_out;
+ int out_count;
+ Visual *result = 0;
+
+ int ndepths = 0;
+ int *depths = XListDepths (dpy, screen_number (screen), &ndepths);
+ int screen_depth = depths[ndepths];
+ XFree (depths);
+
+ vi_in.class = TrueColor;
+ vi_in.screen = screen_number (screen);
+ vi_in.depth = screen_depth / 2;
+ vi_out = XGetVisualInfo (dpy, (VisualClassMask | VisualScreenMask |
+ VisualDepthMask),
+ &vi_in, &out_count);
+ if (out_count > 0)
+ result = vi_out[0].visual;
+
+ if (vi_out)
+ XFree ((char *) vi_out);
+
+ if (!result && screen_depth > 24)
+ {
+ /* If it's a 32-deep screen and we didn't find a depth-16 visual,
+ see if there's a depth-12 visual. */
+ vi_in.class = TrueColor;
+ vi_in.screen = screen_number (screen);
+ vi_in.depth = 12;
+ vi_out = XGetVisualInfo (dpy, (VisualClassMask | VisualScreenMask |
+ VisualDepthMask),
+ &vi_in, &out_count);
+ if (out_count > 0)
+ result = vi_out[0].visual;
+ }
+
+ if (!result)
+ /* No half-depth TrueColor? Ok, try for any TrueColor (the deepest.) */
+ result = pick_best_visual_of_class (screen, TrueColor);
+
+ if (!result)
+ /* No TrueColor? Ok, try for anything. */
+ result = pick_best_visual (screen, False, False);
+
+ return result;
+}
+
+
+Visual *
id_to_visual (Screen *screen, int id)
{
Display *dpy = DisplayOfScreen (screen);
return False;
default:
abort();
+ return False;
}
}
if (ScreenOfDisplay (dpy, i) == screen)
return i;
abort ();
+ return 0;
}
int