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 | #include "x11/fg_window_x11_glx.h" |
31 | |
32 | /* |
33 | * Queries the GL context about some attributes |
34 | */ |
35 | int fgPlatformGetConfig( int attribute ) |
36 | { |
37 | int returnValue = 0; |
38 | int result __fg_unused; /* Not checked */ |
39 | |
40 | if( fgStructure.CurrentWindow ) |
41 | result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display, |
42 | fgStructure.CurrentWindow->Window.pContext.FBConfig, |
43 | attribute, |
44 | &returnValue ); |
45 | |
46 | return returnValue; |
47 | } |
48 | |
49 | int fghPlatformGlutGetGLX ( GLenum eWhat ) |
50 | { |
51 | switch( eWhat ) |
52 | { |
53 | /* |
54 | * The window/context specific queries are handled mostly by |
55 | * fgPlatformGetConfig(). |
56 | */ |
57 | case GLUT_WINDOW_NUM_SAMPLES: |
58 | { |
59 | int nsamples = 0; |
60 | #ifdef GLX_VERSION_1_3 |
61 | glGetIntegerv(GL_SAMPLES, &nsamples); |
62 | #endif |
63 | return nsamples; |
64 | } |
65 | |
66 | /* |
67 | * The rest of GLX queries under X are general enough to use a macro to |
68 | * check them |
69 | */ |
70 | # define GLX_QUERY(a,b) case a: return fgPlatformGetConfig( b ); |
71 | |
72 | GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA ); |
73 | GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER ); |
74 | GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE ); |
75 | GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE ); |
76 | GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE ); |
77 | GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE ); |
78 | GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE ); |
79 | GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE ); |
80 | GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE ); |
81 | GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE ); |
82 | GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE ); |
83 | GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE ); |
84 | GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE ); |
85 | GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO ); |
86 | |
87 | # undef GLX_QUERY |
88 | |
89 | /* I do not know yet if there will be a fgChooseVisual() function for Win32 */ |
90 | case GLUT_DISPLAY_MODE_POSSIBLE: |
91 | { |
92 | /* We should not have to call fghChooseConfig again here. */ |
93 | GLXFBConfig config; |
94 | return fghChooseConfig(&config); |
95 | } |
96 | |
97 | /* This is system-dependent */ |
98 | case GLUT_WINDOW_FORMAT_ID: |
99 | if( fgStructure.CurrentWindow == NULL ) |
100 | return 0; |
101 | |
102 | return fgPlatformGetConfig( GLX_VISUAL_ID ); |
103 | |
104 | default: |
105 | fgWarning( "glutGet(): missing enum handle %d" , eWhat ); |
106 | break; |
107 | } |
108 | |
109 | return -1; |
110 | } |
111 | |
112 | int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size) |
113 | { |
114 | int *array; |
115 | |
116 | int attributes[9]; |
117 | GLXFBConfig * fbconfigArray; /* Array of FBConfigs */ |
118 | int fbconfigArraySize; /* Number of FBConfigs in the array */ |
119 | int attribute_name = 0; |
120 | |
121 | array = NULL; |
122 | *size = 0; |
123 | |
124 | switch (eWhat) |
125 | { |
126 | case GLUT_AUX: |
127 | case GLUT_MULTISAMPLE: |
128 | |
129 | attributes[0] = GLX_BUFFER_SIZE; |
130 | attributes[1] = GLX_DONT_CARE; |
131 | |
132 | switch (eWhat) |
133 | { |
134 | case GLUT_AUX: |
135 | /* |
136 | FBConfigs are now sorted by increasing number of auxiliary |
137 | buffers. We want at least one buffer. |
138 | */ |
139 | attributes[2] = GLX_AUX_BUFFERS; |
140 | attributes[3] = 1; |
141 | attributes[4] = None; |
142 | |
143 | attribute_name = GLX_AUX_BUFFERS; |
144 | |
145 | break; |
146 | |
147 | |
148 | case GLUT_MULTISAMPLE: |
149 | attributes[2] = GLX_AUX_BUFFERS; |
150 | attributes[3] = GLX_DONT_CARE; |
151 | attributes[4] = GLX_SAMPLE_BUFFERS; |
152 | attributes[5] = 1; |
153 | /* |
154 | FBConfigs are now sorted by increasing number of samples per |
155 | pixel. We want at least one sample. |
156 | */ |
157 | attributes[6] = GLX_SAMPLES; |
158 | attributes[7] = 1; |
159 | attributes[8] = None; |
160 | |
161 | attribute_name = GLX_SAMPLES; |
162 | |
163 | break; |
164 | } |
165 | |
166 | fbconfigArray = glXChooseFBConfig(fgDisplay.pDisplay.Display, |
167 | fgDisplay.pDisplay.Screen, |
168 | attributes, |
169 | &fbconfigArraySize); |
170 | |
171 | if (fbconfigArray != NULL) |
172 | { |
173 | int * temp_array; |
174 | int result __fg_unused; /* Returned by glXGetFBConfigAttrib. Not checked. */ |
175 | int previous_value; |
176 | int i; |
177 | |
178 | temp_array = malloc(sizeof(int) * fbconfigArraySize); |
179 | previous_value = 0; |
180 | |
181 | for (i = 0; i < fbconfigArraySize; i++) |
182 | { |
183 | int value; |
184 | |
185 | result = glXGetFBConfigAttrib(fgDisplay.pDisplay.Display, |
186 | fbconfigArray[i], |
187 | attribute_name, |
188 | &value); |
189 | if (value > previous_value) |
190 | { |
191 | temp_array[*size] = value; |
192 | previous_value = value; |
193 | (*size)++; |
194 | } |
195 | } |
196 | |
197 | array = malloc(sizeof(int) * (*size)); |
198 | for (i = 0; i < *size; i++) |
199 | { |
200 | array[i] = temp_array[i]; |
201 | } |
202 | |
203 | free(temp_array); |
204 | XFree(fbconfigArray); |
205 | } |
206 | |
207 | break; |
208 | |
209 | default: |
210 | break; |
211 | } |
212 | |
213 | return array; |
214 | } |
215 | |