Added a new state variable "Initalized".
[freeglut] / src / freeglut_state.c
1 /*
2  * freeglut_state.c
3  *
4  * Freeglut state query methods.
5  *
6  * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7  * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8  * Creation date: Thu Dec 16 1999
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 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "../include/GL/freeglut.h"
33 #include "freeglut_internal.h"
34
35 /*
36  * TODO BEFORE THE STABLE RELEASE:
37  *
38  *  glutGet()               -- X11 tests passed, but check if all enums
39  *                             handled (what about Win32?)
40  *  glutDeviceGet()         -- X11 tests passed, but check if all enums
41  *                             handled (what about Win32?)
42  *  glutGetModifiers()      -- OK, but could also remove the limitation
43  *  glutLayerGet()          -- what about GLUT_NORMAL_DAMAGED?
44  *
45  * The fail-on-call policy will help adding the most needed things imho.
46  */
47
48 /* -- LOCAL DEFINITIONS ---------------------------------------------------- */
49
50 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
51
52 #if TARGET_HOST_UNIX_X11
53 /*
54  * Queries the GL context about some attributes
55  */
56 static int fghGetConfig( int attribute )
57 {
58   int returnValue = 0;
59
60   if( fgStructure.Window )
61       glXGetConfig( fgDisplay.Display, fgStructure.Window->Window.VisualInfo,
62                     attribute, &returnValue );
63
64   return returnValue;
65 }
66 #endif
67
68 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
69
70 /*
71  * General settings assignment method
72  */
73 void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
74 {
75   freeglut_assert_ready;
76
77   /*
78    * XXX In chronological code add order.  (WHY in that order?)
79    */
80   switch( eWhat )
81   {
82   case GLUT_INIT_WINDOW_X:
83       fgState.Position.X = (GLint)value;
84       break;
85
86   case GLUT_INIT_WINDOW_Y:
87       fgState.Position.Y = (GLint)value;
88       break;
89
90   case GLUT_INIT_WINDOW_WIDTH:
91       fgState.Size.X = (GLint)value;
92       break;
93
94   case GLUT_INIT_WINDOW_HEIGHT:
95       fgState.Size.Y = (GLint)value;
96       break;
97
98   case GLUT_INIT_DISPLAY_MODE:
99       fgState.DisplayMode = (unsigned int)value;
100       break;
101
102   case GLUT_ACTION_ON_WINDOW_CLOSE:
103       fgState.ActionOnWindowClose = value;
104       break;
105
106   case GLUT_RENDERING_CONTEXT:
107       fgState.UseCurrentContext =
108           ( value == GLUT_USE_CURRENT_CONTEXT ) ? TRUE : FALSE;
109       break;
110
111   case GLUT_WINDOW_CURSOR:
112       if( fgStructure.Window != NULL )
113           fgStructure.Window->State.Cursor = value;
114       break;
115
116   default:
117       fgWarning( "glutSetOption(): missing enum handle %i\n", eWhat );
118       break;
119   }
120 }
121
122 /*
123  * General settings query method
124  */
125 int FGAPIENTRY glutGet( GLenum eWhat )
126 {
127     int returnValue ;
128     GLboolean boolValue ;
129
130     switch (eWhat)
131     {
132     case GLUT_INIT_STATE:
133         return ( fgState.Initalized ) ;
134
135     case GLUT_ELAPSED_TIME:
136         return( fgElapsedTime() );
137     }
138
139     freeglut_assert_ready;
140
141     /*
142      * XXX In chronological code add order.  (WHY in that order?)
143      */
144     switch( eWhat )
145     {
146     /*
147      * Following values are stored in fgState and fgDisplay global structures
148      */
149     case GLUT_SCREEN_WIDTH:         return( fgDisplay.ScreenWidth    );
150     case GLUT_SCREEN_HEIGHT:        return( fgDisplay.ScreenHeight   );
151     case GLUT_SCREEN_WIDTH_MM:      return( fgDisplay.ScreenWidthMM  );
152     case GLUT_SCREEN_HEIGHT_MM:     return( fgDisplay.ScreenHeightMM );
153     case GLUT_INIT_WINDOW_X:        return( fgState.Position.X       );
154     case GLUT_INIT_WINDOW_Y:        return( fgState.Position.Y       );
155     case GLUT_INIT_WINDOW_WIDTH:    return( fgState.Size.X           );
156     case GLUT_INIT_WINDOW_HEIGHT:   return( fgState.Size.Y           );
157     case GLUT_INIT_DISPLAY_MODE:    return( fgState.DisplayMode      );
158
159     /*
160      * The window/context specific queries are handled mostly by
161      * fghGetConfig().
162      */
163     case GLUT_WINDOW_NUM_SAMPLES:
164         /*
165          * XXX Multisampling. Return what I know about multisampling.
166          */
167         return( 0 );
168
169 #if TARGET_HOST_UNIX_X11
170     /*
171      * The rest of GLX queries under X are general enough to use a macro to
172      * check them
173      */
174 #   define GLX_QUERY(a,b) case a: return( fghGetConfig( b ) );
175
176     GLX_QUERY( GLUT_WINDOW_RGBA,                GLX_RGBA                );
177     GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER,        GLX_DOUBLEBUFFER        );
178     GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE,         GLX_BUFFER_SIZE         );
179     GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE,        GLX_STENCIL_SIZE        );
180     GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE,          GLX_DEPTH_SIZE          );
181     GLX_QUERY( GLUT_WINDOW_RED_SIZE,            GLX_RED_SIZE            );
182     GLX_QUERY( GLUT_WINDOW_GREEN_SIZE,          GLX_GREEN_SIZE          );
183     GLX_QUERY( GLUT_WINDOW_BLUE_SIZE,           GLX_BLUE_SIZE           );
184     GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE,          GLX_ALPHA_SIZE          );
185     GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE,      GLX_ACCUM_RED_SIZE      );
186     GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE,    GLX_ACCUM_GREEN_SIZE    );
187     GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE,     GLX_ACCUM_BLUE_SIZE     );
188     GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE,    GLX_ACCUM_ALPHA_SIZE    );
189     GLX_QUERY( GLUT_WINDOW_STEREO,              GLX_STEREO              );
190
191 #   undef GLX_QUERY
192
193     /*
194      * Colormap size is handled in a bit different way than all the rest
195      */
196     case GLUT_WINDOW_COLORMAP_SIZE:
197         if( (fghGetConfig( GLX_RGBA )) || (fgStructure.Window == NULL) )
198         {
199             /*
200              * We've got a RGBA visual, so there is no colormap at all.
201              * The other possibility is that we have no current window set.
202              */
203             return( 0 );
204         }
205         return( fgStructure.Window->Window.VisualInfo->visual->map_entries );
206
207     /*
208      * Those calls are somewhat similiar, as they use XGetWindowAttributes()
209      * function
210      */
211     case GLUT_WINDOW_X:
212     case GLUT_WINDOW_Y:
213     case GLUT_WINDOW_BORDER_WIDTH:
214     case GLUT_WINDOW_HEADER_HEIGHT:
215     {
216         int x, y;
217         Window w;
218
219         if( fgStructure.Window == NULL )
220             return( 0 );
221
222         XTranslateCoordinates(
223             fgDisplay.Display,
224             fgStructure.Window->Window.Handle,
225             fgDisplay.RootWindow,
226             0, 0, &x, &y, &w);
227
228         switch ( eWhat )
229         {
230         case GLUT_WINDOW_X: return x;
231         case GLUT_WINDOW_Y: return y;
232         }
233
234         if ( w == 0 )
235             return( 0 );
236         XTranslateCoordinates(
237             fgDisplay.Display,
238             fgStructure.Window->Window.Handle,
239             w, 0, 0, &x, &y, &w);
240
241         switch ( eWhat )
242         {
243         case GLUT_WINDOW_BORDER_WIDTH:  return x;
244         case GLUT_WINDOW_HEADER_HEIGHT: return y;
245         }
246     }
247
248     case GLUT_WINDOW_WIDTH:
249     case GLUT_WINDOW_HEIGHT:
250     {
251         XWindowAttributes winAttributes;
252
253         if( fgStructure.Window == NULL )
254             return( 0 );
255         XGetWindowAttributes(
256             fgDisplay.Display,
257             fgStructure.Window->Window.Handle,
258             &winAttributes
259         );
260         switch ( eWhat )
261         {
262         case GLUT_WINDOW_WIDTH:            return winAttributes.width ;
263         case GLUT_WINDOW_HEIGHT:           return winAttributes.height ;
264         }
265     }
266
267     /*
268      * I do not know yet if there will be a fgChooseVisual() function for Win32
269      */
270     case GLUT_DISPLAY_MODE_POSSIBLE:
271         return( fgChooseVisual() == NULL ? 0 : 1 );
272
273     /*
274      * This is system-dependant
275      */
276     case GLUT_WINDOW_FORMAT_ID:
277         if( fgStructure.Window == NULL )
278             return( 0 );
279
280         return( fgStructure.Window->Window.VisualInfo->visualid );
281
282 #elif TARGET_HOST_WIN32
283
284     /*
285      * Handle the OpenGL inquiries
286      */
287     case GLUT_WINDOW_RGBA:
288       glGetBooleanv ( GL_RGBA_MODE, &boolValue ) ;
289       returnValue = boolValue ? 1 : 0 ;
290       return ( returnValue ) ;
291     case GLUT_WINDOW_DOUBLEBUFFER:
292       glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ) ;
293       returnValue = boolValue ? 1 : 0 ;
294       return ( returnValue ) ;
295     case GLUT_WINDOW_STEREO:
296       glGetBooleanv ( GL_STEREO, &boolValue ) ;
297       returnValue = boolValue ? 1 : 0 ;
298       return ( returnValue ) ;
299
300     case GLUT_WINDOW_RED_SIZE:
301       glGetIntegerv ( GL_RED_BITS, &returnValue ) ;
302       return ( returnValue ) ;
303     case GLUT_WINDOW_GREEN_SIZE:
304       glGetIntegerv ( GL_GREEN_BITS, &returnValue ) ;
305       return ( returnValue ) ;
306     case GLUT_WINDOW_BLUE_SIZE:
307       glGetIntegerv ( GL_BLUE_BITS, &returnValue ) ;
308       return ( returnValue ) ;
309     case GLUT_WINDOW_ALPHA_SIZE:
310       glGetIntegerv ( GL_ALPHA_BITS, &returnValue ) ;
311       return ( returnValue ) ;
312     case GLUT_WINDOW_ACCUM_RED_SIZE:
313       glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ) ;
314       return ( returnValue ) ;
315     case GLUT_WINDOW_ACCUM_GREEN_SIZE:
316       glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ) ;
317       return ( returnValue ) ;
318     case GLUT_WINDOW_ACCUM_BLUE_SIZE:
319       glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ) ;
320       return ( returnValue ) ;
321     case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
322       glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ) ;
323       return ( returnValue ) ;
324     case GLUT_WINDOW_DEPTH_SIZE:
325       glGetIntegerv ( GL_DEPTH_BITS, &returnValue ) ;
326       return ( returnValue ) ;
327
328     case GLUT_WINDOW_BUFFER_SIZE:
329       returnValue = 1 ;                                      /* ????? */
330       return ( returnValue ) ;
331     case GLUT_WINDOW_STENCIL_SIZE:
332       returnValue = 0 ;                                      /* ????? */
333       return ( returnValue ) ;
334
335     case GLUT_WINDOW_X:
336     case GLUT_WINDOW_Y:
337     case GLUT_WINDOW_WIDTH:
338     case GLUT_WINDOW_HEIGHT:
339     {
340         /*
341          *  There is considerable confusion about the "right thing to
342          *  do" concerning window  size and position.  GLUT itself is
343          *  not consistent between Windows and UNIX/X11; since
344          *  platform independence is a virtue for "freeglut", we
345          *  decided to break with GLUT's behaviour.
346          *
347          *  Under UNIX/X11, it is apparently not possible to get the
348          *  window border sizes in order to subtract them off the
349          *  window's initial position until some time after the window
350          *  has been created.  Therefore we decided on the following
351          *  behaviour, both under Windows and under UNIX/X11:
352          *  - When you create a window with position (x,y) and size
353          *    (w,h), the upper left hand corner of the outside of the
354          *    window is at (x,y) and the size of the drawable area  is
355          *    (w,h).
356          *  - When you query the size and position of the window--as
357          *    is happening here for Windows--"freeglut" will return
358          *    the size of the drawable area--the (w,h) that you
359          *    specified when you created the window--and the coordinates
360          *    of the upper left hand corner of the drawable
361          *    area--which is NOT the (x,y) you specified.
362          */
363
364         RECT winRect;
365
366         freeglut_return_val_if_fail( fgStructure.Window != NULL, 0 );
367
368         /*
369          * We need to call GetWindowRect() first...
370          *  (this returns the pixel coordinates of the outside of the window)
371          */
372         GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
373
374         /*
375          * ...then we've got to correct the results we've just received...
376          */
377         if ( ( fgStructure.GameMode != fgStructure.Window ) && ( fgStructure.Window->Parent == NULL ) &&
378              ( ! fgStructure.Window->IsMenu ) )
379         {
380           winRect.left   += GetSystemMetrics( SM_CXSIZEFRAME );
381           winRect.right  -= GetSystemMetrics( SM_CXSIZEFRAME );
382           winRect.top    += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
383           winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME );
384         }
385
386         switch( eWhat )
387         {
388         case GLUT_WINDOW_X:      return( winRect.left                 );
389         case GLUT_WINDOW_Y:      return( winRect.top                  );
390         case GLUT_WINDOW_WIDTH:  return( winRect.right - winRect.left );
391         case GLUT_WINDOW_HEIGHT: return( winRect.bottom - winRect.top );
392         }
393     }
394     break;
395
396     case GLUT_WINDOW_BORDER_WIDTH :
397         return ( GetSystemMetrics( SM_CXSIZEFRAME ) ) ;
398
399     case GLUT_WINDOW_HEADER_HEIGHT :
400         return ( GetSystemMetrics( SM_CYCAPTION ) ) ;
401
402     case GLUT_DISPLAY_MODE_POSSIBLE:
403         return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_MAIN_PLANE ) );
404
405     case GLUT_WINDOW_FORMAT_ID:
406         if( fgStructure.Window != NULL )
407             return( GetPixelFormat( fgStructure.Window->Window.Device ) );
408         return( 0 );
409
410 #endif
411
412     /*
413      * The window structure queries
414      */
415     case GLUT_WINDOW_PARENT:
416         if( fgStructure.Window         == NULL ) return( 0 );
417         if( fgStructure.Window->Parent == NULL ) return( 0 );
418         return( fgStructure.Window->Parent->ID );
419
420     case GLUT_WINDOW_NUM_CHILDREN:
421         if( fgStructure.Window == NULL )
422             return( 0 );
423         return( fgListLength( &fgStructure.Window->Children ) );
424
425     case GLUT_WINDOW_CURSOR:
426         if( fgStructure.Window == NULL )
427             return( 0 );
428         return( fgStructure.Window->State.Cursor );
429
430     case GLUT_MENU_NUM_ITEMS:
431         if( fgStructure.Menu == NULL )
432             return( 0 );
433         return( fgListLength( &fgStructure.Menu->Entries ) );
434
435     case GLUT_ACTION_ON_WINDOW_CLOSE:
436         return fgState.ActionOnWindowClose ;
437
438     case GLUT_VERSION :
439         return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH ;
440
441     case GLUT_RENDERING_CONTEXT:
442         return ( fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT : GLUT_CREATE_NEW_CONTEXT ) ;
443
444     default:
445         fgWarning( "glutGet(): missing enum handle %i\n", eWhat );
446         break;
447     }
448     return( -1 );
449 }
450
451 /*
452  * Returns various device information.
453  */
454 int FGAPIENTRY glutDeviceGet( GLenum eWhat )
455 {
456     freeglut_assert_ready;
457
458     /*
459      * XXX WARNING: we are mostly lying in this function.
460      */
461     switch( eWhat )
462     {
463     case GLUT_HAS_KEYBOARD:
464         /*
465          * We always have a keyboard present on PC machines...
466          *
467          * XXX I think that some of my PCs will boot without a keyboard.
468          * XXX Also, who says that we are running on a PC?  UNIX/X11
469          * XXX is much more generic, and X11 can go over a network.
470          * XXX Though in actuality, we can probably assume BOTH a
471          * XXX mouse and keyboard for most/all of our users.
472          */
473         return( TRUE );
474
475 #if TARGET_HOST_UNIX_X11
476
477     case GLUT_HAS_MOUSE:
478         return( TRUE );
479
480     case GLUT_NUM_MOUSE_BUTTONS:
481         /*
482          * Return the number of mouse buttons available. This is a big guess.
483          *
484          * XXX We can probe /var/run/dmesg.boot which is world-readable.
485          * XXX This would be somewhat system-dependant, but is doable.
486          * XXX E.g., on NetBSD, my USB mouse registers:
487          * XXX   ums0 at uhidev0: 3 buttons and Z dir.
488          * XXX We can also probe /var/log/XFree86\..*\.log to get
489          * XXX lines such as:
490          * XXX   (**) Option "Buttons" "5"
491          * XXX   (**) Option "ZAxisMapping" "4 5"
492          * XXX   (**) Mouse0: ZAxisMapping: buttons 4 and 5
493          * XXX   (**) Mouse0: Buttons: 5
494          * XXX ...which tells us even more, and is a bit less
495          * XXX system-dependant.  (Other than MS-WINDOWS, all
496          * XXX target hosts with actual users are probably running
497          * XXX XFree86...)  It is at least worth taking a look at
498          * XXX this file.
499          */
500         return( 3 );
501
502 #elif TARGET_HOST_WIN32
503
504     case GLUT_HAS_MOUSE:
505         /*
506          * The Windows can be booted without a mouse. 
507          * It would be nice to have this reported.
508          */
509         return( GetSystemMetrics( SM_MOUSEPRESENT ) );
510
511     case GLUT_NUM_MOUSE_BUTTONS:
512         /*
513          * We are much more fortunate under Win32 about this...
514          */
515         return( GetSystemMetrics( SM_CMOUSEBUTTONS ) );
516
517 #endif
518
519     case GLUT_JOYSTICK_POLL_RATE:
520     case GLUT_HAS_JOYSTICK:
521     case GLUT_JOYSTICK_BUTTONS:
522     case GLUT_JOYSTICK_AXES:
523         /*
524          * XXX WARNING: THIS IS A BIG LIE!
525          */
526         return( 0 );
527
528     case GLUT_HAS_SPACEBALL:
529     case GLUT_HAS_DIAL_AND_BUTTON_BOX:
530     case GLUT_HAS_TABLET:
531         return( FALSE );
532
533     case GLUT_NUM_SPACEBALL_BUTTONS:
534     case GLUT_NUM_BUTTON_BOX_BUTTONS:
535     case GLUT_NUM_DIALS:
536     case GLUT_NUM_TABLET_BUTTONS:
537         return( 0 );
538
539     case GLUT_DEVICE_IGNORE_KEY_REPEAT:
540         return( fgState.IgnoreKeyRepeat );
541
542     case GLUT_DEVICE_KEY_REPEAT:
543         /*
544          * XXX WARNING: THIS IS A BIG LIE!
545          */
546         return( GLUT_KEY_REPEAT_DEFAULT );
547
548     default:
549         fgWarning( "glutDeviceGet(): missing enum handle %i\n", eWhat );
550         break;
551     }
552
553     /*
554      * And now -- the failure.
555      */
556     return( -1 );
557 }
558
559 /*
560  * This should return the current state of ALT, SHIFT and CTRL keys.
561  */
562 int FGAPIENTRY glutGetModifiers( void )
563 {
564     if( fgStructure.Window == NULL )
565         return( 0 );
566
567     if( fgStructure.Window->State.Modifiers == 0xffffffff )
568     {
569         fgWarning( "glutGetModifiers() called outside an input callback" );
570         return( 0 );
571     }
572
573     return( fgStructure.Window->State.Modifiers );
574 }
575
576 /*
577  * Return the state of the GLUT API overlay subsystem. A misery ;-)
578  */
579 int FGAPIENTRY glutLayerGet( GLenum eWhat )
580 {
581     freeglut_assert_ready;
582
583     /*
584      * This is easy as layers are not implemented ;-)
585      *
586      * XXX Can we merge the UNIX/X11 and WIN32 sections?  Or
587      * XXX is overlay support planned?
588      */
589     switch( eWhat )
590     {
591
592 #if TARGET_HOST_UNIX_X11
593
594     case GLUT_OVERLAY_POSSIBLE:
595         return( FALSE );
596
597     case GLUT_LAYER_IN_USE:
598         return( GLUT_NORMAL );
599
600     case GLUT_HAS_OVERLAY:
601         return( FALSE );
602
603     case GLUT_TRANSPARENT_INDEX:
604         /*
605          * Return just anything, which is always defined as zero
606          *
607          * XXX HUH?
608          */
609         return( 0 );
610
611     case GLUT_NORMAL_DAMAGED:
612         /*
613          * XXX Actually I do not know. Maybe.
614          */
615         return( FALSE );
616
617     case GLUT_OVERLAY_DAMAGED:
618         return( -1 );
619
620 #elif TARGET_HOST_WIN32
621
622     case GLUT_OVERLAY_POSSIBLE:
623 /*        return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_OVERLAY_PLANE ) ); */
624       return FALSE ;
625
626     case GLUT_LAYER_IN_USE:
627         return( GLUT_NORMAL );
628
629     case GLUT_HAS_OVERLAY:
630         return( FALSE );
631
632     case GLUT_TRANSPARENT_INDEX:
633         /*
634          * Return just anything, which is always defined as zero
635          *
636          * XXX HUH?
637          */
638         return( 0 );
639
640     case GLUT_NORMAL_DAMAGED:
641         /*
642          * XXX Actually I do not know. Maybe.
643          */
644         return( FALSE );
645
646     case GLUT_OVERLAY_DAMAGED:
647         return( -1 );
648 #endif
649
650     default:
651         fgWarning( "glutLayerGet(): missing enum handle %i\n", eWhat );
652         break;
653     }
654
655     /*
656      * And fail. That's good. Programs do love failing.
657      */
658     return( -1 );
659 }
660
661 /*** END OF FILE ***/