X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=d3041696015bcc06eabc32b0ab63076c5f2e9bf3;hb=065ac95b77b53e025a219da8c7ac31ee2b32dbc5;hp=7cd993e6fceec6d135fb1e3b377ab174110eff87;hpb=fb6675ecf8a5b341385a83563854b54ce58ecbb1;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index 7cd993e..d304169 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -321,37 +321,37 @@ static LRESULT fghWindowProcKeyPress(SFG_Window *window, UINT uMsg, GLboolean ke return 1; } -void fghWindowUnderCursor(SFG_Window *window, SFG_Window **child_window) +static SFG_Window* fghWindowUnderCursor(SFG_Window *window) { /* Check if the current window that the mouse is over is a child window * of the window the message was sent to. Some events only sent to main window, * and when handling some messages, we need to make sure that we process * callbacks on the child window instead. This mirrors how GLUT does things. + * returns either the original window or the found child. */ - if (window && window->Children.First) + if (window && window->Children.First) /* This window has childs */ { - POINT mouse_pos; SFG_WindowHandleType hwnd; - SFG_Window* temp_window; + SFG_Window* child_window; /* Get mouse position at time of message */ - DWORD mouse_pos_Dword = GetMessagePos(); - mouse_pos.x = GET_X_LPARAM(mouse_pos_Dword); - mouse_pos.y = GET_Y_LPARAM(mouse_pos_Dword); + DWORD mouse_pos_dw = GetMessagePos(); + POINT mouse_pos = {GET_X_LPARAM(mouse_pos_dw), GET_Y_LPARAM(mouse_pos_dw)}; ScreenToClient( window->Window.Handle, &mouse_pos ); hwnd = ChildWindowFromPoint(window->Window.Handle, mouse_pos); if (hwnd && hwnd!=window->Window.Handle) /* can be NULL if mouse outside parent by the time we get here, or can be same as parent if we didn't find a child */ { - temp_window = fgWindowByHandle(hwnd); - if (temp_window) /* Verify we got a FreeGLUT window */ + child_window = fgWindowByHandle(hwnd); + if (child_window) /* Verify we got a FreeGLUT window */ { - *child_window = temp_window; /* ChildWindowFromPoint only searches immediate children, so search again to see if actually in grandchild or further descendant */ - fghWindowUnderCursor(temp_window,child_window); + window = fghWindowUnderCursor(child_window); } } } + + return window; } /* @@ -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,51 @@ 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 */ + fgSetCursor ( window, window->State.Cursor ) ; + + /* 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 + /* 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: + { + /* 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); + + 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; @@ -738,9 +774,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR int wheel_number = LOWORD( wParam ); short ticks = ( short )HIWORD( wParam ); - fghWindowUnderCursor(window, &child_window); - if (child_window) - window = child_window; + window = fghWindowUnderCursor(window); fgState.MouseWheelTicks += ticks; if ( abs ( fgState.MouseWheelTicks ) >= WHEEL_DELTA ) @@ -797,28 +831,23 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR case WM_SYSKEYDOWN: case WM_KEYDOWN: { - SFG_Window *child_window = NULL; - fghWindowUnderCursor(window, &child_window); - lRet = fghWindowProcKeyPress(child_window?child_window:window,uMsg,GL_TRUE,wParam,lParam); + window = fghWindowUnderCursor(window); + lRet = fghWindowProcKeyPress(window,uMsg,GL_TRUE,wParam,lParam); } break; case WM_SYSKEYUP: case WM_KEYUP: { - SFG_Window *child_window = NULL; - fghWindowUnderCursor(window, &child_window); - lRet = fghWindowProcKeyPress(child_window?child_window:window,uMsg,GL_FALSE,wParam,lParam); + window = fghWindowUnderCursor(window); + lRet = fghWindowProcKeyPress(window,uMsg,GL_FALSE,wParam,lParam); } break; case WM_SYSCHAR: case WM_CHAR: { - SFG_Window *child_window = NULL; - fghWindowUnderCursor(window, &child_window); - if (child_window) - window = child_window; + window = fghWindowUnderCursor(window); if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) ) break; @@ -835,8 +864,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 */