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