X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=be8248ecb88fda601a1d03aa4f6ea12c27099add;hb=450b0d2bd03f4d7721fa2fe5f54f38d787accb06;hp=25330e81fb601a889a6355ea254e605e5235626d;hpb=f8a0d455b4ec10096337cee040166bd006e63eef;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index 25330e8..be8248e 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -225,7 +225,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, static unsigned char lControl = 0, rControl = 0, lShift = 0, rShift = 0, lAlt = 0, rAlt = 0; - SFG_Window* window; + SFG_Window *window, *child_window = NULL; PAINTSTRUCT ps; LRESULT lRet = 1; @@ -239,31 +239,39 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, uMsg, wParam, lParam ); */ - /* events only sent to main window. Check if the current window that the mouse - is over is a child window and if so, make sure we call the callback on that - child instead. - */ + /* Some events only sent to main window. Check if the current window that + * the mouse is over is a child window. Below when handling some messages, + * we make sure that we process callbacks on the child window instead. + * This mirrors how GLUT does things. + */ if (window && window->Children.First) { POINT mouse_pos; SFG_WindowHandleType hwnd; + SFG_Window* temp_window; GetCursorPos( &mouse_pos ); ScreenToClient( window->Window.Handle, &mouse_pos ); hwnd = ChildWindowFromPoint(window->Window.Handle, mouse_pos); if (hwnd) /* can be NULL if mouse outside parent by the time we get here */ - window = fgWindowByHandle(hwnd); + { + temp_window = fgWindowByHandle(hwnd); + if (temp_window->Parent) /* Verify we got a child window */ + child_window = temp_window; + } } if ( window ) { + SFG_Window* temp_window = child_window?child_window:window; + fgState.Modifiers = fgPlatformGetModifiers( ); /* Checking for CTRL, ALT, and SHIFT key positions: Key Down! */ if ( !lControl && GetAsyncKeyState ( VK_LCONTROL ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lControl = 1; @@ -271,8 +279,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !rControl && GetAsyncKeyState ( VK_RCONTROL ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rControl = 1; @@ -280,8 +288,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !lShift && GetAsyncKeyState ( VK_LSHIFT ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lShift = 1; @@ -289,8 +297,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !rShift && GetAsyncKeyState ( VK_RSHIFT ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rShift = 1; @@ -298,8 +306,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !lAlt && GetAsyncKeyState ( VK_LMENU ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lAlt = 1; @@ -307,8 +315,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !rAlt && GetAsyncKeyState ( VK_RMENU ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rAlt = 1; @@ -317,8 +325,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* Checking for CTRL, ALT, and SHIFT key positions: Key Up! */ if ( lControl && !GetAsyncKeyState ( VK_LCONTROL ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lControl = 0; @@ -326,8 +334,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( rControl && !GetAsyncKeyState ( VK_RCONTROL ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rControl = 0; @@ -335,8 +343,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( lShift && !GetAsyncKeyState ( VK_LSHIFT ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lShift = 0; @@ -344,8 +352,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( rShift && !GetAsyncKeyState ( VK_RSHIFT ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rShift = 0; @@ -353,8 +361,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( lAlt && !GetAsyncKeyState ( VK_LMENU ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lAlt = 0; @@ -362,8 +370,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( rAlt && !GetAsyncKeyState ( VK_RMENU ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rAlt = 0; @@ -486,27 +494,44 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_SETFOCUS: /* printf("WM_SETFOCUS: %p\n", window ); */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); - UpdateWindow ( hWnd ); + if (child_window) + { + /* If child should have focus instead, set it here. */ + SetFocus(child_window->Window.Handle); + SetActiveWindow( child_window->Window.Handle ); + INVOKE_WCB( *child_window, Entry, ( GLUT_ENTERED ) ); + UpdateWindow ( child_window->Window.Handle ); + } + else + { + SetActiveWindow( window->Window.Handle ); + INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); + } + /* Always request update on main window to be safe */ + UpdateWindow ( hWnd ); + break; case WM_KILLFOCUS: { SFG_Menu* menu = NULL; + 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); /* If we have an open menu, see if the open menu should be closed - when focus was lost because user either switched - application or FreeGLUT window (if one is running multiple - windows). If so, close menu the active menu. + * when focus was lost because user either switched + * application or FreeGLUT window (if one is running multiple + * windows). If so, close menu the active menu. */ if ( fgStructure.Menus.First ) menu = fgGetActiveMenu(); - + if ( menu ) { SFG_Window* wnd = NULL; @@ -518,9 +543,24 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if (!hwnd || !wnd) /* User switched to another application*/ fgDeactivateMenu(menu->ParentWindow); - else if (!wnd->IsMenu && wnd!=menu->ParentWindow) - /* User switched to another FreeGLUT window */ - fgDeactivateMenu(menu->ParentWindow); + else if (!wnd->IsMenu) /* Make sure we don't kill the menu when trying to enter a submenu */ + { + if (wnd!=menu->ParentWindow) + /* User switched to another FreeGLUT window */ + fgDeactivateMenu(menu->ParentWindow); + else + { + /* Check if focus lost because non-client area of + * window was pressed (pressing on client area is + * handled in fgCheckActiveMenu) + */ + POINT mouse_pos; + RECT clientArea = fghGetClientArea(menu->ParentWindow, GL_FALSE); + GetCursorPos(&mouse_pos); + if ( !PtInRect( &clientArea, mouse_pos ) ) + fgDeactivateMenu(menu->ParentWindow); + } + } } } break; @@ -788,6 +828,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, int keypress = -1; POINT mouse_pos ; + if (child_window) + window = child_window; if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) ) break; @@ -882,6 +924,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, int keypress = -1; POINT mouse_pos; + if (child_window) + window = child_window; + /* * Remember the current modifiers state. This is done here in order * to make sure the VK_DELETE keyboard callback is executed properly. @@ -968,6 +1013,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_SYSCHAR: case WM_CHAR: { + if (child_window) + window = child_window; + if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) ) break;