Now implemented properly working mouse entry and exit (EntryFunc callback) support...
authorDiederick Niehorster <dcnieho@gmail.com>
Wed, 27 Feb 2013 07:52:55 +0000 (07:52 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Wed, 27 Feb 2013 07:52:55 +0000 (07:52 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1520 7f0cb862-5218-0410-a997-914c9d46530a

src/fg_internal.h
src/mswin/fg_internal_mswin.h
src/mswin/fg_main_mswin.c

index 6ac8ffe..85bb750 100644 (file)
@@ -383,7 +383,7 @@ struct tagSFG_WindowState
     int             Width;              /* Window's width in pixels          */
     int             Height;             /* The same about the height         */
 
-       SFG_PlatformWindowState pWState;    /* Window width/height (X11) or rectangle/style (Windows) from before a resize */
+       SFG_PlatformWindowState pWState;    /* Window width/height (X11) or rectangle/style (Windows) from before a resize, and other stuff only needed on specific platforms */
 
     GLboolean       Redisplay;          /* Do we have to redisplay?          */
     GLboolean       Visible;            /* Is the window visible now         */
index 21899b8..fb6b1b7 100644 (file)
@@ -95,6 +95,8 @@ struct tagSFG_PlatformWindowState
     DWORD           OldStyle;           /* window style    - stored before the window is made fullscreen */
     DWORD           OldStyleEx;         /* window Ex style - stored before the window is made fullscreen */
     BOOL            OldMaximized;       /* window maximized state - stored before the window is made fullscreen */
+
+    GLboolean       MouseTracking;      /* Needed for generating GLUT_ENTERED and GLUT_LEFT entry func callbacks on windows */
 };
 
 
index 19daf5a..daa611c 100644 (file)
@@ -518,18 +518,14 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
         lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
 
         SetActiveWindow( window->Window.Handle );
-        INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
         UpdateWindow ( hWnd );
 
         break;
 
     case WM_KILLFOCUS:
         {
-            SFG_Window* saved_window = fgStructure.CurrentWindow;
 /*            printf("WM_KILLFOCUS: %p\n", window ); */
             lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
-            INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
-            fgSetWindow(saved_window);
 
             /* Check if there are any open menus that need to be closed */
             fgPlatformCheckMenuDeactivate();
@@ -553,11 +549,39 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
     case WM_SETCURSOR:
 /*      printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */
         if( LOWORD( lParam ) == HTCLIENT )
-            fgSetCursor ( window, window->State.Cursor ) ;
+        {
+            if (!window->State.pWState.MouseTracking)
+            {
+                TRACKMOUSEEVENT tme;
+
+                /* Cursor just entered window, set cursor look, invoke callback and start tracking so that we get a WM_MOUSELEAVE message */
+                fgSetCursor ( window, window->State.Cursor ) ;
+                INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
+
+                tme.cbSize = sizeof(TRACKMOUSEEVENT);
+                tme.dwFlags = TME_LEAVE;
+                tme.hwndTrack = window->Window.Handle;
+                TrackMouseEvent(&tme);
+
+                window->State.pWState.MouseTracking = GL_TRUE;
+            }
+        }
         else
+            /* Only pass non-client WM_SETCURSOR to DefWindowProc, or we get WM_SETCURSOR on parents of children as well */
             lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
         break;
 
+    case WM_MOUSELEAVE:
+        {
+            SFG_Window* saved_window = fgStructure.CurrentWindow;
+            INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
+            fgSetWindow(saved_window);
+
+            window->State.pWState.MouseTracking = GL_FALSE;
+            lRet = 0;   /* As per docs, must return zero */
+        }
+        break;
+
     case WM_SHOWWINDOW:
         window->State.Visible = GL_TRUE;
         window->State.Redisplay = GL_TRUE;
@@ -828,8 +852,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
     case WM_CAPTURECHANGED:
         /* User has finished resizing the window, force a redraw */
         INVOKE_WCB( *window, Display, ( ) );
-
-        /*lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); */
+        lRet = 0;   /* Per docs, should return zero */
         break;
 
         /* Other messages that I have seen and which are not handled already */