Added missing files from "src" subdirectory to dist.
[freeglut] / src / freeglut_main.c
index 25c8e38..705f52b 100644 (file)
 #include <sys/stat.h>
 #elif TARGET_HOST_WIN32
 #elif TARGET_HOST_WINCE
-  // including gx.h does only work in c++ (thanks MS...),
-  // so we define this on our own...
-struct GXKeyList {
-    short vkUp;             // key for up
-    POINT ptUp;             // x,y position of key/button.  Not on screen but in screen coordinates.
-    short vkDown;
-    POINT ptDown;
-    short vkLeft;
-    POINT ptLeft;
-    short vkRight;
-    POINT ptRight;
-    short vkA;
-    POINT ptA;
-    short vkB;
-    POINT ptB;
-    short vkC;
-    POINT ptC;
-    short vkStart;
-    POINT ptStart;
-};
-/*__declspec(dllimport) struct GXKeyList GXGetDefaultKeys(int iOptions);
-__declspec(dllimport) int GXOpenInput();
-#include "my_gx.h"*/
-
-extern void wince_GetDefaultKeys(void* nData, int iOptions);
-extern void wince_OpenInput();
-
-/*void wince_GetDefaultKeys(void* nData, int iOptions)
-{
-    *(struct GXKeyList*)nData = GXGetDefaultKeys(iOptions);
-}
-void wince_OpenInput()
-{
-    GXOpenInput();
-}*/
+
+typedef struct GXDisplayProperties GXDisplayProperties;
+typedef struct GXKeyList GXKeyList;
+#include <gx.h>
+
+typedef struct GXKeyList (*GXGETDEFAULTKEYS)(int);
+typedef int (*GXOPENINPUT)();
+
+GXGETDEFAULTKEYS GXGetDefaultKeys_ = NULL;
+GXOPENINPUT GXOpenInput_ = NULL;
+
+struct GXKeyList gxKeyList;
 
 #endif
 
@@ -107,12 +84,10 @@ void wince_OpenInput()
  * callback is hooked, the viewport size is updated to
  * match the new window size.
  */
-static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
-                                       int width, int height )
+static void fghReshapeWindow ( SFG_Window *window, int width, int height )
 {
     SFG_Window *current_window = fgStructure.Window;
 
-    SFG_Window* window = fgWindowByHandle( handle );
     freeglut_return_if_fail( window != NULL );
 
 
@@ -126,7 +101,8 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
 
 #if !TARGET_HOST_WINCE
     {
-        RECT rect;
+        RECT winRect;
+        int x, y, w, h;
 
         /*
          * For windowed mode, get the current position of the
@@ -134,24 +110,29 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
          * decorations into account.
          */
 
-        GetWindowRect( window->Window.Handle, &rect );
-        rect.right  = rect.left + width;
-        rect.bottom = rect.top  + height;
+        /* "GetWindowRect" returns the pixel coordinates of the outside of the window */
+        GetWindowRect( window->Window.Handle, &winRect );
+        x = winRect.left;
+        y = winRect.top;
+        w = width;
+        h = height;
 
         if ( window->Parent == NULL )
         {
             if ( ! window->IsMenu && !window->State.IsGameMode )
             {
-                rect.right  += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
-                rect.bottom += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
-                               GetSystemMetrics( SM_CYCAPTION );
+                w += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
+                h += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
+                     GetSystemMetrics( SM_CYCAPTION );
             }
         }
         else
         {
-            GetWindowRect( window->Parent->Window.Handle, &rect );
-            AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
-                                      WS_CLIPCHILDREN, FALSE );
+            RECT parentRect;
+            GetWindowRect( window->Parent->Window.Handle, &parentRect );
+            x -= parentRect.left + GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
+            y -= parentRect.top  + GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
+                                   GetSystemMetrics( SM_CYCAPTION );
         }
 
         /*
@@ -163,10 +144,7 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
 
         SetWindowPos( window->Window.Handle,
                       HWND_TOP,
-                      rect.left,
-                      rect.top,
-                      rect.right  - rect.left,
-                      rect.bottom - rect.top,
+                      x, y, w, h,
                       SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
                       SWP_NOZORDER
         );
@@ -204,9 +182,10 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
  * Calls a window's redraw method. This is used when
  * a redraw is forced by the incoming window messages.
  */
-static void fghRedrawWindowByHandle ( SFG_WindowHandleType handle )
+static void fghRedrawWindow ( SFG_Window *window )
 {
-    SFG_Window* window = fgWindowByHandle( handle );
+    SFG_Window *current_window = fgStructure.Window;
+
     freeglut_return_if_fail( window );
     freeglut_return_if_fail( FETCH_WCB ( *window, Display ) );
 
@@ -214,23 +193,22 @@ static void fghRedrawWindowByHandle ( SFG_WindowHandleType handle )
 
     freeglut_return_if_fail( window->State.Visible );
 
+    fgSetWindow( window );
+
     if( window->State.NeedToResize )
     {
-        SFG_Window *current_window = fgStructure.Window;
-
-        fgSetWindow( window );
-
-        fghReshapeWindowByHandle(
-            window->Window.Handle,
+        fghReshapeWindow(
+            window,
             window->State.Width,
             window->State.Height
         );
 
         window->State.NeedToResize = GL_FALSE;
-        fgSetWindow( current_window );
     }
 
     INVOKE_WCB( *window, Display, ( ) );
+
+    fgSetWindow( current_window );
 }
 
 /*
@@ -239,34 +217,13 @@ static void fghRedrawWindowByHandle ( SFG_WindowHandleType handle )
 static void fghcbDisplayWindow( SFG_Window *window,
                                 SFG_Enumerator *enumerator )
 {
-    if( window->State.NeedToResize )
-    {
-        SFG_Window *current_window = fgStructure.Window;
-
-        fgSetWindow( window );
-
-        fghReshapeWindowByHandle(
-            window->Window.Handle,
-            window->State.Width,
-            window->State.Height
-        );
-
-        window->State.NeedToResize = GL_FALSE;
-        fgSetWindow ( current_window );
-    }
-
     if( window->State.Redisplay &&
         window->State.Visible )
     {
         window->State.Redisplay = GL_FALSE;
 
 #if TARGET_HOST_UNIX_X11
-        {
-            SFG_Window *current_window = fgStructure.Window;
-
-            INVOKE_WCB( *window, Display, ( ) );
-            fgSetWindow( current_window );
-        }
+        fghRedrawWindow ( window ) ;
 #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
         RedrawWindow(
             window->Window.Handle, NULL, NULL,
@@ -433,44 +390,44 @@ void fgWarning( const char *fmt, ... )
  * and all other "joystick timer" code can be yanked.
  *
  */
-static void fgCheckJoystickCallback( SFG_Window* w, SFG_Enumerator* e)
+static void fghCheckJoystickCallback( SFG_Window* w, SFG_Enumerator* e)
 {
     if( FETCH_WCB( *w, Joystick ) )
     {
         e->found = GL_TRUE;
         e->data = w;
     }
-    fgEnumSubWindows( w, fgCheckJoystickCallback, e );
+    fgEnumSubWindows( w, fghCheckJoystickCallback, e );
 }
-static int fgHaveJoystick( void )
+static int fghHaveJoystick( void )
 {
     SFG_Enumerator enumerator;
     enumerator.found = GL_FALSE;
     enumerator.data = NULL;
-    fgEnumWindows( fgCheckJoystickCallback, &enumerator );
+    fgEnumWindows( fghCheckJoystickCallback, &enumerator );
     return !!enumerator.data;
 }
-static void fgHavePendingRedisplaysCallback( SFG_Window* w, SFG_Enumerator* e)
+static void fghHavePendingRedisplaysCallback( SFG_Window* w, SFG_Enumerator* e)
 {
     if( w->State.Redisplay )
     {
         e->found = GL_TRUE;
         e->data = w;
     }
-    fgEnumSubWindows( w, fgHavePendingRedisplaysCallback, e );
+    fgEnumSubWindows( w, fghHavePendingRedisplaysCallback, e );
 }
-static int fgHavePendingRedisplays (void)
+static int fghHavePendingRedisplays (void)
 {
     SFG_Enumerator enumerator;
     enumerator.found = GL_FALSE;
     enumerator.data = NULL;
-    fgEnumWindows( fgHavePendingRedisplaysCallback, &enumerator );
+    fgEnumWindows( fghHavePendingRedisplaysCallback, &enumerator );
     return !!enumerator.data;
 }
 /*
  * Returns the number of GLUT ticks (milliseconds) till the next timer event.
  */
-static long fgNextTimer( void )
+static long fghNextTimer( void )
 {
     long ret = INT_MAX;
     SFG_Timer *timer = fgState.Timers.First;
@@ -486,16 +443,16 @@ static long fgNextTimer( void )
  * Does the magic required to relinquish the CPU until something interesting
  * happens.
  */
-static void fgSleepForEvents( void )
+static void fghSleepForEvents( void )
 {
     long msec;
 
-    if( fgState.IdleCallback || fgHavePendingRedisplays( ) )
+    if( fgState.IdleCallback || fghHavePendingRedisplays( ) )
         return;
 
-    msec = fgNextTimer( );
-    if( fgHaveJoystick( ) )     /* XXX Use GLUT timers for joysticks... */
-        msec = MIN( msec, 10 ); /* XXX Dumb; forces granularity to .01sec */
+    msec = fghNextTimer( );
+    if( fghHaveJoystick( ) )     /* XXX Use GLUT timers for joysticks... */
+        msec = MIN( msec, 10 );  /* XXX Dumb; forces granularity to .01sec */
 
 #if TARGET_HOST_UNIX_X11
     /*
@@ -503,7 +460,7 @@ static void fgSleepForEvents( void )
      * it is possible to have our socket drained but still have
      * unprocessed events.  (Or, this may just be normal with
      * X, anyway?)  We do non-trivial processing of X events
-     * after tham in event-reading loop, in any case, so we
+     * after the event-reading loop, in any case, so we
      * need to allow that we may have an empty socket but non-
      * empty event queue.
      */
@@ -521,8 +478,8 @@ static void fgSleepForEvents( void )
         wait.tv_usec = (msec % 1000) * 1000;
         err = select( socket+1, &fdset, NULL, NULL, &wait );
 
-        if( -1 == err )
-            fgWarning ( "freeglut select() error: %d\n", errno );
+        if( ( -1 == err ) && ( errno != EINTR ) )
+            fgWarning ( "freeglut select() error: %d", errno );
     }
 #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
     MsgWaitForMultipleObjects( 0, NULL, FALSE, msec, QS_ALLEVENTS );
@@ -533,7 +490,7 @@ static void fgSleepForEvents( void )
 /*
  * Returns GLUT modifier mask for an XEvent.
  */
-int fgGetXModifiers( XEvent *event )
+static int fghGetXModifiers( XEvent *event )
 {
     int ret = 0;
 
@@ -560,9 +517,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
     SFG_Window* window;
     XEvent event;
 
-    /*
-     * This code was repeated constantly, so here it goes into a definition:
-     */
+    /* This code was repeated constantly, so here it goes into a definition: */
 #define GETWINDOW(a)                             \
     window = fgWindowByHandle( event.a.window ); \
     if( window == NULL )                         \
@@ -581,9 +536,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
         switch( event.type )
         {
         case ClientMessage:
-            /*
-             * Destroy the window when the WM_DELETE_WINDOW message arrives
-             */
+            /* Destroy the window when the WM_DELETE_WINDOW message arrives */
             if( (Atom) event.xclient.data.l[ 0 ] == fgDisplay.DeleteWindow )
             {
                 GETWINDOW( xclient );
@@ -595,8 +548,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     fgDeinitialize( );
                     exit( 0 );
                 }
+                else if( fgState.ActionOnWindowClose == GLUT_ACTION_GLUTMAINLOOP_RETURNS )
+                    fgState.ExecState = GLUT_EXEC_STATE_STOP;
 
-                fgState.ExecState = GLUT_EXEC_STATE_STOP;
                 return;
             }
             break;
@@ -719,7 +673,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 break;
 
             default:
-                fgWarning( "Uknown X visibility state: %d",
+                fgWarning( "Unknown X visibility state: %d",
                            event.xvisibility.state );
                 break;
             }
@@ -873,17 +827,13 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 break;
             }
 
-            /*
-             * No active menu, let's check whether we need to activate one.
-             */
+            /* No active menu, let's check whether we need to activate one. */
             if( ( 0 <= button ) &&
                 ( FREEGLUT_MAX_MENUS > button ) &&
                 ( window->Menu[ button ] ) &&
                 pressed )
             {
-                /*
-                 * XXX Posting a requisite Redisplay seems bogus.
-                 */
+                /* XXX Posting a requisite Redisplay seems bogus. */
                 window->State.Redisplay = GL_TRUE;
                 fgSetWindow( window );
                 fgActivateMenu( window, button );
@@ -898,7 +848,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 ! FETCH_WCB( *window, MouseWheel ) )
                 break;
 
-            fgState.Modifiers = fgGetXModifiers( &event );
+            fgState.Modifiers = fghGetXModifiers( &event );
 
             /*
              * Finally execute the mouse or mouse wheel callback
@@ -938,9 +888,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     );
             }
 
-            /*
-             * Trash the modifiers state
-             */
+            /* Trash the modifiers state */
             fgState.Modifiers = 0xffffffff;
         }
         break;
@@ -1024,7 +972,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     if( keyboard_cb )
                     {
                         fgSetWindow( window );
-                        fgState.Modifiers = fgGetXModifiers( &event );
+                        fgState.Modifiers = fghGetXModifiers( &event );
                         keyboard_cb( asciiCode[ 0 ],
                                      event.xkey.x, event.xkey.y
                         );
@@ -1078,7 +1026,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     if( special_cb && (special != -1) )
                     {
                         fgSetWindow( window );
-                        fgState.Modifiers = fgGetXModifiers( &event );
+                        fgState.Modifiers = fghGetXModifiers( &event );
                         special_cb( special, event.xkey.x, event.xkey.y );
                         fgState.Modifiers = 0xffffffff;
                     }
@@ -1109,7 +1057,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 fgDeinitialize( );
                 exit( 0 );
             }
-            fgState.ExecState = GLUT_EXEC_STATE_STOP;
+            else if( fgState.ActionOnWindowClose == GLUT_ACTION_GLUTMAINLOOP_RETURNS )
+                fgState.ExecState = GLUT_EXEC_STATE_STOP;
+
             return;
         }
 
@@ -1187,7 +1137,7 @@ void FGAPIENTRY glutMainLoop( void )
             if( fgState.IdleCallback )
                 fgState.IdleCallback( );
 
-            fgSleepForEvents( );
+            fghSleepForEvents( );
         }
     }
 
@@ -1216,7 +1166,7 @@ void FGAPIENTRY glutLeaveMainLoop( void )
 /*
  * Determine a GLUT modifer mask based on MS-WINDOWS system info.
  */
-int fgGetWin32Modifiers (void)
+static int fghGetWin32Modifiers (void)
 {
     return
         ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
@@ -1245,9 +1195,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
     switch( uMsg )
     {
     case WM_CREATE:
-        /*
-         * The window structure is passed as the creation structure paramter...
-         */
+        /* The window structure is passed as the creation structure paramter... */
         window = (SFG_Window *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
         assert( window != NULL );
 
@@ -1302,8 +1250,21 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         ReleaseDC( window->Window.Handle, window->Window.Device );
 
 #if TARGET_HOST_WINCE
-        // Take over button handling
-        wince_OpenInput();
+        /* Take over button handling */
+        {
+            HINSTANCE dxDllLib=LoadLibrary(_T("gx.dll"));
+            if (dxDllLib)
+            {
+                GXGetDefaultKeys_=(GXGETDEFAULTKEYS)GetProcAddress(dxDllLib, _T("?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z"));
+                GXOpenInput_=(GXOPENINPUT)GetProcAddress(dxDllLib, _T("?GXOpenInput@@YAHXZ"));
+            }
+
+            if(GXOpenInput_)
+                (*GXOpenInput_)();
+            if(GXGetDefaultKeys_)
+                gxKeyList = (*GXGetDefaultKeys_)(GX_LANDSCAPEKEYS);
+        }
+
 #endif /* TARGET_HOST_WINCE */
         break;
 
@@ -1328,7 +1289,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         break;
 #if 0
     case WM_SETFOCUS:
-        printf("WM_SETFOCUS: %p\n", window );
+/*        printf("WM_SETFOCUS: %p\n", window ); */
         lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
         break;
 
@@ -1336,8 +1297,8 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         if (LOWORD(wParam) != WA_INACTIVE)
         {
             /* glutSetCursor( fgStructure.Window->State.Cursor ); */
-            printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window,
-                   window->State.Cursor );
+/*            printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window,
+                   window->State.Cursor ); */
             glutSetCursor( window->State.Cursor );
         }
 
@@ -1398,7 +1359,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         /* Turn on the visibility in case it was turned off somehow */
         window->State.Visible = GL_TRUE;
         BeginPaint( hWnd, &ps );
-        fghRedrawWindowByHandle( hWnd );
+        fghRedrawWindow( window );
         EndPaint( hWnd, &ps );
         break;
 
@@ -1423,6 +1384,10 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         window->State.MouseX = LOWORD( lParam );
         window->State.MouseY = HIWORD( lParam );
 #endif /* TARGET_HOST_WINCE */
+        /* Restrict to [-32768, 32767] to match X11 behaviour       */
+        /* See comment in "freeglut_developer" mailing list 10/4/04 */
+        if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536;
+        if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536;
 
         if ( window->ActiveMenu )
         {
@@ -1431,7 +1396,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
         }
 
-        fgState.Modifiers = fgGetWin32Modifiers( );
+        fgState.Modifiers = fghGetWin32Modifiers( );
 
         if( ( wParam & MK_LBUTTON ) ||
             ( wParam & MK_MBUTTON ) ||
@@ -1464,6 +1429,11 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         window->State.MouseY = HIWORD( lParam );
 #endif /* TARGET_HOST_WINCE */
 
+        /* Restrict to [-32768, 32767] to match X11 behaviour       */
+        /* See comment in "freeglut_developer" mailing list 10/4/04 */
+        if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536;
+        if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536;
+
         switch( uMsg )
         {
         case WM_LBUTTONDOWN:
@@ -1579,11 +1549,24 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
         }
 
+        /* Set capture so that the window captures all the mouse messages */
+        /*
+         * XXX - Multiple button support:  Under X11, the mouse is not released
+         * XXX - from the window until all buttons have been released, even if the
+         * XXX - user presses a button in another window.  This will take more
+         * XXX - code changes than I am up to at the moment (10/5/04).  The present
+         * XXX - is a 90 percent solution.
+         */
+        if ( pressed == GL_TRUE )
+          SetCapture ( window->Window.Handle ) ;
+        else
+          ReleaseCapture () ;
+
         if( ! FETCH_WCB( *window, Mouse ) )
             break;
 
         fgSetWindow( window );
-        fgState.Modifiers = fgGetWin32Modifiers( );
+        fgState.Modifiers = fghGetWin32Modifiers( );
 
         INVOKE_WCB(
             *window, Mouse,
@@ -1628,7 +1611,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
 
         fgSetWindow( window );
-        fgState.Modifiers = fgGetWin32Modifiers( );
+        fgState.Modifiers = fghGetWin32Modifiers( );
 
         while( ticks-- )
             if( FETCH_WCB( *window, MouseWheel ) )
@@ -1665,9 +1648,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
     case WM_SYSKEYDOWN:
     case WM_KEYDOWN:
     {
-#if TARGET_HOST_WINCE
-        struct GXKeyList gxKeyList;
-#endif /* TARGET_HOST_WINCE */
         int keypress = -1;
         POINT mouse_pos ;
 
@@ -1678,7 +1658,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.
          */
-        fgState.Modifiers = fgGetWin32Modifiers( );
+        fgState.Modifiers = fghGetWin32Modifiers( );
 
         GetCursorPos( &mouse_pos );
         ScreenToClient( window->Window.Handle, &mouse_pos );
@@ -1725,10 +1705,8 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         }
 
 #if TARGET_HOST_WINCE
-        if(!(lParam & 0x40000000)) // Prevent auto-repeat
+        if(!(lParam & 0x40000000)) /* Prevent auto-repeat */
         {
-            wince_GetDefaultKeys(&gxKeyList, 0x03);
-
             if(wParam==(unsigned)gxKeyList.vkRight)
                 keypress = GLUT_KEY_RIGHT;
             else if(wParam==(unsigned)gxKeyList.vkLeft)
@@ -1768,7 +1746,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.
          */
-        fgState.Modifiers = fgGetWin32Modifiers( );
+        fgState.Modifiers = fghGetWin32Modifiers( );
 
         GetCursorPos( &mouse_pos );
         ScreenToClient( window->Window.Handle, &mouse_pos );
@@ -1849,7 +1827,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
       if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) )
             break;
 
-        fgState.Modifiers = fgGetWin32Modifiers( );
+        fgState.Modifiers = fghGetWin32Modifiers( );
         INVOKE_WCB( *window, Keyboard,
                     ( (char)wParam,
                       window->State.MouseX, window->State.MouseY )
@@ -1909,11 +1887,15 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         {
           /*
            * We have received a system command message.  Try to act on it.
-           * The commands are passed in through the "lParam" parameter:
-           * Clicking on a corner to resize the window gives a "F004" message
-           * but this is not defined in my header file.
+           * The commands are passed in through the "wParam" parameter:
+           * The least significant digit seems to be which edge of the window
+           * is being used for a resize event:
+           *     4  3  5
+           *     1     2
+           *     7  6  8
+           * Congratulations and thanks to Richard Rauch for figuring this out..
            */
-            switch ( lParam )
+            switch ( wParam & 0xfff0 )
             {
             case SC_SIZE       :
                 break ;
@@ -1967,6 +1949,12 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
 
             case SC_HOTKEY     :
                 break ;
+
+            default:
+#if _DEBUG
+                fgWarning( "Unknown wParam type 0x%x", wParam );
+#endif
+                break;
             }
         }
 #endif /* !TARGET_HOST_WINCE */