X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=be8248ecb88fda601a1d03aa4f6ea12c27099add;hb=450b0d2bd03f4d7721fa2fe5f54f38d787accb06;hp=c631a9c9a8556be4c9c1ccf05fd420e7e50f2eab;hpb=9015943b5abecb4caf4b76805d937ecc577edf07;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index c631a9c..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,15 +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 ); */ + /* 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 */ + { + 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; @@ -255,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; @@ -264,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; @@ -273,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; @@ -282,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; @@ -291,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; @@ -301,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; @@ -310,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; @@ -319,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; @@ -328,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; @@ -337,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; @@ -346,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; @@ -470,21 +494,75 @@ 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: -/* printf("WM_KILLFOCUS: %p\n", window ); */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) ); + { + 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( window->IsMenu && - window->ActiveMenu && window->ActiveMenu->IsActive ) - fgUpdateMenuHighlight( window->ActiveMenu ); + /* 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. + */ + if ( fgStructure.Menus.First ) + menu = fgGetActiveMenu(); + if ( menu ) + { + SFG_Window* wnd = NULL; + HWND hwnd = GetFocus(); /* Get window with current focus - NULL for non freeglut windows */ + if (hwnd) + /* See which of our windows it is */ + wnd = fgWindowByHandle(hwnd); + + if (!hwnd || !wnd) + /* User switched to another application*/ + 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; #if 0 @@ -552,7 +630,6 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, fgUpdateMenuHighlight( window->ActiveMenu ); break; } - SetFocus(window->Window.Handle); fgState.Modifiers = fgPlatformGetModifiers( ); @@ -751,6 +828,9 @@ 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; @@ -844,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. @@ -930,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;