-/* xscreensaver, Copyright (c) 1993 Jamie Zawinski <jwz@lucid.com>
+/* xscreensaver, Copyright (c) 1993 Jamie Zawinski <jwz@mcom.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#if __STDC__
#include <stdlib.h>
+#include <unistd.h>
+#endif
+
+#ifdef __DECC
+typedef char * caddr_t;
#endif
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#if __STDC__
+# define P(x)x
+#else
+#define P(x)()
+#endif
+
#ifndef isupper
# define isupper(c) ((c) >= 'A' && (c) <= 'Z')
#endif
#endif
extern char *progname;
-extern char *get_string_resource ();
+extern char *get_string_resource P((char *, char *));
+
+static Visual *pick_best_visual P ((Screen *));
+static Visual *pick_best_visual_of_class P((Screen *, int));
+static Visual *id_to_visual P((Screen *, int));
+static int visual_depth P((Display *, Visual *));
+static int screen_number P((Screen *));
+static Visual *id_to_visual P((Screen *screen, int id));
+
+
+#define DEFAULT_VISUAL -1
+#define BEST_VISUAL -2
+#define SPECIFIC_VISUAL -3
+
+Visual *
+get_visual_resource (dpy, name, class)
+ Display *dpy;
+ char *name, *class;
+{
+ Screen *screen = DefaultScreenOfDisplay (dpy);
+ char c, *v = get_string_resource (name, class);
+ char *tmp;
+ int vclass;
+ unsigned long id;
+
+ if (v)
+ for (tmp = v; *tmp; tmp++)
+ if (isupper (*tmp)) *tmp = _tolower (*tmp);
+
+ if (!v) vclass = BEST_VISUAL;
+ else if (!strcmp (v, "default")) vclass = DEFAULT_VISUAL;
+ else if (!strcmp (v, "best")) vclass = BEST_VISUAL;
+ else if (!strcmp (v, "staticgray")) vclass = StaticGray;
+ else if (!strcmp (v, "staticcolor")) vclass = StaticColor;
+ else if (!strcmp (v, "truecolor")) vclass = TrueColor;
+ else if (!strcmp (v, "grayscale")) vclass = GrayScale;
+ else if (!strcmp (v, "pseudocolor")) vclass = PseudoColor;
+ else if (!strcmp (v, "directcolor")) vclass = DirectColor;
+ else if (1 == sscanf (v, " %ld %c", &id, &c)) vclass = SPECIFIC_VISUAL;
+ else if (1 == sscanf (v, " 0x%lx %c", &id, &c)) vclass = SPECIFIC_VISUAL;
+ else
+ {
+ fprintf (stderr, "%s: unrecognized visual \"%s\".\n", progname, v);
+ vclass = DEFAULT_VISUAL;
+ }
+ if (v) free (v);
+
+ if (vclass == DEFAULT_VISUAL)
+ return DefaultVisualOfScreen (screen);
+ else if (vclass == BEST_VISUAL)
+ return pick_best_visual (screen);
+ else if (vclass == SPECIFIC_VISUAL)
+ {
+ Visual *visual = id_to_visual (screen, id);
+ if (visual) return visual;
+ fprintf (stderr, "%s: no visual with id 0x%x.\n", progname,
+ (unsigned int) id);
+ return DefaultVisualOfScreen (screen);
+ }
+ else
+ {
+ Visual *visual = pick_best_visual_of_class (screen, vclass);
+ if (visual) return visual;
+ fprintf (stderr, "%s: no visual of class %s.\n", progname, v);
+ return DefaultVisualOfScreen (screen);
+ }
+}
+
+static Visual *
+pick_best_visual (screen)
+ Screen *screen;
+{
+ /* The "best" visual is the one on which we can allocate the largest
+ range and number of colors.
+
+ Therefore, a TrueColor visual which is at least 16 bits deep is best.
+ (The assumption here being that a TrueColor of less than 16 bits is
+ really just a PseudoColor visual with a pre-allocated color cube.)
+
+ The next best thing is a PseudoColor visual of any type. After that
+ come the non-colormappable visuals, and non-color visuals.
+ */
+ Display *dpy = DisplayOfScreen (screen);
+ Visual *visual;
+ if ((visual = pick_best_visual_of_class (screen, TrueColor)) &&
+ visual_depth (dpy, visual) >= 16)
+ return visual;
+ if ((visual = pick_best_visual_of_class (screen, PseudoColor)))
+ return visual;
+ if ((visual = pick_best_visual_of_class (screen, TrueColor)))
+ return visual;
+ if ((visual = pick_best_visual_of_class (screen, DirectColor)))
+ return visual;
+ if ((visual = pick_best_visual_of_class (screen, GrayScale)))
+ return visual;
+ if ((visual = pick_best_visual_of_class (screen, StaticGray)))
+ return visual;
+ return DefaultVisualOfScreen (screen);
+}
static Visual *
-pick_best_visual_of_class (display, visual_class)
- Display *display;
+pick_best_visual_of_class (screen, visual_class)
+ Screen *screen;
int visual_class;
{
+ /* The best visual of a class is the one which on which we can allocate
+ the largest range and number of colors, which means the one with the
+ greatest depth and number of cells.
+ */
+ Display *dpy = DisplayOfScreen (screen);
XVisualInfo vi_in, *vi_out;
int out_count;
vi_in.class = visual_class;
- vi_in.screen = DefaultScreen (display);
- vi_out = XGetVisualInfo (display, VisualClassMask|VisualScreenMask,
+ vi_in.screen = screen_number (screen);
+ vi_out = XGetVisualInfo (dpy, (VisualClassMask | VisualScreenMask),
&vi_in, &out_count);
if (vi_out)
- { /* choose the 'best' one, if multiple */
+ {
+ /* choose the 'best' one, if multiple */
int i, best;
Visual *visual;
for (i = 0, best = 0; i < out_count; i++)
- if (vi_out [i].depth > vi_out [best].depth)
+ /* 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) ||
+ ((vi_out [i].depth == vi_out [best].depth) &&
+ (vi_out [i].colormap_size > vi_out [best].colormap_size)))
best = i;
visual = vi_out [best].visual;
XFree ((char *) vi_out);
}
static Visual *
-pick_best_visual (display)
- Display *display;
-{
- Visual *visual;
- if (visual = pick_best_visual_of_class (display, PseudoColor))
- return visual;
- if (visual = pick_best_visual_of_class (display, DirectColor))
- return visual;
- if (visual = pick_best_visual_of_class (display, GrayScale))
- return visual;
- if (visual = pick_best_visual_of_class (display, StaticGray))
- return visual;
- return DefaultVisual (display, DefaultScreen (display));
-}
-
-
-static Visual *
-id_to_visual (dpy, id)
- Display *dpy;
+id_to_visual (screen, id)
+ Screen *screen;
int id;
{
+ Display *dpy = DisplayOfScreen (screen);
XVisualInfo vi_in, *vi_out;
int out_count;
- vi_in.screen = DefaultScreen (dpy);
+ vi_in.screen = screen_number (screen);
vi_in.visualid = id;
- vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
+ vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
&vi_in, &out_count);
if (vi_out)
{
return c;
}
-
-Visual *
-get_visual_resource (dpy, name, class)
- Display *dpy;
- char *name, *class;
-{
- char c, *s = get_string_resource (name, class);
- char *tmp;
- int vclass;
- int id;
-
- if (s)
- for (tmp = s; *tmp; tmp++)
- if (isupper (*tmp)) *tmp = _tolower (*tmp);
-
- if (!s || !strcmp (s, "best")) vclass = -1;
- else if (!strcmp (s, "default")) vclass = -2;
- else if (!strcmp (s, "staticgray")) vclass = StaticGray;
- else if (!strcmp (s, "staticcolor")) vclass = StaticColor;
- else if (!strcmp (s, "truecolor")) vclass = TrueColor;
- else if (!strcmp (s, "grayscale")) vclass = GrayScale;
- else if (!strcmp (s, "pseudocolor")) vclass = PseudoColor;
- else if (!strcmp (s, "directcolor")) vclass = DirectColor;
- else if (1 == sscanf (s, " %ld %c", &id, &c)) vclass = -3;
- else if (1 == sscanf (s, " 0x%lx %c", &id, &c)) vclass = -3;
- else
- {
- fprintf (stderr, "%s: unrecognized visual \"%s\".\n", progname, s);
- vclass = -1;
- }
- if (s) free (s);
-
- if (vclass == -1)
- return pick_best_visual (dpy);
- else if (vclass == -2)
- return DefaultVisual (dpy, DefaultScreen (dpy));
- else if (vclass == -3)
- {
- Visual *v = id_to_visual (dpy, id);
- if (v) return v;
- fprintf (stderr, "%s: no visual with id 0x%x.\n", progname, id);
- return pick_best_visual (dpy);
- }
- else
- return pick_best_visual_of_class (dpy, vclass);
-}
-
void
describe_visual (f, dpy, visual)
FILE *f;
Display *dpy;
Visual *visual;
{
+ Screen *screen = DefaultScreenOfDisplay (dpy);
XVisualInfo vi_in, *vi_out;
- int out_count, d;
- vi_in.screen = DefaultScreen (dpy);
+ int out_count;
+ vi_in.screen = screen_number (screen);
vi_in.visualid = XVisualIDFromVisual (visual);
- vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
+ vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
&vi_in, &out_count);
if (! vi_out) abort ();
- fprintf (f, "0x%02x (%s depth: %2d, cmap: %3d @ %d)\n", vi_out->visualid,
+ fprintf (f, "0x%02x (%s depth: %2d, cmap: %3d)\n",
+ (unsigned int) vi_out->visualid,
(vi_out->class == StaticGray ? "StaticGray, " :
vi_out->class == StaticColor ? "StaticColor," :
vi_out->class == TrueColor ? "TrueColor, " :
vi_out->class == GrayScale ? "GrayScale, " :
vi_out->class == PseudoColor ? "PseudoColor," :
vi_out->class == DirectColor ? "DirectColor," :
- "???"),
- vi_out->depth, vi_out->colormap_size, vi_out->bits_per_rgb);
+ "UNKNOWN: "),
+ vi_out->depth, vi_out->colormap_size /*, vi_out->bits_per_rgb*/);
+ XFree ((char *) vi_out);
+}
+
+static int
+screen_number (screen)
+ Screen *screen;
+{
+ Display *dpy = DisplayOfScreen (screen);
+ int i;
+ for (i = 0; i < ScreenCount (dpy); i++)
+ if (ScreenOfDisplay (dpy, i) == screen)
+ return i;
+ abort ();
+}
+
+static int
+visual_depth (dpy, visual)
+ Display *dpy;
+ Visual *visual;
+{
+ XVisualInfo vi_in, *vi_out;
+ int out_count, d;
+ vi_in.screen = DefaultScreen (dpy);
+ vi_in.visualid = XVisualIDFromVisual (visual);
+ vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
+ &vi_in, &out_count);
+ if (! vi_out) abort ();
+ d = vi_out [0].depth;
XFree ((char *) vi_out);
+ return d;
+}
+
+int
+visual_cells (dpy, visual)
+ Display *dpy;
+ Visual *visual;
+{
+ XVisualInfo vi_in, *vi_out;
+ int out_count, c;
+ vi_in.screen = DefaultScreen (dpy);
+ vi_in.visualid = XVisualIDFromVisual (visual);
+ vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
+ &vi_in, &out_count);
+ if (! vi_out) abort ();
+ c = vi_out [0].colormap_size;
+ XFree ((char *) vi_out);
+ return c;
}