updated comments from John Fay
[freeglut] / src / freeglut_main.c
index 3e3a344..2e22721 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;
-};
-extern void wince_GetDefaultKeys(void* nData, int iOptions);
-extern void wince_OpenInput();
+
+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
 
 #ifndef MAX
@@ -157,7 +148,7 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
                       SWP_NOZORDER
         );
     }
-#endif //TARGET_HOST_WINCE
+#endif /* TARGET_HOST_WINCE */
 
     /*
      * XXX Should update {window->State.OldWidth, window->State.OldHeight}
@@ -290,7 +281,7 @@ static void fghcbCheckJoystickPolls( SFG_Window *window,
     {
 #if !TARGET_HOST_WINCE
         fgJoystickPollWindow( window );
-#endif //!TARGET_HOST_WINCE
+#endif /* !TARGET_HOST_WINCE */
         window->State.JoystickLastPoll = checkTime;
     }
 
@@ -489,7 +480,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.
      */
@@ -546,9 +537,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 )                         \
@@ -567,9 +556,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 );
@@ -581,8 +568,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;
@@ -859,17 +847,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 );
@@ -924,9 +908,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     );
             }
 
-            /*
-             * Trash the modifiers state
-             */
+            /* Trash the modifiers state */
             fgState.Modifiers = 0xffffffff;
         }
         break;
@@ -954,10 +936,13 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     char keys[32];
                     XQueryKeymap( fgDisplay.Display, keys ); /* Look at X11 keystate to detect repeat mode */
 
-                    if ( keys[event.xkey.keycode>>3] & (1<<(event.xkey.keycode%8)) )
-                        window->State.KeyRepeating = GL_TRUE;
-                    else
-                        window->State.KeyRepeating = GL_FALSE;
+                    if ( event.xkey.keycode<256 )            /* XQueryKeymap is limited to 256 keycodes    */
+                    {
+                        if ( keys[event.xkey.keycode>>3] & (1<<(event.xkey.keycode%8)) )
+                            window->State.KeyRepeating = GL_TRUE;
+                        else
+                            window->State.KeyRepeating = GL_FALSE;
+                    }
                 }
             }
             else
@@ -1092,7 +1077,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;
         }
 
@@ -1228,9 +1215,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 );
 
@@ -1285,9 +1270,22 @@ 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();
-#endif //TARGET_HOST_WINCE
+        /* 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;
 
     case WM_SIZE:
@@ -1305,13 +1303,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
 #else
             window->State.Width  = LOWORD(lParam);
             window->State.Height = HIWORD(lParam);
-#endif //TARGET_HOST_WINCE
+#endif /* TARGET_HOST_WINCE */
         }
 
         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;
 
@@ -1319,8 +1317,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 );
         }
 
@@ -1405,7 +1403,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
 #else
         window->State.MouseX = LOWORD( lParam );
         window->State.MouseY = HIWORD( lParam );
-#endif //TARGET_HOST_WINCE
+#endif /* TARGET_HOST_WINCE */
 
         if ( window->ActiveMenu )
         {
@@ -1445,7 +1443,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
 #else
         window->State.MouseX = LOWORD( lParam );
         window->State.MouseY = HIWORD( lParam );
-#endif //TARGET_HOST_WINCE
+#endif /* TARGET_HOST_WINCE */
 
         switch( uMsg )
         {
@@ -1488,7 +1486,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                 if( button == GLUT_RIGHT_BUTTON )
                     button = GLUT_LEFT_BUTTON;
         }
-#endif //!TARGET_HOST_WINCE
+#endif /* !TARGET_HOST_WINCE */
 
         if( button == -1 )
             return DefWindowProc( hWnd, uMsg, lParam, wParam );
@@ -1648,9 +1646,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 ;
 
@@ -1708,27 +1703,25 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         }
 
 #if TARGET_HOST_WINCE
-               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)
-                               keypress = GLUT_KEY_LEFT;
-                       else if(wParam==(unsigned)gxKeyList.vkUp)
-                               keypress = GLUT_KEY_UP;
-                       else if(wParam==(unsigned)gxKeyList.vkDown)
-                               keypress = GLUT_KEY_DOWN;
-                       else if(wParam==(unsigned)gxKeyList.vkA)
-                               keypress = GLUT_KEY_F1;
-                       else if(wParam==(unsigned)gxKeyList.vkB)
-                               keypress = GLUT_KEY_F2;
-                       else if(wParam==(unsigned)gxKeyList.vkC)
-                               keypress = GLUT_KEY_F3;
-                       else if(wParam==(unsigned)gxKeyList.vkStart)
-                               keypress = GLUT_KEY_F4;
-               }
+        if(!(lParam & 0x40000000)) /* Prevent auto-repeat */
+        {
+            if(wParam==(unsigned)gxKeyList.vkRight)
+                keypress = GLUT_KEY_RIGHT;
+            else if(wParam==(unsigned)gxKeyList.vkLeft)
+                keypress = GLUT_KEY_LEFT;
+            else if(wParam==(unsigned)gxKeyList.vkUp)
+                keypress = GLUT_KEY_UP;
+            else if(wParam==(unsigned)gxKeyList.vkDown)
+                keypress = GLUT_KEY_DOWN;
+            else if(wParam==(unsigned)gxKeyList.vkA)
+                keypress = GLUT_KEY_F1;
+            else if(wParam==(unsigned)gxKeyList.vkB)
+                keypress = GLUT_KEY_F2;
+            else if(wParam==(unsigned)gxKeyList.vkC)
+                keypress = GLUT_KEY_F3;
+            else if(wParam==(unsigned)gxKeyList.vkStart)
+                keypress = GLUT_KEY_F4;
+        }
 #endif
 
         if( keypress != -1 )
@@ -1812,7 +1805,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                         ( (char)wParam,
                           window->State.MouseX, window->State.MouseY )
             );
-#endif //!TARGET_HOST_WINCE
+#endif /* !TARGET_HOST_WINCE */
         }
         }
 
@@ -1892,11 +1885,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 ;
@@ -1950,9 +1947,15 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
 
             case SC_HOTKEY     :
                 break ;
+
+            default:
+#if _DEBUG
+                fgWarning( "Unknown wParam type 0x%x\n", wParam );
+#endif
+                break;
             }
         }
-#endif //!TARGET_HOST_WINCE
+#endif /* !TARGET_HOST_WINCE */
 
         /* We need to pass the message on to the operating system as well */
         lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );