/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 1997 by Ton Roosendaal, Frank van Beek and Joeri Kassenaar. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /* * File: glxhelper.c: * * Description: This file provides a helper function "GLXCreateWindow", * which does all the necessary magic to create an X window * suit able for GL drawing to take place within. See the * definition of GLXCreateWindow() for a description of how * to call it. * * Functions: Uses no SGI Movie Library functions. */ #include #include #include #include #include #include "glxhelper.h" char *typeToName[] = { "color index single buffer", "color index double buffer", "rgb single buffer", "rgb double buffer", }; /* * Little helper function used to build up a GLXconfig array. */ static void setEntry ( GLXconfig* ptr, int b, int m, int a ) { ptr->buffer = b; ptr->mode = m; ptr->arg = a; } /* * GLXCreateWindow( dpy, parent, x, y, w, h, borderWidth, xValueMask, winAttribs, type ) * * Return value is the X window id of the newly created window. * * Arguments are: * dpy The X "Display*" returned by XOpenDisplay * parent The parent of the newly created window, * a typical value for this is * RootWindow(dpy, DefaultScreen(dpy)) * * x,y The location of the window to be created, * y coordinate is measured from the top down. * * w,h size of the new window * * borderWidth the X border size for this window, should probably * be zero. * * xValueMask Specifies which window attributes are defined in * the winAttribs argument. This mask is the bitwise * inclusive OR of the valid attribute mask bits. If * xValueMask is zero, the attributes are ignored and * are not referenced. (See XCreateWindow(3X11)). * * winAttribs Specifies the structure from which the values (as * specified by xValueMask) are to be taken. xValueMask * should have the appropriate bits set to indicate * which attributes have been set in the structure. * * * type the GLXWindowType (see glxhelper.h) desribing the * typer of GL drawing to be done in this window */ Window GLXCreateWindow( Display* dpy, Window parent, int x, int y, int w, int h, int borderWidth, unsigned long xValueMask, XSetWindowAttributes * winAttribs, GLXWindowType type ) { GLXconfig params[50]; GLXconfig* nextConfig; GLXconfig* retConfig; XVisualInfo* vis; XVisualInfo template; XSetWindowAttributes childWinAttribs = *winAttribs; XWindowAttributes parentWinAttribs; int i, nret; Window win; /* * This builds an array in "params" that describes for GLXgetconfig(3G) * the type of GL drawing that will be done. */ nextConfig = params; switch ( type ) { case GLXcolorIndexSingleBuffer: setEntry( nextConfig++, GLX_NORMAL, GLX_RGB, FALSE ); setEntry( nextConfig++, GLX_NORMAL, GLX_DOUBLE, FALSE ); break; case GLXcolorIndexDoubleBuffer: setEntry( nextConfig++, GLX_NORMAL, GLX_RGB, FALSE ); setEntry( nextConfig++, GLX_NORMAL, GLX_DOUBLE, TRUE ); break; case GLXrgbSingleBuffer: setEntry( nextConfig++, GLX_NORMAL, GLX_RGB, TRUE ); setEntry( nextConfig++, GLX_NORMAL, GLX_DOUBLE, FALSE ); break; case GLXrgbDoubleBuffer: setEntry( nextConfig++, GLX_NORMAL, GLX_RGB, TRUE ); setEntry( nextConfig++, GLX_NORMAL, GLX_DOUBLE, TRUE ); break; } /* * Input to GLXgetconfig() is null terminated. */ setEntry( nextConfig, 0, 0, 0 ); /* * Get configuration data for a window based on above parameters. * First we have to find out which screen the parent window is on, * then we can call GXLgetconfig(). */ XGetWindowAttributes( dpy, parent, &parentWinAttribs ); retConfig = GLXgetconfig( dpy, XScreenNumberOfScreen( parentWinAttribs.screen ), params ); if ( retConfig == NULL ) { printf( "Sorry, can't support %s type of windows\n", typeToName[type] ); exit( EXIT_FAILURE ); } /* * The GL sets its own X error handlers, which aren't as informative * when errors happen. Calling XSetErrorHandler(0) here will * reset back to the default Xlib version. */ XSetErrorHandler( NULL ); /* * Scan through config info, pulling info needed to create a window * that supports the rendering mode. */ for ( nextConfig = retConfig; nextConfig->buffer; nextConfig++ ) { unsigned long buffer = nextConfig->buffer; unsigned long mode = nextConfig->mode; unsigned long value = nextConfig->arg; switch ( mode ) { case GLX_COLORMAP: if ( buffer == GLX_NORMAL ) { childWinAttribs.colormap = value; } break; case GLX_VISUAL: if ( buffer == GLX_NORMAL ) { template.visualid = value; template.screen = DefaultScreen( dpy ); vis = XGetVisualInfo( dpy, VisualScreenMask|VisualIDMask, &template, &nret ); } break; } } /* * Create the window. */ win = XCreateWindow( dpy, parent, x, y, w, h, borderWidth, vis->depth, InputOutput, vis->visual, xValueMask, &childWinAttribs ); /* * Rescan configuration info and find window slot that getconfig * provided. Fill it in with the window we just created. */ for ( nextConfig = retConfig; nextConfig->buffer; nextConfig++ ) { if ( ( nextConfig->buffer == GLX_NORMAL ) && ( nextConfig->mode == GLX_WINDOW ) ) { nextConfig->arg = win; break; } } /* * Now "retConfig" contains all the information the GL needs to * configure the window and its own internal state. */ i = GLXlink( dpy, retConfig ); if ( i < 0 ) { printf( "GLXlink returned %d\n", i ); exit( EXIT_FAILURE ); } return win; }