4 * Window management methods for X11 with GLX
6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8 * Copied for Platform code by Evan Felix <karcaw at gmail.com>
9 * Creation date: Thur Feb 2 2012
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #define FREEGLUT_BUILDING_LIB
30 #include <GL/freeglut.h>
31 #include "fg_internal.h"
33 /* pushing attribute/value pairs into an array */
34 #define ATTRIB(a) attributes[where++]=(a)
35 #define ATTRIB_VAL(a,v) {ATTRIB(a); ATTRIB(v);}
38 * Chooses a visual basing on the current display mode settings
41 int fghChooseConfig(GLXFBConfig* fbconfig)
43 GLboolean wantIndexedMode = GL_FALSE;
44 int attributes[ 100 ];
45 int where = 0, numAuxBuffers;
47 /* First we have to process the display mode settings... */
48 if( fgState.DisplayMode & GLUT_INDEX ) {
49 ATTRIB_VAL( GLX_BUFFER_SIZE, 8 );
50 /* Buffer size is selected later. */
52 ATTRIB_VAL( GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT );
53 wantIndexedMode = GL_TRUE;
55 ATTRIB_VAL( GLX_RED_SIZE, 1 );
56 ATTRIB_VAL( GLX_GREEN_SIZE, 1 );
57 ATTRIB_VAL( GLX_BLUE_SIZE, 1 );
58 if( fgState.DisplayMode & GLUT_ALPHA ) {
59 ATTRIB_VAL( GLX_ALPHA_SIZE, 1 );
63 if( fgState.DisplayMode & GLUT_DOUBLE ) {
64 ATTRIB_VAL( GLX_DOUBLEBUFFER, True );
67 if( fgState.DisplayMode & GLUT_STEREO ) {
68 ATTRIB_VAL( GLX_STEREO, True );
71 if( fgState.DisplayMode & GLUT_DEPTH ) {
72 ATTRIB_VAL( GLX_DEPTH_SIZE, 1 );
75 if( fgState.DisplayMode & GLUT_STENCIL ) {
76 ATTRIB_VAL( GLX_STENCIL_SIZE, 1 );
79 if( fgState.DisplayMode & GLUT_ACCUM ) {
80 ATTRIB_VAL( GLX_ACCUM_RED_SIZE, 1 );
81 ATTRIB_VAL( GLX_ACCUM_GREEN_SIZE, 1 );
82 ATTRIB_VAL( GLX_ACCUM_BLUE_SIZE, 1 );
83 if( fgState.DisplayMode & GLUT_ALPHA ) {
84 ATTRIB_VAL( GLX_ACCUM_ALPHA_SIZE, 1 );
88 numAuxBuffers = fghNumberOfAuxBuffersRequested();
89 if ( numAuxBuffers > 0 ) {
90 ATTRIB_VAL( GLX_AUX_BUFFERS, numAuxBuffers );
93 if( fgState.DisplayMode & GLUT_SRGB ) {
94 ATTRIB_VAL( GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True );
97 if (fgState.DisplayMode & GLUT_MULTISAMPLE) {
98 ATTRIB_VAL(GLX_SAMPLE_BUFFERS, 1);
99 ATTRIB_VAL(GLX_SAMPLES, fgState.SampleNumber);
102 /* Push a terminator at the end of the list */
106 GLXFBConfig * fbconfigArray; /* Array of FBConfigs */
107 int fbconfigArraySize; /* Number of FBConfigs in the array */
110 /* Get all FBConfigs that match "attributes". */
111 fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
112 fgDisplay.pDisplay.Screen,
114 &fbconfigArraySize );
116 if (fbconfigArray != NULL)
118 int result __fg_unused; /* Returned by glXGetFBConfigAttrib, not checked. */
121 if( wantIndexedMode )
124 * In index mode, we want the largest buffer size, i.e. visual
125 * depth. Here, FBConfigs are sorted by increasing buffer size
126 * first, so FBConfigs with the largest size come last.
129 int bufferSizeMin, bufferSizeMax;
131 /* Get bufferSizeMin. */
133 glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
137 /* Get bufferSizeMax. */
139 glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
140 fbconfigArray[fbconfigArraySize - 1],
144 if (bufferSizeMax > bufferSizeMin)
147 * Free and reallocate fbconfigArray, keeping only FBConfigs
148 * with the largest buffer size.
150 XFree(fbconfigArray);
152 /* Add buffer size token at the end of the list. */
154 ATTRIB_VAL( GLX_BUFFER_SIZE, bufferSizeMax );
157 fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
158 fgDisplay.pDisplay.Screen,
160 &fbconfigArraySize );
164 *fbconfig = fbconfigArray[0];
171 XFree(fbconfigArray);
177 static void fghFillContextAttributes( int *attributes ) {
178 int where = 0, contextFlags, contextProfile;
180 ATTRIB_VAL( GLX_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion );
181 ATTRIB_VAL( GLX_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion );
184 fghMapBit( fgState.ContextFlags, GLUT_DEBUG, GLX_CONTEXT_DEBUG_BIT_ARB ) |
185 fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB );
186 if ( contextFlags != 0 ) {
187 ATTRIB_VAL( GLX_CONTEXT_FLAGS_ARB, contextFlags );
191 fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB ) |
192 fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB );
193 if ( contextProfile != 0 ) {
194 ATTRIB_VAL( GLX_CONTEXT_PROFILE_MASK_ARB, contextProfile );
200 typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config,
201 GLXContext share_list, Bool direct,
202 const int *attrib_list);
204 GLXContext fghCreateNewContext( SFG_Window* window )
206 /* for color model calculation */
207 int menu = ( window->IsMenu && !fgStructure.MenuContext );
208 int index_mode = ( fgState.DisplayMode & GLUT_INDEX );
210 /* "classic" context creation */
211 Display *dpy = fgDisplay.pDisplay.Display;
212 GLXFBConfig config = window->Window.pContext.FBConfig;
213 int render_type = ( !menu && index_mode ) ? GLX_COLOR_INDEX_TYPE : GLX_RGBA_TYPE;
214 GLXContext share_list = NULL;
215 Bool direct = ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT );
218 /* new context creation */
220 CreateContextAttribsProc createContextAttribs = (CreateContextAttribsProc) fgPlatformGetProcAddress( "glXCreateContextAttribsARB" );
222 /* glXCreateContextAttribsARB not found, yet the user has requested the new context creation */
223 if ( !createContextAttribs && !fghIsLegacyContextRequested() ) {
224 fgWarning( "OpenGL >2.1 context requested but glXCreateContextAttribsARB is not available! Falling back to legacy context creation" );
225 fgState.MajorVersion = 2;
226 fgState.MinorVersion = 1;
229 /* If nothing fancy has been required, simply use the old context creation GLX API entry */
230 if ( fghIsLegacyContextRequested() || !createContextAttribs )
232 context = glXCreateNewContext( dpy, config, render_type, share_list, direct );
233 if ( context == NULL ) {
234 fghContextCreationError();
239 /* color index mode is not available anymore with OpenGL 3.0 */
240 if ( render_type == GLX_COLOR_INDEX_TYPE ) {
241 fgWarning( "color index mode is deprecated, using RGBA mode" );
244 fghFillContextAttributes( attributes );
246 context = createContextAttribs( dpy, config, share_list, direct, attributes );
247 if ( context == NULL ) {
248 fghContextCreationError();
253 void fgPlatformSetWindow ( SFG_Window *window )
257 glXMakeContextCurrent(
258 fgDisplay.pDisplay.Display,
259 window->Window.Handle,
260 window->Window.Handle,
261 window->Window.Context