EGL: implement fgPlatformGetProcAddress
[freeglut] / src / x11 / fg_state_x11_glx.c
1 /*
2  * fg_state_x11_glx.c
3  *
4  * X11-specific freeglut state query methods.
5  *
6  * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
7  * Written by John F. Fay, <fayjf@sourceforge.net>
8  * Creation date: Sat Feb 4 2012
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  */
27
28 #include <GL/freeglut.h>
29 #include "fg_internal.h"
30
31 /*
32  * Queries the GL context about some attributes
33  */
34 int fgPlatformGetConfig( int attribute )
35 {
36   int returnValue = 0;
37   int result;  /*  Not checked  */
38
39   if( fgStructure.CurrentWindow )
40       result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
41                                      fgStructure.CurrentWindow->Window.pContext.FBConfig,
42                                      attribute,
43                                      &returnValue );
44
45   return returnValue;
46 }
47
48 int fghPlatformGlutGetGLX ( GLenum eWhat )
49 {
50     switch( eWhat )
51     {
52     /*
53      * The window/context specific queries are handled mostly by
54      * fgPlatformGetConfig().
55      */
56     case GLUT_WINDOW_NUM_SAMPLES:
57       {
58         int nsamples = 0;
59 #ifdef GLX_VERSION_1_3
60         glGetIntegerv(GL_SAMPLES, &nsamples);
61 #endif
62         return nsamples;
63       }
64
65     /*
66      * The rest of GLX queries under X are general enough to use a macro to
67      * check them
68      */
69 #   define GLX_QUERY(a,b) case a: return fgPlatformGetConfig( b );
70
71     GLX_QUERY( GLUT_WINDOW_RGBA,                GLX_RGBA                );
72     GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER,        GLX_DOUBLEBUFFER        );
73     GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE,         GLX_BUFFER_SIZE         );
74     GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE,        GLX_STENCIL_SIZE        );
75     GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE,          GLX_DEPTH_SIZE          );
76     GLX_QUERY( GLUT_WINDOW_RED_SIZE,            GLX_RED_SIZE            );
77     GLX_QUERY( GLUT_WINDOW_GREEN_SIZE,          GLX_GREEN_SIZE          );
78     GLX_QUERY( GLUT_WINDOW_BLUE_SIZE,           GLX_BLUE_SIZE           );
79     GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE,          GLX_ALPHA_SIZE          );
80     GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE,      GLX_ACCUM_RED_SIZE      );
81     GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE,    GLX_ACCUM_GREEN_SIZE    );
82     GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE,     GLX_ACCUM_BLUE_SIZE     );
83     GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE,    GLX_ACCUM_ALPHA_SIZE    );
84     GLX_QUERY( GLUT_WINDOW_STEREO,              GLX_STEREO              );
85
86 #   undef GLX_QUERY
87
88     /* I do not know yet if there will be a fgChooseVisual() function for Win32 */
89     case GLUT_DISPLAY_MODE_POSSIBLE:
90     {
91         /*  We should not have to call fghChooseConfig again here.  */
92         GLXFBConfig config;
93         return fghChooseConfig(&config);
94     }
95
96     /* This is system-dependant */
97     case GLUT_WINDOW_FORMAT_ID:
98         if( fgStructure.CurrentWindow == NULL )
99             return 0;
100
101         return fgPlatformGetConfig( GLX_VISUAL_ID );
102
103     default:
104         fgWarning( "glutGet(): missing enum handle %d", eWhat );
105         break;
106     }
107
108         return -1;
109 }
110
111 int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
112 {
113   int *array;
114
115   int attributes[9];
116   GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
117   int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
118   int attribute_name = 0;
119
120   array = NULL;
121   *size = 0;
122
123   switch (eWhat)
124     {
125     case GLUT_AUX:
126     case GLUT_MULTISAMPLE:
127
128       attributes[0] = GLX_BUFFER_SIZE;
129       attributes[1] = GLX_DONT_CARE;
130
131       switch (eWhat)
132         {
133         case GLUT_AUX:
134           /*
135             FBConfigs are now sorted by increasing number of auxiliary
136             buffers.  We want at least one buffer.
137           */
138           attributes[2] = GLX_AUX_BUFFERS;
139           attributes[3] = 1;
140           attributes[4] = None;
141
142           attribute_name = GLX_AUX_BUFFERS;
143
144           break;
145
146
147         case GLUT_MULTISAMPLE:
148           attributes[2] = GLX_AUX_BUFFERS;
149           attributes[3] = GLX_DONT_CARE;
150           attributes[4] = GLX_SAMPLE_BUFFERS;
151           attributes[5] = 1;
152           /*
153             FBConfigs are now sorted by increasing number of samples per
154             pixel.  We want at least one sample.
155           */
156           attributes[6] = GLX_SAMPLES;
157           attributes[7] = 1;
158           attributes[8] = None;
159
160           attribute_name = GLX_SAMPLES;
161
162           break;
163         }
164
165       fbconfigArray = glXChooseFBConfig(fgDisplay.pDisplay.Display,
166                                         fgDisplay.pDisplay.Screen,
167                                         attributes,
168                                         &fbconfigArraySize);
169
170       if (fbconfigArray != NULL)
171         {
172           int * temp_array;
173           int result;   /*  Returned by glXGetFBConfigAttrib. Not checked.  */
174           int previous_value;
175           int i;
176
177           temp_array = malloc(sizeof(int) * fbconfigArraySize);
178           previous_value = 0;
179
180           for (i = 0; i < fbconfigArraySize; i++)
181             {
182               int value;
183
184               result = glXGetFBConfigAttrib(fgDisplay.pDisplay.Display,
185                                             fbconfigArray[i],
186                                             attribute_name,
187                                             &value);
188               if (value > previous_value)
189                 {
190                   temp_array[*size] = value;
191                   previous_value = value;
192                   (*size)++;
193                 }
194             }
195
196           array = malloc(sizeof(int) * (*size));
197           for (i = 0; i < *size; i++)
198             {
199               array[i] = temp_array[i];
200             }
201
202           free(temp_array);
203           XFree(fbconfigArray);
204         }
205
206       break;
207
208     default:
209       break;
210     }
211
212   return array;
213 }