Resolved bug #869765 glutIgnoreKeyRepeat() Fix (Win32)
[freeglut] / src / freeglut_main.c
index 4daeaa2..9bc7a91 100644 (file)
@@ -29,7 +29,7 @@
 #include "config.h"
 #endif
 
-#include "../include/GL/freeglut.h"
+#include <GL/freeglut.h>
 #include "freeglut_internal.h"
 
 #include <limits.h>
@@ -116,10 +116,10 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
         }
 
         /*
-         * SWP_NOACTIVATE      Do not activate the window
-         * SWP_NOOWNERZORDER   Do not change position in z-order
-         * SWP_NOSENDCHANGING  Supress WM_WINDOWPOSCHANGING message
-         * SWP_NOZORDER                Retains the current Z order (ignore 2nd param)
+         * SWP_NOACTIVATE      Do not activate the window
+         * SWP_NOOWNERZORDER   Do not change position in z-order
+         * SWP_NOSENDCHANGING  Supress WM_WINDOWPOSCHANGING message
+         * SWP_NOZORDER        Retains the current Z order (ignore 2nd param)
          */
 
         SetWindowPos( window->Window.Handle,
@@ -187,7 +187,7 @@ static void fghRedrawWindowByHandle ( SFG_WindowHandleType handle )
         );
 
         window->State.NeedToResize = GL_FALSE;
-        fgSetWindow ( current_window );
+        fgSetWindow( current_window );
     }
 
     INVOKE_WCB( *window, Display, ( ) );
@@ -379,20 +379,12 @@ void fgWarning( const char *fmt, ... )
  * Indicates whether Joystick events are being used by ANY window.
  *
  * The current mechanism is to walk all of the windows and ask if
- * there is a joystick callback.  Certainly in some cases, maybe
- * in all cases, the joystick is attached to the system and accessed
- * from ONE point by GLUT/freeglut, so this is not the right way,
- * in general, to do this.  However, the Joystick code is segregated
- * in its own little world, so we can't access the information that
- * we need in order to do that nicely.
- *
- * Some alternatives:
- *  * Store Joystick data into freeglut global state.
- *  * Provide NON-static functions or data from Joystick *.c file.
+ * there is a joystick callback.  We have a short-circuit early
+ * return if we find any joystick handler registered.
  *
- * Basically, the RIGHT way to do this requires knowing something
- * about the Joystick.  Right now, the Joystick code is behind
- * an opaque wall.
+ * The real way to do this is to make use of the glutTimer() API
+ * to more cleanly re-implement the joystick API.  Then, this code
+ * and all other "joystick timer" code can be yanked.
  *
  */
 static void fgCheckJoystickCallback( SFG_Window* w, SFG_Enumerator* e)
@@ -450,7 +442,7 @@ static long fgNextTimer( void )
  */
 static void fgSleepForEvents( void )
 {
-    long msec;    
+    long msec;
 
     if( fgState.IdleCallback || fgHavePendingRedisplays( ) )
         return;
@@ -460,15 +452,25 @@ static void fgSleepForEvents( void )
         msec = MIN( msec, 10 ); /* XXX Dumb; forces granularity to .01sec */
 
 #if TARGET_HOST_UNIX_X11
+    /*
+     * Possibly due to aggressive use of XFlush() and friends,
+     * 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
+     * need to allow that we may have an empty socket but non-
+     * empty event queue.
+     */
+    if( ! XPending( fgDisplay.Display ) )
     {
         fd_set fdset;
         int err;
         int socket;
         struct timeval wait;
+
         socket = ConnectionNumber( fgDisplay.Display );
         FD_ZERO( &fdset );
         FD_SET( socket, &fdset );
-
         wait.tv_sec = msec / 1000;
         wait.tv_usec = (msec % 1000) * 1000;
         err = select( socket+1, &fdset, NULL, NULL, &wait );
@@ -477,7 +479,7 @@ static void fgSleepForEvents( void )
             fgWarning ( "freeglut select() error: %d\n", errno );
     }
 #elif TARGET_HOST_WIN32
-    MsgWaitForMultipleObjects ( 0, NULL, FALSE, msec, QS_ALLEVENTS );
+    MsgWaitForMultipleObjects( 0, NULL, FALSE, msec, QS_ALLEVENTS );
 #endif
 }
 
@@ -611,12 +613,13 @@ void FGAPIENTRY glutMainLoopEvent( void )
              * XXX double-buffered does not respect viewport when we
              * XXX do a buffer-swap).
              *
-             * XXX GETWINDOW( xexpose );
-             * XXX fgSetWindow( window );
-             * XXX glutPostRedisplay( );
              */
             if( event.xexpose.count == 0 )
-                fghRedrawWindowByHandle( event.xexpose.window );
+            {
+                GETWINDOW( xexpose );
+                fgSetWindow( window );
+                glutPostRedisplay( );
+            }
             break;
 
         case MapNotify:
@@ -1562,7 +1565,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         int keypress = -1;
         POINT mouse_pos ;
 
-        if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) )
+        if( fgState.IgnoreKeyRepeat && (HIWORD(lParam) & KF_REPEAT) )
             break;
 
         /*
@@ -1711,7 +1714,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
     case WM_SYSCHAR:
     case WM_CHAR:
     {
-        if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) )
+        if( fgState.IgnoreKeyRepeat && (HIWORD(lParam) & KF_REPEAT) )
             break;
 
         fgState.Modifiers = fgGetWin32Modifiers( );