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; /* 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 if ( !fghIsLegacyContextVersionRequested() ) {
181 ATTRIB_VAL( GLX_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion );
182 ATTRIB_VAL( GLX_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion );
186 fghMapBit( fgState.ContextFlags, GLUT_DEBUG, GLX_CONTEXT_DEBUG_BIT_ARB ) |
187 fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB );
188 if ( contextFlags != 0 ) {
189 ATTRIB_VAL( GLX_CONTEXT_FLAGS_ARB, contextFlags );
193 fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB ) |
194 fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB );
195 if ( contextProfile != 0 ) {
196 ATTRIB_VAL( GLX_CONTEXT_PROFILE_MASK_ARB, contextProfile );
202 typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config,
203 GLXContext share_list, Bool direct,
204 const int *attrib_list);
206 GLXContext fghCreateNewContext( SFG_Window* window )
208 /* for color model calculation */
209 int menu = ( window->IsMenu && !fgStructure.MenuContext );
210 int index_mode = ( fgState.DisplayMode & GLUT_INDEX );
212 /* "classic" context creation */
213 Display *dpy = fgDisplay.pDisplay.Display;
214 GLXFBConfig config = window->Window.pContext.FBConfig;
215 int render_type = ( !menu && index_mode ) ? GLX_COLOR_INDEX_TYPE : GLX_RGBA_TYPE;
216 GLXContext share_list = NULL;
217 Bool direct = ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT );
220 /* new context creation */
222 CreateContextAttribsProc createContextAttribs = (CreateContextAttribsProc) fgPlatformGetProcAddress( "glXCreateContextAttribsARB" );
224 /* glXCreateContextAttribsARB not found, yet the user has requested the new context creation */
225 if ( !createContextAttribs && !fghIsLegacyContextRequested() ) {
226 fgWarning( "OpenGL >2.1 context requested but glXCreateContextAttribsARB is not available! Falling back to legacy context creation" );
227 fgState.MajorVersion = 2;
228 fgState.MinorVersion = 1;
231 /* If nothing fancy has been required, simply use the old context creation GLX API entry */
232 if ( fghIsLegacyContextRequested() || !createContextAttribs )
234 context = glXCreateNewContext( dpy, config, render_type, share_list, direct );
235 if ( context == NULL ) {
236 fghContextCreationError();
241 /* color index mode is not available anymore with OpenGL 3.0 */
242 if ( render_type == GLX_COLOR_INDEX_TYPE ) {
243 fgWarning( "color index mode is deprecated, using RGBA mode" );
246 fghFillContextAttributes( attributes );
248 context = createContextAttribs( dpy, config, share_list, direct, attributes );
249 if ( context == NULL ) {
250 fghContextCreationError();
255 void fgPlatformSetWindow ( SFG_Window *window )
259 glXMakeContextCurrent(
260 fgDisplay.pDisplay.Display,
261 window->Window.Handle,
262 window->Window.Handle,
263 window->Window.Context