Made Modifers variable global as per glut classic.
[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 ) ? GL_TRUE : GL_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, GL_TRUE,
404                                     PFD_MAIN_PLANE ) );
405
406     case GLUT_WINDOW_FORMAT_ID:
407         if( fgStructure.Window != NULL )
408             return( GetPixelFormat( fgStructure.Window->Window.Device ) );
409         return( 0 );
410
411 #endif
412
413     /*
414      * The window structure queries
415      */
416     case GLUT_WINDOW_PARENT:
417         if( fgStructure.Window         == NULL ) return( 0 );
418         if( fgStructure.Window->Parent == NULL ) return( 0 );
419         return( fgStructure.Window->Parent->ID );
420
421     case GLUT_WINDOW_NUM_CHILDREN:
422         if( fgStructure.Window == NULL )
423             return( 0 );
424         return( fgListLength( &fgStructure.Window->Children ) );
425
426     case GLUT_WINDOW_CURSOR:
427         if( fgStructure.Window == NULL )
428             return( 0 );
429         return( fgStructure.Window->State.Cursor );
430
431     case GLUT_MENU_NUM_ITEMS:
432         if( fgStructure.Menu == NULL )
433             return( 0 );
434         return( fgListLength( &fgStructure.Menu->Entries ) );
435
436     case GLUT_ACTION_ON_WINDOW_CLOSE:
437         return fgState.ActionOnWindowClose ;
438
439     case GLUT_VERSION :
440         return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH ;
441
442     case GLUT_RENDERING_CONTEXT:
443         return ( fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT : GLUT_CREATE_NEW_CONTEXT ) ;
444
445     default:
446         fgWarning( "glutGet(): missing enum handle %i\n", eWhat );
447         break;
448     }
449     return( -1 );
450 }
451
452 /*
453  * Returns various device information.
454  */
455 int FGAPIENTRY glutDeviceGet( GLenum eWhat )
456 {
457     freeglut_assert_ready;
458
459     /*
460      * XXX WARNING: we are mostly lying in this function.
461      */
462     switch( eWhat )
463     {
464     case GLUT_HAS_KEYBOARD:
465         /*
466          * We always have a keyboard present on PC machines...
467          *
468          * XXX I think that some of my PCs will boot without a keyboard.
469          * XXX Also, who says that we are running on a PC?  UNIX/X11
470          * XXX is much more generic, and X11 can go over a network.
471          * XXX Though in actuality, we can probably assume BOTH a
472          * XXX mouse and keyboard for most/all of our users.
473          */
474         return( TRUE );
475
476 #if TARGET_HOST_UNIX_X11
477
478     case GLUT_HAS_MOUSE:
479         return( TRUE );
480
481     case GLUT_NUM_MOUSE_BUTTONS:
482         /*
483          * Return the number of mouse buttons available. This is a big guess.
484          *
485          * XXX We can probe /var/run/dmesg.boot which is world-readable.
486          * XXX This would be somewhat system-dependant, but is doable.
487          * XXX E.g., on NetBSD, my USB mouse registers:
488          * XXX   ums0 at uhidev0: 3 buttons and Z dir.
489          * XXX We can also probe /var/log/XFree86\..*\.log to get
490          * XXX lines such as:
491          * XXX   (**) Option "Buttons" "5"
492          * XXX   (**) Option "ZAxisMapping" "4 5"
493          * XXX   (**) Mouse0: ZAxisMapping: buttons 4 and 5
494          * XXX   (**) Mouse0: Buttons: 5
495          * XXX ...which tells us even more, and is a bit less
496          * XXX system-dependant.  (Other than MS-WINDOWS, all
497          * XXX target hosts with actual users are probably running
498          * XXX XFree86...)  It is at least worth taking a look at
499          * XXX this file.
500          */
501         return( 3 );
502
503 #elif TARGET_HOST_WIN32
504
505     case GLUT_HAS_MOUSE:
506         /*
507          * The Windows can be booted without a mouse. 
508          * It would be nice to have this reported.
509          */
510         return( GetSystemMetrics( SM_MOUSEPRESENT ) );
511
512     case GLUT_NUM_MOUSE_BUTTONS:
513         /*
514          * We are much more fortunate under Win32 about this...
515          */
516         return( GetSystemMetrics( SM_CMOUSEBUTTONS ) );
517
518 #endif
519
520     case GLUT_JOYSTICK_POLL_RATE:
521     case GLUT_HAS_JOYSTICK:
522     case GLUT_JOYSTICK_BUTTONS:
523     case GLUT_JOYSTICK_AXES:
524         /*
525          * XXX WARNING: THIS IS A BIG LIE!
526          */
527         return( 0 );
528
529     case GLUT_HAS_SPACEBALL:
530     case GLUT_HAS_DIAL_AND_BUTTON_BOX:
531     case GLUT_HAS_TABLET:
532         return( FALSE );
533
534     case GLUT_NUM_SPACEBALL_BUTTONS:
535     case GLUT_NUM_BUTTON_BOX_BUTTONS:
536     case GLUT_NUM_DIALS:
537     case GLUT_NUM_TABLET_BUTTONS:
538         return( 0 );
539
540     case GLUT_DEVICE_IGNORE_KEY_REPEAT:
541         return( fgState.IgnoreKeyRepeat );
542
543     case GLUT_DEVICE_KEY_REPEAT:
544         /*
545          * XXX WARNING: THIS IS A BIG LIE!
546          */
547         return( GLUT_KEY_REPEAT_DEFAULT );
548
549     default:
550         fgWarning( "glutDeviceGet(): missing enum handle %i\n", eWhat );
551         break;
552     }
553
554     /*
555      * And now -- the failure.
556      */
557     return( -1 );
558 }
559
560 /*
561  * This should return the current state of ALT, SHIFT and CTRL keys.
562  */
563 int FGAPIENTRY glutGetModifiers( void )
564 {
565     if( fgState.Modifiers == 0xffffffff )
566     {
567         fgWarning( "glutGetModifiers() called outside an input callback" );
568         return( 0 );
569     }
570
571     return( fgState.Modifiers );
572 }
573
574 /*
575  * Return the state of the GLUT API overlay subsystem. A misery ;-)
576  */
577 int FGAPIENTRY glutLayerGet( GLenum eWhat )
578 {
579     freeglut_assert_ready;
580
581     /*
582      * This is easy as layers are not implemented ;-)
583      *
584      * XXX Can we merge the UNIX/X11 and WIN32 sections?  Or
585      * XXX is overlay support planned?
586      */
587     switch( eWhat )
588     {
589
590 #if TARGET_HOST_UNIX_X11
591
592     case GLUT_OVERLAY_POSSIBLE:
593         return( FALSE );
594
595     case GLUT_LAYER_IN_USE:
596         return( GLUT_NORMAL );
597
598     case GLUT_HAS_OVERLAY:
599         return( FALSE );
600
601     case GLUT_TRANSPARENT_INDEX:
602         /*
603          * Return just anything, which is always defined as zero
604          *
605          * XXX HUH?
606          */
607         return( 0 );
608
609     case GLUT_NORMAL_DAMAGED:
610         /*
611          * XXX Actually I do not know. Maybe.
612          */
613         return( FALSE );
614
615     case GLUT_OVERLAY_DAMAGED:
616         return( -1 );
617
618 #elif TARGET_HOST_WIN32
619
620     case GLUT_OVERLAY_POSSIBLE:
621 /*      return( fgSetupPixelFormat( fgStructure.Window, GL_TRUE,
622                                     PFD_OVERLAY_PLANE ) ); */
623       return FALSE ;
624
625     case GLUT_LAYER_IN_USE:
626         return( GLUT_NORMAL );
627
628     case GLUT_HAS_OVERLAY:
629         return( FALSE );
630
631     case GLUT_TRANSPARENT_INDEX:
632         /*
633          * Return just anything, which is always defined as zero
634          *
635          * XXX HUH?
636          */
637         return( 0 );
638
639     case GLUT_NORMAL_DAMAGED:
640         /*
641          * XXX Actually I do not know. Maybe.
642          */
643         return( FALSE );
644
645     case GLUT_OVERLAY_DAMAGED:
646         return( -1 );
647 #endif
648
649     default:
650         fgWarning( "glutLayerGet(): missing enum handle %i\n", eWhat );
651         break;
652     }
653
654     /*
655      * And fail. That's good. Programs do love failing.
656      */
657     return( -1 );
658 }
659
660 /*** END OF FILE ***/