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#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS) 17#include <X11/SGIFastAtom.h> 18#else 19#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how) 20#endif 21 22static Bool layersRead = False; 23static OverlayInfo **overlayInfoPerScreen; 24static unsigned long *numOverlaysPerScreen; 25 26static void 27findServerOverlayVisualsInfo(Display * dpy) 28{ 29 static Atom overlayVisualsAtom; 30 Atom actualType; 31 Status status; 32 unsigned long sizeData, bytesLeft; 33 Window root; 34 int actualFormat, numScreens, i; 35 36 if (layersRead == False) { 37 overlayVisualsAtom = XSGIFastInternAtom(dpy, 38 "SERVER_OVERLAY_VISUALS", SGI_XA_SERVER_OVERLAY_VISUALS, True); 39 if (overlayVisualsAtom != None) { 40 numScreens = ScreenCount(dpy); 41 overlayInfoPerScreen = (OverlayInfo **) 42 malloc(numScreens * sizeof(OverlayInfo *)); 43 numOverlaysPerScreen = (unsigned long *) 44 malloc(numScreens * sizeof(unsigned long)); 45 if (overlayInfoPerScreen != NULL && 46 numOverlaysPerScreen != NULL) { 47 for (i = 0; i < numScreens; i++) { 48 root = RootWindow(dpy, i); 49 status = XGetWindowProperty(dpy, root, 50 overlayVisualsAtom, 0L, (long) 10000, False, 51 overlayVisualsAtom, &actualType, &actualFormat, 52 &sizeData, &bytesLeft, 53 (unsigned char **) &overlayInfoPerScreen[i]); 54 if (status != Success || 55 actualType != overlayVisualsAtom || 56 actualFormat != 32 || sizeData < 4) 57 numOverlaysPerScreen[i] = 0; 58 else 59 /* Four 32-bit quantities per 60 SERVER_OVERLAY_VISUALS entry. */ 61 numOverlaysPerScreen[i] = sizeData / 4; 62 } 63 layersRead = True; 64 } else { 65 if (overlayInfoPerScreen != NULL) 66 free(overlayInfoPerScreen); 67 if (numOverlaysPerScreen != NULL) 68 free(numOverlaysPerScreen); 69 } 70 } 71 } 72} 73 74int 75__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo) 76{ 77 int i, screen = vinfo->screen; 78 OverlayInfo *overlayInfo; 79 80 findServerOverlayVisualsInfo(dpy); 81 if (layersRead) { 82 for (i = 0; i < numOverlaysPerScreen[screen]; i++) { 83 overlayInfo = &overlayInfoPerScreen[screen][i]; 84 if (vinfo->visualid == overlayInfo->overlay_visual) { 85 if (overlayInfo->transparent_type == TransparentPixel) { 86 return (int) overlayInfo->value; 87 } else { 88 return -1; 89 } 90 } 91 } 92 } 93 return -1; 94} 95 96XLayerVisualInfo * 97__glutXGetLayerVisualInfo(Display * dpy, long lvinfo_mask, 98 XLayerVisualInfo * lvinfo_template, int *nitems_return) 99{ 100 XVisualInfo *vinfo; 101 XLayerVisualInfo *layerInfo; 102 int numVisuals, count, i, j; 103 104 vinfo = XGetVisualInfo(dpy, lvinfo_mask & VisualAllMask, 105 &lvinfo_template->vinfo, nitems_return); 106 if (vinfo == NULL) 107 return NULL; 108 numVisuals = *nitems_return; 109 findServerOverlayVisualsInfo(dpy); 110 layerInfo = (XLayerVisualInfo *) 111 malloc(numVisuals * sizeof(XLayerVisualInfo)); 112 if (layerInfo == NULL) { 113 XFree(vinfo); 114 return NULL; 115 } 116 count = 0; 117 for (i = 0; i < numVisuals; i++) { 118 XVisualInfo *pVinfo = &vinfo[i]; 119 int screen = pVinfo->screen; 120 OverlayInfo *overlayInfo = NULL; 121 122 overlayInfo = NULL; 123 if (layersRead) { 124 for (j = 0; j < numOverlaysPerScreen[screen]; j++) 125 if (pVinfo->visualid == 126 overlayInfoPerScreen[screen][j].overlay_visual) { 127 overlayInfo = &overlayInfoPerScreen[screen][j]; 128 break; 129 } 130 } 131 if (lvinfo_mask & VisualLayerMask) { 132 if (overlayInfo == NULL) { 133 if (lvinfo_template->layer != 0) 134 continue; 135 } else if (lvinfo_template->layer != overlayInfo->layer) 136 continue; 137 } 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 } 146 if (lvinfo_mask & VisualTransparentValue) { 147 if (overlayInfo == NULL) 148 /* Non-overlay visuals have no sense of 149 TransparentValue. */ 150 continue; 151 else if (lvinfo_template->value != overlayInfo->value) 152 continue; 153 } 154 layerInfo[count].vinfo = *pVinfo; 155 if (overlayInfo == NULL) { 156 layerInfo[count].layer = 0; 157 layerInfo[count].type = None; 158 layerInfo[count].value = 0; /* meaningless */ 159 } else { 160 layerInfo[count].layer = overlayInfo->layer; 161 layerInfo[count].type = overlayInfo->transparent_type; 162 layerInfo[count].value = overlayInfo->value; 163 } 164 count++; 165 } 166 XFree(vinfo); 167 *nitems_return = count; 168 if (count == 0) { 169 XFree(layerInfo); 170 return NULL; 171 } else 172 return layerInfo; 173} 174 175#if 0 /* Unused by GLUT. */ 176Status 177__glutXMatchLayerVisualInfo(Display * dpy, int screen, 178 int depth, int visualClass, int layer, 179 XLayerVisualInfo * lvinfo_return) 180{ 181 XLayerVisualInfo *lvinfo; 182 XLayerVisualInfo lvinfoTemplate; 183 int nitems; 184 185 lvinfoTemplate.vinfo.screen = screen; 186 lvinfoTemplate.vinfo.depth = depth; 187#if defined(__cplusplus) || defined(c_plusplus) 188 lvinfoTemplate.vinfo.c_class = visualClass; 189#else 190 lvinfoTemplate.vinfo.class = visualClass; 191#endif 192 lvinfoTemplate.layer = layer; 193 lvinfo = __glutXGetLayerVisualInfo(dpy, 194 VisualScreenMask | VisualDepthMask | 195 VisualClassMask | VisualLayerMask, 196 &lvinfoTemplate, &nitems); 197 if (lvinfo != NULL && nitems > 0) { 198 *lvinfo_return = *lvinfo; 199 return 1; 200 } else 201 return 0; 202} 203#endif 204