Added -linker option to mklib, used to specify a particular program for
[mesa.git] / src / glut / glx / layerutil.c
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
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
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 *
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 }
139 if (lvinfo_mask & VisualTransparentType) {
140 if (overlayInfo == NULL) {
141 if (lvinfo_template->type != None)
142 continue;
143 } else if (lvinfo_template->type !=
144 overlayInfo->transparent_type)
145 continue;
146 }
147 if (lvinfo_mask & VisualTransparentValue) {
148 if (overlayInfo == NULL)
149 /* Non-overlay visuals have no sense of
150 TransparentValue. */
151 continue;
152 else if (lvinfo_template->value != overlayInfo->value)
153 continue;
154 }
155 layerInfo[count].vinfo = *pVinfo;
156 if (overlayInfo == NULL) {
157 layerInfo[count].layer = 0;
158 layerInfo[count].type = None;
159 layerInfo[count].value = 0; /* meaningless */
160 } else {
161 layerInfo[count].layer = overlayInfo->layer;
162 layerInfo[count].type = overlayInfo->transparent_type;
163 layerInfo[count].value = overlayInfo->value;
164 }
165 count++;
166 }
167 XFree(vinfo);
168 *nitems_return = count;
169 if (count == 0) {
170 XFree(layerInfo);
171 return NULL;
172 } else
173 return layerInfo;
174 }
175
176 #if 0 /* Unused by GLUT. */
177 Status
178 __glutXMatchLayerVisualInfo(Display * dpy, int screen,
179 int depth, int visualClass, int layer,
180 XLayerVisualInfo * lvinfo_return)
181 {
182 XLayerVisualInfo *lvinfo;
183 XLayerVisualInfo lvinfoTemplate;
184 int nitems;
185
186 lvinfoTemplate.vinfo.screen = screen;
187 lvinfoTemplate.vinfo.depth = depth;
188 #if defined(__cplusplus) || defined(c_plusplus)
189 lvinfoTemplate.vinfo.c_class = visualClass;
190 #else
191 lvinfoTemplate.vinfo.class = visualClass;
192 #endif
193 lvinfoTemplate.layer = layer;
194 lvinfo = __glutXGetLayerVisualInfo(dpy,
195 VisualScreenMask | VisualDepthMask |
196 VisualClassMask | VisualLayerMask,
197 &lvinfoTemplate, &nitems);
198 if (lvinfo != NULL && nitems > 0) {
199 *lvinfo_return = *lvinfo;
200 return 1;
201 } else
202 return 0;
203 }
204 #endif