1 
2 /* Copyright (c) Mark J. Kilgard, 1993, 1994. */
3 
4 /* This program is freely distributable without licensing fees
5    and is provided without guarantee or warrantee expressed or
6    implied. This program is -not- in the public domain. */
7 
8 /* Based on XLayerUtil.c: Revision: 1.5 */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "layerutil.h"
13 
14 /* SGI optimization introduced in IRIX 6.3 to avoid X server
15    round trips for interning common X atoms. */
16 #include <X11/Xatom.h>
17 #if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
18 #include <X11/SGIFastAtom.h>
19 #else
20 #define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
21 #endif
22 
23 static Bool layersRead = False;
24 static OverlayInfo **overlayInfoPerScreen;
25 static unsigned long *numOverlaysPerScreen;
26 
27 static void
findServerOverlayVisualsInfo(Display * dpy)28 findServerOverlayVisualsInfo(Display * dpy)
29 {
30   static Atom overlayVisualsAtom;
31   Atom actualType;
32   Status status;
33   unsigned long sizeData, bytesLeft;
34   Window root;
35   int actualFormat, numScreens, i;
36 
37   if (layersRead == False) {
38     overlayVisualsAtom = XSGIFastInternAtom(dpy,
39       "SERVER_OVERLAY_VISUALS", SGI_XA_SERVER_OVERLAY_VISUALS, True);
40     if (overlayVisualsAtom != None) {
41       numScreens = ScreenCount(dpy);
42       overlayInfoPerScreen = (OverlayInfo **)
43         malloc(numScreens * sizeof(OverlayInfo *));
44       numOverlaysPerScreen = (unsigned long *)
45         malloc(numScreens * sizeof(unsigned long));
46       if (overlayInfoPerScreen != NULL &&
47         numOverlaysPerScreen != NULL) {
48         for (i = 0; i < numScreens; i++) {
49           root = RootWindow(dpy, i);
50           status = XGetWindowProperty(dpy, root,
51             overlayVisualsAtom, 0L, (long) 10000, False,
52             overlayVisualsAtom, &actualType, &actualFormat,
53             &sizeData, &bytesLeft,
54             (unsigned char **) &overlayInfoPerScreen[i]);
55           if (status != Success ||
56             actualType != overlayVisualsAtom ||
57             actualFormat != 32 || sizeData < 4)
58             numOverlaysPerScreen[i] = 0;
59           else
60             /* Four 32-bit quantities per
61                SERVER_OVERLAY_VISUALS entry. */
62             numOverlaysPerScreen[i] = sizeData / 4;
63         }
64         layersRead = True;
65       } else {
66         if (overlayInfoPerScreen != NULL)
67           free(overlayInfoPerScreen);
68         if (numOverlaysPerScreen != NULL)
69           free(numOverlaysPerScreen);
70       }
71     }
72   }
73 }
74 
75 int
__glutGetTransparentPixel(Display * dpy,XVisualInfo * vinfo)76 __glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo)
77 {
78   int i, screen = vinfo->screen;
79   OverlayInfo *overlayInfo;
80 
81   findServerOverlayVisualsInfo(dpy);
82   if (layersRead) {
83     for (i = 0; i < numOverlaysPerScreen[screen]; i++) {
84       overlayInfo = &overlayInfoPerScreen[screen][i];
85       if (vinfo->visualid == overlayInfo->overlay_visual) {
86         if (overlayInfo->transparent_type == TransparentPixel) {
87           return (int) overlayInfo->value;
88         } else {
89           return -1;
90         }
91       }
92     }
93   }
94   return -1;
95 }
96 
97 XLayerVisualInfo *
__glutXGetLayerVisualInfo(Display * dpy,long lvinfo_mask,XLayerVisualInfo * lvinfo_template,int * nitems_return)98 __glutXGetLayerVisualInfo(Display * dpy, long lvinfo_mask,
99   XLayerVisualInfo * lvinfo_template, int *nitems_return)
100 {
101   XVisualInfo *vinfo;
102   XLayerVisualInfo *layerInfo;
103   int numVisuals, count, i, j;
104 
105   vinfo = XGetVisualInfo(dpy, lvinfo_mask & VisualAllMask,
106     &lvinfo_template->vinfo, nitems_return);
107   if (vinfo == NULL)
108     return NULL;
109   numVisuals = *nitems_return;
110   findServerOverlayVisualsInfo(dpy);
111   layerInfo = (XLayerVisualInfo *)
112     malloc(numVisuals * sizeof(XLayerVisualInfo));
113   if (layerInfo == NULL) {
114     XFree(vinfo);
115     return NULL;
116   }
117   count = 0;
118   for (i = 0; i < numVisuals; i++) {
119     XVisualInfo *pVinfo = &vinfo[i];
120     int screen = pVinfo->screen;
121     OverlayInfo *overlayInfo = NULL;
122 
123     overlayInfo = NULL;
124     if (layersRead) {
125       for (j = 0; j < numOverlaysPerScreen[screen]; j++)
126         if (pVinfo->visualid ==
127           overlayInfoPerScreen[screen][j].overlay_visual) {
128           overlayInfo = &overlayInfoPerScreen[screen][j];
129           break;
130         }
131     }
132     if (lvinfo_mask & VisualLayerMask)
133       if (overlayInfo == NULL) {
134         if (lvinfo_template->layer != 0)
135           continue;
136       } else if (lvinfo_template->layer != overlayInfo->layer)
137         continue;
138     if (lvinfo_mask & VisualTransparentType)
139       if (overlayInfo == NULL) {
140         if (lvinfo_template->type != None)
141           continue;
142       } else if (lvinfo_template->type !=
143         overlayInfo->transparent_type)
144         continue;
145     if (lvinfo_mask & VisualTransparentValue)
146       if (overlayInfo == NULL)
147         /* Non-overlay visuals have no sense of
148            TransparentValue. */
149         continue;
150       else if (lvinfo_template->value != overlayInfo->value)
151         continue;
152     layerInfo[count].vinfo = *pVinfo;
153     if (overlayInfo == NULL) {
154       layerInfo[count].layer = 0;
155       layerInfo[count].type = None;
156       layerInfo[count].value = 0;  /* meaningless */
157     } else {
158       layerInfo[count].layer = overlayInfo->layer;
159       layerInfo[count].type = overlayInfo->transparent_type;
160       layerInfo[count].value = overlayInfo->value;
161     }
162     count++;
163   }
164   XFree(vinfo);
165   *nitems_return = count;
166   if (count == 0) {
167     XFree(layerInfo);
168     return NULL;
169   } else
170     return layerInfo;
171 }
172 
173 #if 0                   /* Unused by GLUT. */
174 Status
175 __glutXMatchLayerVisualInfo(Display * dpy, int screen,
176   int depth, int class, int layer,
177   XLayerVisualInfo * lvinfo_return)
178 {
179   XLayerVisualInfo *lvinfo;
180   XLayerVisualInfo lvinfoTemplate;
181   int nitems;
182 
183   lvinfoTemplate.vinfo.screen = screen;
184   lvinfoTemplate.vinfo.depth = depth;
185   lvinfoTemplate.vinfo.class = class;
186   lvinfoTemplate.layer = layer;
187   lvinfo = __glutXGetLayerVisualInfo(dpy,
188     VisualScreenMask | VisualDepthMask |
189     VisualClassMask | VisualLayerMask,
190     &lvinfoTemplate, &nitems);
191   if (lvinfo != NULL && nitems > 0) {
192     *lvinfo_return = *lvinfo;
193     return 1;
194   } else
195     return 0;
196 }
197 #endif
198