1 /* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@jwz.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 /* If the server's root window contains a SERVER_OVERLAY_VISUALS property,
13 then that identifies the visuals which correspond to the video hardware's
14 overlay planes. Windows created in these kinds of visuals have the
15 property that one particular pixel value is transparent.
17 On my Indy, there are two transparent visuals, one of which is at layer 1,
18 and one of which is at layer 2. This is apparently the ordering in which
19 they are overlayed (1 being topmost.) The other difference between them
20 is that the topmost one only has 2 planes, while the next one has 8.
22 Rumor has it that SGI, HP, DEC, and IBM all use the same mechanism.
24 This code selects the topmost one, regardless of depth. Maybe that's not
25 the right thing. Well, in XScreenSaver, we only need to allocate two
26 colors from it (it's only used to display the stderr output, so that the
27 text can overlay the graphics without being obliterated by it.)
33 #include <X11/Xutil.h>
34 #include <X11/Xproto.h>
42 CARD32 transparency; /* 0: none; 1: pixel; 2: mask (?) */
43 CARD32 value; /* the transparent pixel */
44 CARD32 layer; /* -1: underlay; 0: normal; 1: popup; 2: overlay */
48 get_overlay_prop (Screen *screen, struct overlay_data **data_ret)
53 unsigned long nitems, bytes_after;
54 struct overlay_data *data = 0;
55 Display *dpy = DisplayOfScreen(screen);
56 Window window = RootWindowOfScreen(screen);
57 Atom XA_SERVER_OVERLAY_VISUALS =
58 XInternAtom (dpy, "SERVER_OVERLAY_VISUALS", False);
61 result = XGetWindowProperty (dpy, window, XA_SERVER_OVERLAY_VISUALS,
62 0, (65536 / sizeof (long)), False,
63 XA_SERVER_OVERLAY_VISUALS,
64 &actual_type, &actual_format,
65 &nitems, &bytes_after,
66 (unsigned char **) &data);
67 if (result != Success ||
68 actual_type != XA_SERVER_OVERLAY_VISUALS ||
69 actual_format != 32 ||
72 if (data) XFree(data);
78 return nitems / (sizeof(*data) / sizeof(CARD32));
84 get_overlay_visual (Screen *screen, unsigned long *transparent_pixel_ret)
86 struct overlay_data *data = 0;
87 int n_visuals = get_overlay_prop (screen, &data);
90 unsigned long pixel = 0;
91 unsigned int layer = 0;
95 for (i = 0; i < n_visuals; i++)
97 /* Only accept ones that have a transparent pixel. */
98 if (data[i].transparency == 1)
100 XVisualInfo vi_in, *vi_out;
102 vi_in.visualid = data[i].visual_id;
103 vi_out = XGetVisualInfo (DisplayOfScreen(screen), VisualIDMask,
107 /* Prefer the one at the topmost layer; after that, prefer
108 the one with the greatest depth (most colors.) */
109 if (layer < data[i].layer ||
110 (layer == data[i].layer &&
111 depth < vi_out[0].depth))
113 visual = vi_out[0].visual;
114 depth = vi_out[0].depth;
115 layer = data[i].layer;
116 pixel = data[i].value;
122 if (data) XFree(data);
123 if (visual && transparent_pixel_ret)
124 *transparent_pixel_ret = pixel;