7001582d7d5069e4addf4dc0967d33f8956fd1e1
[freeglut] / src / Common / freeglut_state.c
1 /*\r
2  * freeglut_state.c\r
3  *\r
4  * Freeglut state query methods.\r
5  *\r
6  * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.\r
7  * Written by Pawel W. Olszta, <olszta@sourceforge.net>\r
8  * Creation date: Thu Dec 16 1999\r
9  *\r
10  * Permission is hereby granted, free of charge, to any person obtaining a\r
11  * copy of this software and associated documentation files (the "Software"),\r
12  * to deal in the Software without restriction, including without limitation\r
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
14  * and/or sell copies of the Software, and to permit persons to whom the\r
15  * Software is furnished to do so, subject to the following conditions:\r
16  *\r
17  * The above copyright notice and this permission notice shall be included\r
18  * in all copies or substantial portions of the Software.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
23  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
24  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
26  */\r
27 \r
28 #include <GL/freeglut.h>\r
29 #include "freeglut_internal.h"\r
30 \r
31 /*\r
32  * TODO BEFORE THE STABLE RELEASE:\r
33  *\r
34  *  glutGet()               -- X11 tests passed, but check if all enums\r
35  *                             handled (what about Win32?)\r
36  *  glutDeviceGet()         -- X11 tests passed, but check if all enums\r
37  *                             handled (what about Win32?)\r
38  *  glutGetModifiers()      -- OK, but could also remove the limitation\r
39  *  glutLayerGet()          -- what about GLUT_NORMAL_DAMAGED?\r
40  *\r
41  * The fail-on-call policy will help adding the most needed things imho.\r
42  */\r
43 \r
44 extern int fgPlatformGlutGet ( GLenum eWhat );\r
45 extern int fgPlatformGlutDeviceGet ( GLenum eWhat );\r
46 extern int fgPlatformGlutLayerGet ( GLenum eWhat );\r
47 extern int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size);\r
48 \r
49 \r
50 /* -- LOCAL DEFINITIONS ---------------------------------------------------- */\r
51 \r
52 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */\r
53 \r
54 \r
55 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */\r
56 \r
57 /*\r
58  * General settings assignment method\r
59  */\r
60 void FGAPIENTRY glutSetOption( GLenum eWhat, int value )\r
61 {\r
62     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetOption" );\r
63 \r
64     /*\r
65      * XXX In chronological code add order.  (WHY in that order?)\r
66      */\r
67     switch( eWhat )\r
68     {\r
69     case GLUT_INIT_WINDOW_X:\r
70         fgState.Position.X = (GLint)value;\r
71         break;\r
72 \r
73     case GLUT_INIT_WINDOW_Y:\r
74         fgState.Position.Y = (GLint)value;\r
75         break;\r
76 \r
77     case GLUT_INIT_WINDOW_WIDTH:\r
78         fgState.Size.X = (GLint)value;\r
79         break;\r
80 \r
81     case GLUT_INIT_WINDOW_HEIGHT:\r
82         fgState.Size.Y = (GLint)value;\r
83         break;\r
84 \r
85     case GLUT_INIT_DISPLAY_MODE:\r
86         fgState.DisplayMode = (unsigned int)value;\r
87         break;\r
88 \r
89     case GLUT_ACTION_ON_WINDOW_CLOSE:\r
90         fgState.ActionOnWindowClose = value;\r
91         break;\r
92 \r
93     case GLUT_RENDERING_CONTEXT:\r
94         fgState.UseCurrentContext =\r
95             ( value == GLUT_USE_CURRENT_CONTEXT ) ? GL_TRUE : GL_FALSE;\r
96         break;\r
97 \r
98     case GLUT_DIRECT_RENDERING:\r
99         fgState.DirectContext = value;\r
100         break;\r
101 \r
102     case GLUT_WINDOW_CURSOR:\r
103         if( fgStructure.CurrentWindow != NULL )\r
104             fgStructure.CurrentWindow->State.Cursor = value;\r
105         break;\r
106 \r
107     case GLUT_AUX:\r
108       fgState.AuxiliaryBufferNumber = value;\r
109       break;\r
110 \r
111     case GLUT_MULTISAMPLE:\r
112       fgState.SampleNumber = value;\r
113       break;\r
114 \r
115     default:\r
116         fgWarning( "glutSetOption(): missing enum handle %d", eWhat );\r
117         break;\r
118     }\r
119 }\r
120 \r
121 /*\r
122  * General settings query method\r
123  */\r
124 int FGAPIENTRY glutGet( GLenum eWhat )\r
125 {\r
126     switch (eWhat)\r
127     {\r
128     case GLUT_INIT_STATE:\r
129         return fgState.Initialised;\r
130 \r
131     case GLUT_ELAPSED_TIME:\r
132         return fgElapsedTime();\r
133     }\r
134 \r
135     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGet" );\r
136 \r
137     /* XXX In chronological code add order.  (WHY in that order?) */\r
138     switch( eWhat )\r
139     {\r
140     /* Following values are stored in fgState and fgDisplay global structures */\r
141     case GLUT_SCREEN_WIDTH:         return fgDisplay.ScreenWidth   ;\r
142     case GLUT_SCREEN_HEIGHT:        return fgDisplay.ScreenHeight  ;\r
143     case GLUT_SCREEN_WIDTH_MM:      return fgDisplay.ScreenWidthMM ;\r
144     case GLUT_SCREEN_HEIGHT_MM:     return fgDisplay.ScreenHeightMM;\r
145     case GLUT_INIT_WINDOW_X:        return fgState.Position.Use ?\r
146                                            fgState.Position.X : -1 ;\r
147     case GLUT_INIT_WINDOW_Y:        return fgState.Position.Use ?\r
148                                            fgState.Position.Y : -1 ;\r
149     case GLUT_INIT_WINDOW_WIDTH:    return fgState.Size.Use ?\r
150                                            fgState.Size.X : -1     ;\r
151     case GLUT_INIT_WINDOW_HEIGHT:   return fgState.Size.Use ?\r
152                                            fgState.Size.Y : -1     ;\r
153     case GLUT_INIT_DISPLAY_MODE:    return fgState.DisplayMode     ;\r
154     case GLUT_INIT_MAJOR_VERSION:   return fgState.MajorVersion    ;\r
155     case GLUT_INIT_MINOR_VERSION:   return fgState.MinorVersion    ;\r
156     case GLUT_INIT_FLAGS:           return fgState.ContextFlags    ;\r
157     case GLUT_INIT_PROFILE:         return fgState.ContextProfile  ;\r
158 \r
159     /* The window structure queries */\r
160     case GLUT_WINDOW_PARENT:\r
161         if( fgStructure.CurrentWindow         == NULL ) return 0;\r
162         if( fgStructure.CurrentWindow->Parent == NULL ) return 0;\r
163         return fgStructure.CurrentWindow->Parent->ID;\r
164 \r
165     case GLUT_WINDOW_NUM_CHILDREN:\r
166         if( fgStructure.CurrentWindow == NULL )\r
167             return 0;\r
168         return fgListLength( &fgStructure.CurrentWindow->Children );\r
169 \r
170     case GLUT_WINDOW_CURSOR:\r
171         if( fgStructure.CurrentWindow == NULL )\r
172             return 0;\r
173         return fgStructure.CurrentWindow->State.Cursor;\r
174 \r
175     case GLUT_MENU_NUM_ITEMS:\r
176         if( fgStructure.CurrentMenu == NULL )\r
177             return 0;\r
178         return fgListLength( &fgStructure.CurrentMenu->Entries );\r
179 \r
180     case GLUT_ACTION_ON_WINDOW_CLOSE:\r
181         return fgState.ActionOnWindowClose;\r
182 \r
183     case GLUT_VERSION :\r
184         return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH;\r
185 \r
186     case GLUT_RENDERING_CONTEXT:\r
187         return fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT\r
188                                          : GLUT_CREATE_NEW_CONTEXT;\r
189 \r
190     case GLUT_DIRECT_RENDERING:\r
191         return fgState.DirectContext;\r
192 \r
193     case GLUT_FULL_SCREEN:\r
194         return fgStructure.CurrentWindow->State.IsFullscreen;\r
195 \r
196     case GLUT_AUX:\r
197       return fgState.AuxiliaryBufferNumber;\r
198 \r
199     case GLUT_MULTISAMPLE:\r
200       return fgState.SampleNumber;\r
201 \r
202     default:\r
203         return fgPlatformGlutGet ( eWhat );\r
204         break;\r
205     }\r
206     return -1;\r
207 }\r
208 \r
209 /*\r
210  * Returns various device information.\r
211  */\r
212 int FGAPIENTRY glutDeviceGet( GLenum eWhat )\r
213 {\r
214     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDeviceGet" );\r
215 \r
216     /* XXX WARNING: we are mostly lying in this function. */\r
217     switch( eWhat )\r
218     {\r
219     case GLUT_HAS_JOYSTICK:\r
220         return fgJoystickDetect ();\r
221 \r
222     case GLUT_OWNS_JOYSTICK:\r
223         return fgState.JoysticksInitialised;\r
224 \r
225     case GLUT_JOYSTICK_POLL_RATE:\r
226         return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.JoystickPollRate : 0;\r
227 \r
228     /* XXX The following two are only for Joystick 0 but this is an improvement */\r
229     case GLUT_JOYSTICK_BUTTONS:\r
230         return glutJoystickGetNumButtons ( 0 );\r
231 \r
232     case GLUT_JOYSTICK_AXES:\r
233         return glutJoystickGetNumAxes ( 0 );\r
234 \r
235     case GLUT_HAS_DIAL_AND_BUTTON_BOX:\r
236         return fgInputDeviceDetect ();\r
237 \r
238     case GLUT_NUM_DIALS:\r
239         if ( fgState.InputDevsInitialised ) return 8;\r
240         return 0;\r
241  \r
242     case GLUT_NUM_BUTTON_BOX_BUTTONS:\r
243         return 0;\r
244 \r
245     case GLUT_HAS_SPACEBALL:\r
246         return fgHasSpaceball();\r
247 \r
248     case GLUT_HAS_TABLET:\r
249         return 0;\r
250 \r
251     case GLUT_NUM_SPACEBALL_BUTTONS:\r
252         return fgSpaceballNumButtons();\r
253 \r
254     case GLUT_NUM_TABLET_BUTTONS:\r
255         return 0;\r
256 \r
257     case GLUT_DEVICE_IGNORE_KEY_REPEAT:\r
258         return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.IgnoreKeyRepeat : 0;\r
259 \r
260     case GLUT_DEVICE_KEY_REPEAT:\r
261         return fgState.KeyRepeat;\r
262 \r
263     default:\r
264                 return fgPlatformGlutDeviceGet ( eWhat );\r
265     }\r
266 \r
267     /* And now -- the failure. */\r
268     return -1;\r
269 }\r
270 \r
271 /*\r
272  * This should return the current state of ALT, SHIFT and CTRL keys.\r
273  */\r
274 int FGAPIENTRY glutGetModifiers( void )\r
275 {\r
276     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetModifiers" );\r
277     if( fgState.Modifiers == INVALID_MODIFIERS )\r
278     {\r
279         fgWarning( "glutGetModifiers() called outside an input callback" );\r
280         return 0;\r
281     }\r
282 \r
283     return fgState.Modifiers;\r
284 }\r
285 \r
286 /*\r
287  * Return the state of the GLUT API overlay subsystem. A misery ;-)\r
288  */\r
289 int FGAPIENTRY glutLayerGet( GLenum eWhat )\r
290 {\r
291     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutLayerGet" );\r
292 \r
293     /*\r
294      * This is easy as layers are not implemented ;-)\r
295      *\r
296      * XXX Can we merge the UNIX/X11 and WIN32 sections?  Or\r
297      * XXX is overlay support planned?\r
298      */\r
299     switch( eWhat )\r
300     {\r
301 \r
302     default:\r
303         return fgPlatformGlutLayerGet( eWhat );\r
304     }\r
305 \r
306     /* And fail. That's good. Programs do love failing. */\r
307     return -1;\r
308 }\r
309 \r
310 int * FGAPIENTRY glutGetModeValues(GLenum eWhat, int *size)\r
311 {\r
312   int *array;\r
313 \r
314   FREEGLUT_EXIT_IF_NOT_INITIALISED("glutGetModeValues");\r
315 \r
316   *size = 0;\r
317   array = fgPlatformGlutGetModeValues ( eWhat, size );\r
318 \r
319   return array;\r
320 }\r
321 \r
322 /*** END OF FILE ***/\r