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