Update from John: Includes mouse button, mouse motion, and mouse wheel
[freeglut] / src / freeglut_main.c
index cfda031..485ee4b 100644 (file)
@@ -29,8 +29,6 @@
 #include "config.h"
 #endif
 
-#define  G_LOG_DOMAIN  "freeglut-main"
-
 #include "../include/GL/freeglut.h"
 #include "freeglut_internal.h"
 
@@ -90,7 +88,7 @@ static void fghRedrawWindowByHandle
 
     fgSetWindow( window );
     window->State.Redisplay = FALSE;
-    window->Callbacks.Display();
+    window->Callbacks.Display( );
 }
 
 /*
@@ -105,7 +103,7 @@ static void fghReshapeWindowByHandle
     ( HWND handle, int width, int height )
 #endif
 {
-    SFG_Window *current_window = fgStructure.Window ;
+    SFG_Window *current_window = fgStructure.Window;
 
     SFG_Window* window = fgWindowByHandle( handle );
     freeglut_return_if_fail( window != NULL );
@@ -123,10 +121,10 @@ static void fghReshapeWindowByHandle
      * But without this we get this bad behaviour whenever we resize the
      * window.
      */
-    window->State.Redisplay = TRUE ;
+    window->State.Redisplay = TRUE;
 
-    if ( window->IsMenu )
-        fgSetWindow ( current_window ) ;
+    if( window->IsMenu )
+        fgSetWindow( current_window );
 }
 
 /*
@@ -143,15 +141,15 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
 
         fgSetWindow( window );
         window->State.Redisplay = FALSE;
-        window->Callbacks.Display();
-        fgSetWindow( current_window ) ;
+        window->Callbacks.Display( );
+        fgSetWindow( current_window );
     }
 
 #elif TARGET_HOST_WIN32
 
     if( window->State.NeedToResize )
     {
-        SFG_Window *current_window = fgStructure.Window ;
+        SFG_Window *current_window = fgStructure.Window;
 
         fgSetWindow( window );
 
@@ -162,18 +160,18 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
         );
 
         window->State.NeedToResize = FALSE;
-        fgSetWindow ( current_window ) ;
+        fgSetWindow ( current_window );
     }
 
     if( (window->Callbacks.Display != NULL) &&
         (window->State.Redisplay == TRUE) &&
         (window->State.Visible == TRUE) )
     {
-      window->State.Redisplay = FALSE;
+        window->State.Redisplay = FALSE;
 
-      RedrawWindow( 
-        window->Window.Handle, NULL, NULL, 
-        RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
+        RedrawWindow( 
+            window->Window.Handle, NULL, NULL, 
+            RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
         );
     }
 
@@ -201,7 +199,7 @@ static void fghDisplayAll( void )
 static void fghcbCheckJoystickPolls( SFG_Window *window,
                                      SFG_Enumerator *enumerator )
 {
-    long int checkTime = fgElapsedTime();
+    long int checkTime = fgElapsedTime( );
 
     if( window->State.JoystickLastPoll + window->State.JoystickPollRate <=
         checkTime )
@@ -231,7 +229,7 @@ static void fghCheckJoystickPolls( void )
  */
 static void fghCheckTimers( void )
 {
-    long checkTime = fgElapsedTime();
+    long checkTime = fgElapsedTime( );
     SFG_Timer *timer, *next;
     SFG_List timedOut;
 
@@ -278,9 +276,9 @@ long fgElapsedTime( void )
     elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000;
     elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000;
     
-    return( elapsed );
+    return elapsed;
 #elif TARGET_HOST_WIN32
-    return (timeGetTime() - fgState.Time.Value);
+    return timeGetTime() - fgState.Time.Value;
 #endif
 }
 
@@ -409,15 +407,14 @@ static void fgSleepForEvents( void )
     struct timeval wait;
     long msec;    
     
-    if( fgState.IdleCallback ||
-        fgHavePendingRedisplays() )
+    if( fgState.IdleCallback || fgHavePendingRedisplays( ) )
         return;
     socket = ConnectionNumber( fgDisplay.Display );
     FD_ZERO( &fdset );
     FD_SET( socket, &fdset );
     
-    msec = fgNextTimer();
-    if( fgHaveJoystick() )
+    msec = fgNextTimer( );
+    if( fgHaveJoystick( ) )
         msec = MIN( msec, 10 );
     
     wait.tv_sec = msec / 1000;
@@ -431,6 +428,26 @@ static void fgSleepForEvents( void )
 #endif
 }
 
+#if TARGET_HOST_UNIX_X11
+/*
+ * Returns GLUT modifier mask for an XEvent.
+ */
+int fgGetXModifiers( XEvent *event )
+{
+    int ret = 0;
+
+    if( event->xkey.state & ( ShiftMask | LockMask ) )
+        ret |= GLUT_ACTIVE_SHIFT;
+    if( event->xkey.state & ControlMask )
+        ret |= GLUT_ACTIVE_CTRL;
+    if( event->xkey.state & Mod1Mask )
+        ret |= GLUT_ACTIVE_ALT;
+    
+    return ret;
+}
+#endif
+
+
 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
 
 /*
@@ -441,7 +458,6 @@ void FGAPIENTRY glutMainLoopEvent( void )
 #if TARGET_HOST_UNIX_X11
     SFG_Window* window;
     XEvent event;
-    int modifiers;
 
     /*
      * This code was repeated constantly, so here it goes into a definition:
@@ -637,10 +653,14 @@ void FGAPIENTRY glutMainLoopEvent( void )
                                               event.xmotion.y );
                 }
             }
-            else if( window->Callbacks.Passive )
+            else
             {
-                fgSetWindow ( window ) ;
-                window->Callbacks.Passive( event.xmotion.x, event.xmotion.y );
+                if( window->Callbacks.Passive )
+                {
+                    fgSetWindow( window );
+                    window->Callbacks.Passive( event.xmotion.x,
+                                               event.xmotion.y );
+                }
             }
         }
         break;
@@ -759,14 +779,10 @@ void FGAPIENTRY glutMainLoopEvent( void )
 
             fgSetWindow( window );
 
-            modifiers = 0;
-            if( event.xbutton.state & ( ShiftMask | LockMask ) )
-                modifiers |= GLUT_ACTIVE_SHIFT;
-            if( event.xbutton.state & ControlMask )
-                modifiers |= GLUT_ACTIVE_CTRL;
-            if( event.xbutton.state & Mod1Mask )
-                modifiers |= GLUT_ACTIVE_ALT;
-            fgStructure.Window->State.Modifiers = modifiers;
+            /*
+             * XXX Why don't we use {window}?  Other code here does...
+             */
+            fgStructure.Window->State.Modifiers = fgGetXModifiers( &event );
 
             /*
              * Finally execute the mouse or mouse wheel callback
@@ -778,43 +794,40 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 if( window->Callbacks.Mouse )
                     fgStructure.Window->Callbacks.Mouse(
                         button,
-                        event.type == ButtonPress ? GLUT_DOWN : GLUT_UP,
+                        pressed ? GLUT_DOWN : GLUT_UP,
                         event.xbutton.x,
                         event.xbutton.y
                     );
             }
             else
             {
-                if( ( button >= 4 ) && window->Callbacks.MouseWheel )
-                {
-                    /*
-                     * Map 4 and 5 to wheel zero; EVEN to +1, ODD to -1
-                     *  "  6 and 7 "    "   one; ...
-                     *
-                     * XXX This *should* be behind some variables/macros,
-                     * XXX since the order and numbering isn't certain
-                     * XXX See XFree86 configuration docs (even back in the
-                     * XXX 3.x days, and especially with 4.x).
-                     */
-                    int wheel_number = (button - 4) / 2;
-                    int direction = (button & 1)*2 - 1;
-
-                    if( ButtonPress )
-                        fgStructure.Window->Callbacks.MouseWheel(
-                            wheel_number,
-                            direction,
-                            event.xbutton.x,
-                            event.xbutton.y
-                        );
-                }
+                /*
+                 * Map 4 and 5 to wheel zero; EVEN to +1, ODD to -1
+                 *  "  6 and 7 "    "   one; ...
+                 *
+                 * XXX This *should* be behind some variables/macros,
+                 * XXX since the order and numbering isn't certain
+                 * XXX See XFree86 configuration docs (even back in the
+                 * XXX 3.x days, and especially with 4.x).
+                 */
+                int wheel_number = (button - 4) / 2;
+                int direction = (button & 1)*2 - 1;
+                
+                if( pressed )
+                    fgStructure.Window->Callbacks.MouseWheel(
+                        wheel_number,
+                        direction,
+                        event.xbutton.x,
+                        event.xbutton.y
+                    );
             }
 
             /*
              * Trash the modifiers state
              */
             fgStructure.Window->State.Modifiers = 0xffffffff;
-            break;
         }
+        break;
 
         case KeyRelease:
         case KeyPress:
@@ -863,25 +876,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     if( keyboard_cb )
                     {
                         fgSetWindow( window );
-
-                        /*
-                         * Remember the current modifiers state
-                         */
-                        modifiers = 0;
-                        if( event.xkey.state & ( ShiftMask | LockMask ) )
-                            modifiers |= GLUT_ACTIVE_SHIFT;
-                        if( event.xkey.state & ControlMask )
-                            modifiers |= GLUT_ACTIVE_CTRL;
-                        if( event.xkey.state & Mod1Mask )
-                            modifiers |= GLUT_ACTIVE_ALT;
-                        window->State.Modifiers = modifiers;
-
+                        window->State.Modifiers = fgGetXModifiers( &event );
                         keyboard_cb( asciiCode[ 0 ],
                                      event.xkey.x, event.xkey.y );
-
-                        /*
-                         * Trash the modifiers state
-                         */
                         window->State.Modifiers = 0xffffffff;
                     }
                 }
@@ -932,24 +929,8 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     if( special_cb && (special != -1) )
                     {
                         fgSetWindow( window );
-
-                        /*
-                         * Remember the current modifiers state
-                         */
-                        modifiers = 0;
-                        if( event.xkey.state & ( ShiftMask | LockMask ) )
-                            modifiers |= GLUT_ACTIVE_SHIFT;
-                        if( event.xkey.state & ControlMask )
-                            modifiers |= GLUT_ACTIVE_CTRL;
-                        if( event.xkey.state & Mod1Mask )
-                            modifiers |= GLUT_ACTIVE_ALT;
-                        window->State.Modifiers = modifiers;
-
+                        window->State.Modifiers = fgGetXModifiers( &event );
                         special_cb( special, event.xkey.x, event.xkey.y );
-
-                        /*
-                         * Trash the modifiers state
-                         */
                         window->State.Modifiers = 0xffffffff;
                     }
                 }
@@ -1038,7 +1019,7 @@ void FGAPIENTRY glutMainLoop( void )
     }
 
     {
-        fgExecutionState execState = fgState.ActionOnWindowClose;
+        fgExecutionState execState = fgState.ExecState;
         
         /*
          * When this loop terminates, destroy the display, state and structure
@@ -1059,10 +1040,25 @@ void FGAPIENTRY glutLeaveMainLoop( void )
     fgState.ExecState = GLUT_EXEC_STATE_STOP ;
 }
 
+
+#if TARGET_HOST_WIN32
+/*
+ * Determine a GLUT modifer mask based on MS-WINDOWS system info.
+ */
+int fgGetWin32Modifiers (void)
+{
+    return
+        ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
+            ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
+        ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
+            ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
+        ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
+            ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+}
+
 /*
  * The window procedure for handling Win32 events
  */
-#if TARGET_HOST_WIN32
 LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                                LPARAM lParam )
 {
@@ -1088,24 +1084,24 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         window->Window.Device = GetDC( hWnd );
         if( fgState.BuildingAMenu )
         {
-          unsigned int current_DisplayMode = fgState.DisplayMode;
-          fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH;
-          fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
-          fgState.DisplayMode = current_DisplayMode;
-
-          if( fgStructure.MenuContext )
-              wglMakeCurrent( window->Window.Device,
-                              fgStructure.MenuContext->Context ) ;
-          else
-          {
-              fgStructure.MenuContext =
-                  (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
-              fgStructure.MenuContext->Context =
-                  wglCreateContext( window->Window.Device );
-          }
-
-          /* window->Window.Context = wglGetCurrentContext () ;   */
-          window->Window.Context = wglCreateContext( window->Window.Device );
+            unsigned int current_DisplayMode = fgState.DisplayMode;
+            fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH;
+            fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
+            fgState.DisplayMode = current_DisplayMode;
+
+            if( fgStructure.MenuContext )
+                wglMakeCurrent( window->Window.Device,
+                                fgStructure.MenuContext->Context ) ;
+            else
+            {
+                fgStructure.MenuContext =
+                    (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
+                fgStructure.MenuContext->Context =
+                    wglCreateContext( window->Window.Device );
+            }
+
+            /* window->Window.Context = wglGetCurrentContext () ;   */
+            window->Window.Context = wglCreateContext( window->Window.Device );
         }
         else
         {
@@ -1145,7 +1141,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             /* glutSetCursor( fgStructure.Window->State.Cursor ); */
             printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window,
                    window->State.Cursor );
-
             glutSetCursor( window->State.Cursor );
         }
 
@@ -1162,32 +1157,38 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             (fgStructure.Window->State.Cursor == GLUT_CURSOR_NONE))
           SetCursor( NULL );
 #else
+
         /* Set the cursor AND change it for this window class. */
-#        define MAP_CURSOR(a,b) case a: SetCursor( LoadCursor( NULL, b ) ); \
-        break;
+#define MAP_CURSOR(a,b)                 \
+    case a:                             \
+    SetCursor( LoadCursor( NULL, b ) ); \
+    break;
+
         /* Nuke the cursor AND change it for this window class. */
-#        define ZAP_CURSOR(a,b) case a: SetCursor( NULL ); \
-        break;
+#define ZAP_CURSOR(a,b) \
+    case a:             \
+    SetCursor( NULL );  \
+    break;
 
         if( LOWORD( lParam ) == HTCLIENT )
-          switch( window->State.Cursor )
-          {
-              MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW     );
-              MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW,  IDC_ARROW     );
-              MAP_CURSOR( GLUT_CURSOR_INFO,        IDC_HELP      );
-              MAP_CURSOR( GLUT_CURSOR_DESTROY,     IDC_CROSS     );
-              MAP_CURSOR( GLUT_CURSOR_HELP,        IDC_HELP           );
-              MAP_CURSOR( GLUT_CURSOR_CYCLE,       IDC_SIZEALL   );
-              MAP_CURSOR( GLUT_CURSOR_SPRAY,       IDC_CROSS     );
-              MAP_CURSOR( GLUT_CURSOR_WAIT,                 IDC_WAIT      );
-              MAP_CURSOR( GLUT_CURSOR_TEXT,        IDC_UPARROW   );
-              MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,   IDC_CROSS     );
-              /* MAP_CURSOR( GLUT_CURSOR_NONE,        IDC_NO                   ); */
-              ZAP_CURSOR( GLUT_CURSOR_NONE,        NULL           );
-
-          default:
-              MAP_CURSOR( GLUT_CURSOR_UP_DOWN,     IDC_ARROW     );
-          }
+            switch( window->State.Cursor )
+            {
+                MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW     );
+                MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW,  IDC_ARROW     );
+                MAP_CURSOR( GLUT_CURSOR_INFO,        IDC_HELP      );
+                MAP_CURSOR( GLUT_CURSOR_DESTROY,     IDC_CROSS     );
+                MAP_CURSOR( GLUT_CURSOR_HELP,        IDC_HELP      );
+                MAP_CURSOR( GLUT_CURSOR_CYCLE,       IDC_SIZEALL   );
+                MAP_CURSOR( GLUT_CURSOR_SPRAY,       IDC_CROSS     );
+                MAP_CURSOR( GLUT_CURSOR_WAIT,        IDC_WAIT      );
+                MAP_CURSOR( GLUT_CURSOR_TEXT,        IDC_UPARROW   );
+                MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,   IDC_CROSS     );
+                /* MAP_CURSOR( GLUT_CURSOR_NONE,        IDC_NO         ); */
+                ZAP_CURSOR( GLUT_CURSOR_NONE,        NULL          );
+
+            default:
+                MAP_CURSOR( GLUT_CURSOR_UP_DOWN,     IDC_ARROW     );
+            }
 #endif
         else
             lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
@@ -1235,7 +1236,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
          * Put on a linked list of windows to be removed after all the
          * callbacks have returned
          */
-        fgAddToWindowDestroyList( window, FALSE ) ;
+        fgAddToWindowDestroyList( window, FALSE );
         DestroyWindow( hWnd );
         break;
 
@@ -1243,7 +1244,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         /*
          * The window already got destroyed, so don't bother with it.
          */
-        return( 0 );
+        return 0;
 
     case WM_MOUSEMOVE:
     {
@@ -1252,23 +1253,12 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         
         if ( window->ActiveMenu )
         {
-            window->State.Redisplay = TRUE ;
-
-            /*
-             * Since the window is a menu, make the parent window current
-             */
-            fgSetWindow ( window->ActiveMenu->ParentWindow ) ;
-
+            window->State.Redisplay = TRUE;
+            fgSetWindow ( window->ActiveMenu->ParentWindow );
             break;
         }
 
-        window->State.Modifiers = 
-            ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
-                ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
-            ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
-                ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
-            ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
-                ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+        window->State.Modifiers = fgGetWin32Modifiers( );
 
         if( ( wParam & MK_LBUTTON ) ||
             ( wParam & MK_MBUTTON ) ||
@@ -1392,7 +1382,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
         }
 
-        if ( ( window->Menu[ button ] != NULL ) && ( pressed == TRUE ) )
+        if ( ( window->Menu[ button ] ) && ( pressed == TRUE ) )
         {
             window->State.Redisplay = TRUE;
             fgSetWindow( window );
@@ -1405,14 +1395,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
 
         fgSetWindow( window );
-
-        fgStructure.Window->State.Modifiers = 
-            ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
-                ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
-            ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
-                ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
-            ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
-                ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+        fgStructure.Window->State.Modifiers = fgGetWin32Modifiers( );
 
         window->Callbacks.Mouse(
             button,
@@ -1453,13 +1436,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
 
         fgSetWindow( window );
-        fgStructure.Window->State.Modifiers = 
-            ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
-                ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
-            ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
-                ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
-            ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
-                ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+        fgStructure.Window->State.Modifiers = fgGetWin32Modifiers( );
 
         while( ticks-- )
             if( window->Callbacks.MouseWheel )
@@ -1476,13 +1453,16 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                  * XXX buttons.  Sorry.
                  */
                 int button = wheel_number*2 + 4;
-                button += (1 + direction)/2;
+                if( direction > 0 )
+                    ++button;
                 window->Callbacks.Mouse( button, GLUT_DOWN,
                                          window->State.MouseX,
-                                         window->State.MouseY ) ;
+                                         window->State.MouseY
+                );
                 window->Callbacks.Mouse( button, GLUT_UP,
                                          window->State.MouseX,
-                                         window->State.MouseY ) ;
+                                         window->State.MouseY
+                );
             }
 
         fgStructure.Window->State.Modifiers = 0xffffffff;
@@ -1502,13 +1482,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
          * Remember the current modifiers state. This is done here in order 
          * to make sure the VK_DELETE keyboard callback is executed properly.
          */
-        window->State.Modifiers = 
-            ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
-                ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
-            ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
-                ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
-            ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
-                ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+        window->State.Modifiers = fgGetWin32Modifiers( );
 
         GetCursorPos( &mouse_pos );
         ScreenToClient( window->Window.Handle, &mouse_pos );
@@ -1572,19 +1546,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
     case WM_KEYUP:
     {
         int keypress = -1;
-        POINT mouse_pos ;
+        POINT mouse_pos;
 
         /*
          * Remember the current modifiers state. This is done here in order 
          * to make sure the VK_DELETE keyboard callback is executed properly.
          */
-        window->State.Modifiers = 
-            ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
-                ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
-            ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
-                ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
-            ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
-                ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+        window->State.Modifiers = fgGetWin32Modifiers( );
 
         GetCursorPos( &mouse_pos );
         ScreenToClient( window->Window.Handle, &mouse_pos );
@@ -1674,14 +1642,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         if( window->Callbacks.Keyboard )
         {
             fgSetWindow( window );
-            window->State.Modifiers = 
-                ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
-                    ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
-                ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
-                    ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
-                ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
-                    ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
-
+            window->State.Modifiers = fgGetWin32Modifiers( );
             window->Callbacks.Keyboard( (char)wParam, window->State.MouseX,
                                         window->State.MouseY );
             window->State.Modifiers = 0xffffffff;
@@ -1694,7 +1655,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         if( window->Callbacks.Display )
         {
             fgSetWindow( window );
-
             window->Callbacks.Display( );
         }
 
@@ -1748,7 +1708,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         break;
     }
 
-    return lRet ;
+    return lRet;
 }
 #endif