Changing hard-coded constant (number of mouse buttons = 3) to a \"glutDeviceGet\...
[freeglut] / src / freeglut_main.c
index 5726571..da5bcfe 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include <GL/freeglut.h>
 #include "freeglut_internal.h"
-
-#include <limits.h>
-#if TARGET_HOST_UNIX_X11
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
 #include <errno.h>
-#include <sys/stat.h>
-#elif TARGET_HOST_WIN32
-#elif TARGET_HOST_WINCE
+#include <stdarg.h>
+#if HAVE_VPRINTF
+#    define VFPRINTF(s,f,a) vfprintf((s),(f),(a))
+#elif HAVE_DOPRNT
+#    define VFPRINTF(s,f,a) _doprnt((f),(a),(s))
+#else
+#    define VFPRINTF(s,f,a)
+#endif
+
+#if TARGET_HOST_WINCE
 
 typedef struct GXDisplayProperties GXDisplayProperties;
 typedef struct GXKeyList GXKeyList;
@@ -57,8 +53,15 @@ struct GXKeyList gxKeyList;
 
 #endif
 
-#ifndef MAX
-#define MAX(a,b) (((a)>(b)) ? (a) : (b))
+/*
+ * Try to get the maximum value allowed for ints, falling back to the minimum
+ * guaranteed by ISO C99 if there is no suitable header.
+ */
+#if HAVE_LIMITS_H
+#    include <limits.h>
+#endif
+#ifndef INT_MAX
+#    define INT_MAX 32767
 #endif
 
 #ifndef MIN
@@ -86,7 +89,7 @@ struct GXKeyList gxKeyList;
  */
 static void fghReshapeWindow ( SFG_Window *window, int width, int height )
 {
-    SFG_Window *current_window = fgStructure.Window;
+    SFG_Window *current_window = fgStructure.CurrentWindow;
 
     freeglut_return_if_fail( window != NULL );
 
@@ -184,7 +187,7 @@ static void fghReshapeWindow ( SFG_Window *window, int width, int height )
  */
 static void fghRedrawWindow ( SFG_Window *window )
 {
-    SFG_Window *current_window = fgStructure.Window;
+    SFG_Window *current_window = fgStructure.CurrentWindow;
 
     freeglut_return_if_fail( window );
     freeglut_return_if_fail( FETCH_WCB ( *window, Display ) );
@@ -351,8 +354,8 @@ void fgError( const char *fmt, ... )
 
     fprintf( stderr, "freeglut ");
     if( fgState.ProgramName )
-        fprintf (stderr, "(%s): ", fgState.ProgramName);
-    vfprintf( stderr, fmt, ap );
+        fprintf( stderr, "(%s): ", fgState.ProgramName );
+    VFPRINTF( stderr, fmt, ap );
     fprintf( stderr, "\n" );
 
     va_end( ap );
@@ -372,7 +375,7 @@ void fgWarning( const char *fmt, ... )
     fprintf( stderr, "freeglut ");
     if( fgState.ProgramName )
         fprintf( stderr, "(%s): ", fgState.ProgramName );
-    vfprintf( stderr, fmt, ap );
+    VFPRINTF( stderr, fmt, ap );
     fprintf( stderr, "\n" );
 
     va_end( ap );
@@ -453,8 +456,10 @@ static void fghSleepForEvents( void )
         return;
 
     msec = fghNextTimer( );
-    if( fghHaveJoystick( ) )     /* XXX Use GLUT timers for joysticks... */
-        msec = MIN( msec, 10 );  /* XXX Dumb; forces granularity to .01sec */
+    /* XXX Use GLUT timers for joysticks... */
+    /* XXX Dumb; forces granularity to .01sec */
+    if( fghHaveJoystick( ) && ( msec < 10 ) )     
+        msec = 10;
 
 #if TARGET_HOST_UNIX_X11
     /*
@@ -480,7 +485,7 @@ static void fghSleepForEvents( void )
         wait.tv_usec = (msec % 1000) * 1000;
         err = select( socket+1, &fdset, NULL, NULL, &wait );
 
-        if( -1 == err )
+        if( ( -1 == err ) && ( errno != EINTR ) )
             fgWarning ( "freeglut select() error: %d", errno );
     }
 #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
@@ -772,12 +777,8 @@ void FGAPIENTRY glutMainLoopEvent( void )
 
             fgState.Modifiers = fghGetXModifiers( &event );
 
-            /*
-             * Finally execute the mouse or mouse wheel callback
-             *
-             * XXX Use a symbolic constant, *not* "4"!  ("3, sire!")
-             */
-            if( ( button < 3 ) || ( ! FETCH_WCB( *window, MouseWheel ) ) )
+            /* Finally execute the mouse or mouse wheel callback */
+            if( ( button < glutDeviceGet ( GLUT_NUM_MOUSE_BUTTONS ) ) || ( ! FETCH_WCB( *window, MouseWheel ) ) )
                 INVOKE_WCB( *window, Mouse, ( button,
                                               pressed ? GLUT_DOWN : GLUT_UP,
                                               event.xbutton.x,
@@ -797,7 +798,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                  * XXX Note that {button} has already been decremeted
                  * XXX in mapping from X button numbering to GLUT.
                  */
-                int wheel_number = (button - 3) / 2;
+                int wheel_number = (button - glutDeviceGet ( GLUT_NUM_MOUSE_BUTTONS )) / 2;
                 int direction = -1;
                 if( button % 2 )
                     direction = 1;
@@ -1020,7 +1021,7 @@ void FGAPIENTRY glutMainLoop( void )
     {
         if ( FETCH_WCB( *window, Visibility ) )
         {
-            SFG_Window *current_window = fgStructure.Window ;
+            SFG_Window *current_window = fgStructure.CurrentWindow ;
 
             INVOKE_WCB( *window, Visibility, ( window->State.Visible ) );
             fgSetWindow( current_window );
@@ -1218,57 +1219,19 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
     case WM_ACTIVATE:
         if (LOWORD(wParam) != WA_INACTIVE)
         {
-            /* glutSetCursor( fgStructure.Window->State.Cursor ); */
-/*            printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window,
+/*            printf("WM_ACTIVATE: fgSetCursor( %p, %d)\n", window,
                    window->State.Cursor ); */
-            glutSetCursor( window->State.Cursor );
+            fgSetCursor( window, window->State.Cursor );
         }
 
         lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
         break;
 #endif
 
-        /*
-         * XXX Why not re-use some common code with the glutSetCursor()
-         * XXX function (or perhaps invoke glutSetCursor())?
-         * XXX That is, why are we duplicating code, here, from
-         * XXX glutSetCursor()?  The WIN32 code should be able to just
-         * XXX call glutSetCursor() instead of defining two macros
-         * XXX and implementing a nested case in-line.
-         */
     case WM_SETCURSOR:
-        /* Set the cursor AND change it for this window class. */
-#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;
-
 /*      printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */
         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     );
-            }
+            fgSetCursor ( window, window->State.Cursor ) ;
         else
             lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
         break;
@@ -1298,6 +1261,16 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
          */
         return 0;
 
+    /* XXX For a future patch:  we need a mouse entry event.  Unfortunately Windows
+     * XXX doesn't give us one, so we will probably need a "MouseInWindow" flag in
+     * XXX the SFG_Window structure.  Set it to true to begin with and then have the
+     * XXX WM_MOUSELEAVE code set it to false.  Then when we get a WM_MOUSEMOVE event,
+     * XXX if the flag is false we invoke the Entry callback and set the flag to true.
+     */
+    case 0x02a2:  /* This is the message we get when the mouse is leaving the window */
+        INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
+        break ;
+
     case WM_MOUSEMOVE:
     {
 #if TARGET_HOST_WINCE
@@ -1412,15 +1385,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                                window->State.MouseX, window->State.MouseY ) )
             break;
 
-        if( window->Menu[ button ] && pressed )
-        {
-            window->State.Redisplay = GL_TRUE;
-            fgSetWindow( window );
-            fgActivateMenu( window, button );
-
-            break;
-        }
-
         /* Set capture so that the window captures all the mouse messages */
         /*
          * XXX - Multiple button support:  Under X11, the mouse is not released