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