X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utils%2Fvisual.c;h=c6764ba929f9edc0fd92bea1b596002705c65db9;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hp=c37b6baa5e899628f12ff94e18398190a9bb1b33;hpb=5832fe184606766fef23369159306c0a5799aeb0;p=xscreensaver diff --git a/utils/visual.c b/utils/visual.c index c37b6baa..c6764ba9 100644 --- a/utils/visual.c +++ b/utils/visual.c @@ -1,5 +1,4 @@ -/* xscreensaver, Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999 - * by Jamie Zawinski +/* xscreensaver, Copyright (c) 1993-2017 by Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -19,11 +18,15 @@ #include "resources.h" /* for get_string_resource() */ #include "visual.h" +#include +#ifndef HAVE_ANDROID #include +#else +#include "../android/android-visual.h" +#endif extern char *progname; - #ifndef isupper # define isupper(c) ((c) >= 'A' && (c) <= 'Z') #endif @@ -36,8 +39,6 @@ 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 *pick_best_gl_visual (Screen *); -static Visual *id_to_visual (Screen *, int); -static Visual *id_to_visual (Screen *screen, int id); #define DEFAULT_VISUAL -1 @@ -78,7 +79,7 @@ get_visual (Screen *screen, const char *string, Bool prefer_writable_cells, else if (!strcmp (v, "greyscale")) 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, " %lu %c", &id, &c)) vclass = SPECIFIC_VISUAL; else if (1 == sscanf (v, " 0x%lx %c", &id, &c)) vclass = SPECIFIC_VISUAL; else { @@ -135,7 +136,7 @@ get_visual (Screen *screen, const char *string, Bool prefer_writable_cells, if (visual) result = visual; else if (verbose_p) - fprintf (stderr, "%s: no visual suitable for GL.\n", progname, v); + fprintf (stderr, "%s: no visual suitable for GL.\n", progname); } else if (vclass == SPECIFIC_VISUAL) { @@ -161,7 +162,7 @@ Visual * get_visual_resource (Screen *screen, char *name, char *class, Bool prefer_writable_cells) { - char *string = get_string_resource (name, class); + char *string = get_string_resource (DisplayOfScreen (screen), name, class); Visual *v = get_visual (screen, string, prefer_writable_cells, True); if (string) free(string); @@ -263,7 +264,8 @@ pick_best_visual_of_class (Screen *screen, int visual_class) /* 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) || @@ -296,7 +298,7 @@ pick_best_gl_visual (Screen *screen) int ndepths = 0; int *depths = XListDepths (dpy, screen_number (screen), &ndepths); - int screen_depth = depths[ndepths]; + int screen_depth = (depths && ndepths) ? depths[ndepths - 1] : 0; XFree (depths); vi_in.class = TrueColor; @@ -325,7 +327,7 @@ pick_best_gl_visual (Screen *screen) result = vi_out[0].visual; } - if (result) + if (!result) /* No half-depth TrueColor? Ok, try for any TrueColor (the deepest.) */ result = pick_best_visual_of_class (screen, TrueColor); @@ -337,16 +339,30 @@ pick_best_gl_visual (Screen *screen) } -static Visual * -id_to_visual (Screen *screen, int id) +static XVisualInfo * +visual_info_id (Screen *screen, int id) { Display *dpy = DisplayOfScreen (screen); - XVisualInfo vi_in, *vi_out; + XVisualInfo vi_in; int out_count; vi_in.screen = screen_number (screen); vi_in.visualid = id; - vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask), - &vi_in, &out_count); + return XGetVisualInfo (dpy, VisualScreenMask | VisualIDMask, + &vi_in, &out_count); +} + +static XVisualInfo * +visual_info (Screen *screen, Visual *visual) +{ + XVisualInfo *vi_out = visual_info_id (screen, XVisualIDFromVisual (visual)); + if (! vi_out) abort (); + return vi_out; +} + +Visual * +id_to_visual (Screen *screen, int id) +{ + XVisualInfo *vi_out = visual_info_id (screen, id); if (vi_out) { Visual *v = vi_out[0].visual; @@ -359,27 +375,34 @@ id_to_visual (Screen *screen, int id) int visual_depth (Screen *screen, Visual *visual) { - Display *dpy = DisplayOfScreen (screen); - XVisualInfo vi_in, *vi_out; - int out_count, d; - 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 (); - d = vi_out [0].depth; + XVisualInfo *vi_out = visual_info (screen, visual); + int d = vi_out [0].depth; XFree ((char *) vi_out); return d; } -#if 0 /* You very probably don't want to be using this. Pixmap depth doesn't refer to the depths of pixmaps, but rather, to the depth of protocol-level on-the-wire pixmap data, that is, XImages. To get this info, you should be looking at XImage->bits_per_pixel instead. (And allocating the data for your XImage structures by multiplying ximage->bytes_per_line by ximage->height.) + + Still, it can be useful to know bits_per_pixel before the XImage exists. + + XCreateImage calls _XGetBitsPerPixel to figure this out, but that function + is private to Xlib. + + For some reason, _XGetBitsPerPixel tries a hard-coded list of depths if + it doesn't find a matching pixmap format, but I (Dave Odell) couldn't + find any justification for this in the X11 spec. And the XFree86 CVS + repository doesn't quite go back far enough to shed any light on what + the deal is with that. + http://cvsweb.xfree86.org/cvsweb/xc/lib/X11/ImUtil.c + + The hard-coded list apparently was added between X11R5 and X11R6. + See . */ int visual_pixmap_depth (Screen *screen, Visual *visual) @@ -403,21 +426,13 @@ visual_pixmap_depth (Screen *screen, Visual *visual) XFree (pfv); return pdepth; } -#endif /* 0 */ int visual_class (Screen *screen, Visual *visual) { - Display *dpy = DisplayOfScreen (screen); - XVisualInfo vi_in, *vi_out; - int out_count, c; - 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 (); - c = vi_out [0].class; + XVisualInfo *vi_out = visual_info (screen, visual); + int c = vi_out [0].class; XFree ((char *) vi_out); return c; } @@ -429,13 +444,12 @@ has_writable_cells (Screen *screen, Visual *visual) { case GrayScale: /* Mappable grays. */ case PseudoColor: /* Mappable colors. */ + case DirectColor: /* Like TrueColor, but with three colormaps: + one each for red, green, and blue. */ return True; case StaticGray: /* Fixed grays. */ case TrueColor: /* Fixed colors. */ - case StaticColor: /* (What's the difference again?) */ - case DirectColor: /* DirectColor visuals are like TrueColor, but have - three colormaps - one for each component of RGB. - Screw it. */ + case StaticColor: /* Like PseudoColor with an unmodifiable colormap. */ return False; default: abort(); @@ -447,14 +461,7 @@ void describe_visual (FILE *f, Screen *screen, Visual *visual, Bool private_cmap_p) { char n[10]; - Display *dpy = DisplayOfScreen (screen); - XVisualInfo vi_in, *vi_out; - int out_count; - 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 (); + XVisualInfo *vi_out = visual_info (screen, visual); if (private_cmap_p) sprintf(n, "%3d", vi_out->colormap_size); else @@ -488,15 +495,8 @@ screen_number (Screen *screen) int visual_cells (Screen *screen, Visual *visual) { - Display *dpy = DisplayOfScreen (screen); - XVisualInfo vi_in, *vi_out; - int out_count, c; - 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 (); - c = vi_out [0].colormap_size; + XVisualInfo *vi_out = visual_info (screen, visual); + int c = vi_out [0].colormap_size; XFree ((char *) vi_out); return c; } @@ -541,3 +541,15 @@ find_similar_visual(Screen *screen, Visual *old_visual) return result; } + + +void +visual_rgb_masks (Screen *screen, Visual *visual, unsigned long *red_mask, + unsigned long *green_mask, unsigned long *blue_mask) +{ + XVisualInfo *vi_out = visual_info (screen, visual); + *red_mask = vi_out->red_mask; + *green_mask = vi_out->green_mask; + *blue_mask = vi_out->blue_mask; + XFree ((char *) vi_out); +}