X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=bf02a7eb534c878207a7e509ce7edf264a934bb3;hb=a6652836b04c2ed99ae68c9ed5963dfac3e062a6;hp=daa611cfc373299bec0574c6c91ccc5aa8f7c38c;hpb=7f4876d5e652a7936123de63788bc74d34a15ad7;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index daa611c..bf02a7e 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -361,6 +361,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR { SFG_Window *window; LRESULT lRet = 1; + static int setCaptureActive = 0; FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ; @@ -554,16 +555,24 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR { TRACKMOUSEEVENT tme; - /* Cursor just entered window, set cursor look, invoke callback and start tracking so that we get a WM_MOUSELEAVE message */ + /* Cursor just entered window, set cursor look */ 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; + /* If an EntryFunc callback is specified by the user, also + * invoke that callback and start mouse tracking so that + * we get a WM_MOUSELEAVE message + */ + if (FETCH_WCB( *window, Entry )) + { + 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 @@ -573,6 +582,10 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR case WM_MOUSELEAVE: { + /* NB: This message is only received when a EntryFunc callback + * is specified by the user, as that is the only condition under + * which mouse tracking is setup in WM_SETCURSOR handler above + */ SFG_Window* saved_window = fgStructure.CurrentWindow; INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) ); fgSetWindow(saved_window); @@ -724,17 +737,20 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR window->State.MouseX, window->State.MouseY ) ) 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. + /* Set capture so that the window captures all the mouse messages + * + * The mouse is not released from the window until all buttons have + * been released, even if the user presses a button in another window. + * This is consistent with the behavior on X11. */ if ( pressed == GL_TRUE ) - SetCapture ( window->Window.Handle ) ; - else + { + if (!setCaptureActive) + SetCapture ( window->Window.Handle ) ; + setCaptureActive = 1; /* Set to false in WM_CAPTURECHANGED handler */ + } + else if (!GetAsyncKeyState(VK_LBUTTON) && !GetAsyncKeyState(VK_MBUTTON) && !GetAsyncKeyState(VK_RBUTTON)) + /* Make sure all mouse buttons are released before releasing capture */ ReleaseCapture () ; if( ! FETCH_WCB( *window, Mouse ) ) @@ -753,6 +769,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR ); fgState.Modifiers = INVALID_MODIFIERS; + + /* As per docs, should return zero */ + lRet = 0; } break; @@ -850,6 +869,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR break; case WM_CAPTURECHANGED: + if (!lParam || !fgWindowByHandle((HWND)lParam)) + /* Capture released or capture taken by non-FreeGLUT window */ + setCaptureActive = 0; /* User has finished resizing the window, force a redraw */ INVOKE_WCB( *window, Display, ( ) ); lRet = 0; /* Per docs, should return zero */