source: trunk/third/xscreensaver/utils/overlay.c @ 20148

Revision 20148, 5.2 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/* xscreensaver, Copyright (c) 1997, 2001 Jamie Zawinski <jwz@jwz.org>
2 *
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
9 * implied warranty.
10 */
11
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 or more particular pixel values is transparent.
16
17   Vendor support:
18
19    SGI:  - Supported on all systems since IRIX 4.0.
20          - Their version of the Motif toolkit renders menus into the overlay
21            visual, so that they don't cause exposure events on occluded
22            windows.
23          - 2 bit overlay plane with Indigo Entry graphics (e.g., Indy).
24          - 8 bit overlay on O2 with Indigo 24 graphics or better (e.g., O2).
25
26    HP:   - Supported on workstations with CRX24 and CRX48Z graphics hardware.
27          - 8 bit or 24 bit overlay plane.
28          - The default visual is the overlay visual, with a transparent pixel.
29            That way, all Xlib programs draw into the overlay plane, and no
30            Xlib program causes exposures on occluded OpenGL windows.
31
32    IBM:  - Supported on some graphics hardware (which?)
33
34    DEC:  - Supported on some graphics hardware (which?)
35
36    SUN:  - Some systems apparently implement it VERRRRRRY SLOWLY, so drawing
37            into the overlay plane is a performance killer (about as bad as
38            using the SHAPE extension.)
39
40
41   On my Indy, there are two transparent visuals, one of which is at layer 1,
42   and one of which is at layer 2.  This is apparently the ordering in which
43   they are overlayed (1 being topmost.)  The other difference between them
44   is that the topmost one only has 2 planes, while the next one has 8.
45
46   This code selects the topmost one, regardless of depth.  Maybe that's not
47   the right thing.  Well, in XScreenSaver, we only need to allocate two
48   colors from it (it's only used to display the stderr output, so that the
49   text can overlay the graphics without being obliterated by it.)
50
51   Documentation, such as it is, on SERVER_OVERLAY_VISUALS found on the web:
52
53     http://www.hp.com/xwindow/sharedInfo/Whitepapers/Visuals/server_overlay_visuals.html
54    http://www.xig.com/Pages/Ed-Overlays.html
55 */
56
57
58#include "utils.h"
59
60#include <X11/Xutil.h>
61#include <X11/Xproto.h>
62
63#include "visual.h"
64
65
66struct overlay_data
67{
68  CARD32 visual_id;
69  CARD32 transparency;  /* 0: none; 1: pixel; 2: mask
70                           ("mask" means "any pixel with these bits set
71                           is a transparent pixel")
72                         */
73  CARD32 value;         /* the transparent pixel or mask */
74  CARD32 layer;         /* -1: underlay; 0: normal; 1: popup; 2: overlay */
75};
76
77static int
78get_overlay_prop (Screen *screen, struct overlay_data **data_ret)
79{
80  int result;
81  Atom actual_type;
82  int actual_format;
83  unsigned long nitems, bytes_after;
84  struct overlay_data *data = 0;
85  Display *dpy = DisplayOfScreen(screen);
86  Window window = RootWindowOfScreen(screen);
87  Atom XA_SERVER_OVERLAY_VISUALS =
88    XInternAtom (dpy, "SERVER_OVERLAY_VISUALS", False);
89
90  *data_ret = 0;
91  result = XGetWindowProperty (dpy, window, XA_SERVER_OVERLAY_VISUALS,
92                               0, (65536 / sizeof (long)), False,
93                               XA_SERVER_OVERLAY_VISUALS,
94                               &actual_type, &actual_format,
95                               &nitems, &bytes_after,
96                               (unsigned char **) &data);
97  if (result != Success ||
98      actual_type != XA_SERVER_OVERLAY_VISUALS ||
99      actual_format != 32 ||
100      nitems < 1)
101    {
102      if (data) XFree(data);
103      return 0;
104    }
105  else
106    {
107      *data_ret = data;
108      return nitems / (sizeof(*data) / sizeof(CARD32));
109    }
110}
111
112
113Visual *
114get_overlay_visual (Screen *screen, unsigned long *transparent_pixel_ret)
115{
116  struct overlay_data *data = 0;
117  int n_visuals = get_overlay_prop (screen, &data);
118  Visual *visual = 0;
119  int depth = 0;
120  unsigned long pixel = 0;
121  unsigned int layer = 0;
122  int i;
123
124  if (data)
125    for (i = 0; i < n_visuals; i++)
126
127      /* Only accept ones that have a transparent pixel or mask. */
128      if (data[i].transparency == 1 ||
129          data[i].transparency == 2)
130        {
131          XVisualInfo vi_in, *vi_out;
132          int out_count;
133          vi_in.visualid = data[i].visual_id;
134          vi_out = XGetVisualInfo (DisplayOfScreen(screen), VisualIDMask,
135                                   &vi_in, &out_count);
136          if (vi_out)
137            {
138              /* Prefer the one at the topmost layer; after that, prefer
139                 the one with the greatest depth (most colors.) */
140              if (layer < data[i].layer ||
141                  (layer == data[i].layer &&
142                   depth < vi_out[0].depth))
143                {
144                  visual = vi_out[0].visual;
145                  depth  = vi_out[0].depth;
146                  layer  = data[i].layer;
147                  pixel  = data[i].value;
148                }
149              XFree(vi_out);
150            }
151        }
152
153  if (data) XFree(data);
154  if (visual && transparent_pixel_ret)
155    *transparent_pixel_ret = pixel;
156  return visual;
157}
Note: See TracBrowser for help on using the repository browser.