X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_menu_mswin.c;h=78ea70788c9c84d6fd6e6feb4d06604808bd49fe;hb=b1ed93dd348f7b8f3bd2c75474f5d4151d502f1f;hp=3d8369378a87d3e8e96333800def0ed244c4687e;hpb=637e1260edb9068591665330c32407549ca36535;p=freeglut diff --git a/src/mswin/fg_menu_mswin.c b/src/mswin/fg_menu_mswin.c index 3d83693..78ea707 100644 --- a/src/mswin/fg_menu_mswin.c +++ b/src/mswin/fg_menu_mswin.c @@ -1,5 +1,5 @@ /* - * freeglut_menu_mswin.c + * fg_menu_mswin.c * * The Windows-specific mouse cursor related stuff. * @@ -29,7 +29,9 @@ #include #include "../fg_internal.h" -extern void fghGetClientArea( RECT *clientRect, const SFG_Window *window, BOOL wantPosOutside ); + +extern void fgEnumMenus( FGCBMenuEnumerator enumCallback, SFG_Enumerator* enumerator ); + GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y ) @@ -38,46 +40,57 @@ GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y ) *y = glutGet ( GLUT_SCREEN_HEIGHT ); } -void fgPlatformCheckMenuDeactivate() +static void fghcbIsActiveMenu(SFG_Menu *menu, + SFG_Enumerator *enumerator) +{ + if (enumerator->found) + return; + + /* Check the menu's active and the one we are searching for. */ + if (menu->IsActive && menu->Window->Window.Handle==(HWND)enumerator->data) + { + enumerator->found = GL_TRUE; + enumerator->data = (void*) menu; + return; + } +} + +void fgPlatformCheckMenuDeactivate(HWND newFocusWnd) { - /* 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. + /* User/system switched application focus. + * If we have an open menu, close it. + * If the window that got focus is an active + * menu window, don't do anything. This occurs + * as it is sadly necessary to do an activating + * ShowWindow() for the menu to pop up over the + * gamemode window. + * If the window that got focus is the gamemode + * window, the menus pop under it. Bring them + * back in view in this special case. */ SFG_Menu* menu = NULL; + SFG_Enumerator enumerator; - if ( fgStructure.Menus.First ) - menu = fgGetActiveMenu(); - - if ( menu ) + if ( fgState.ActiveMenus ) { - 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 */ + /* see if there is an active menu whose window matches the one that got focus */ + enumerator.found = GL_FALSE; + enumerator.data = (void*) newFocusWnd; + fgEnumMenus(fghcbIsActiveMenu, &enumerator); + if (enumerator.found) + menu = (SFG_Menu*) enumerator.data; + + if ( !menu ) { - if (wnd!=menu->ParentWindow) - /* User switched to another FreeGLUT window */ - fgDeactivateMenu(menu->ParentWindow); - else + /* window that got focus was not one of the active menus. That means we'll + * close the active menu's unless the window that got focus was their parent */ + menu = fgGetActiveMenu(); + + if (newFocusWnd != menu->ParentWindow->Window.Handle) { - /* 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(&clientArea,menu->ParentWindow, GL_FALSE); - GetCursorPos(&mouse_pos); - if ( !PtInRect( &clientArea, mouse_pos ) ) - fgDeactivateMenu(menu->ParentWindow); + /* focus shifted to another window than the menu's parent, close menus */ + fgDeactivateMenu(menu->ParentWindow); + return; } } } @@ -93,3 +106,8 @@ int FGAPIENTRY __glutCreateMenuWithExit( void(* callback)( int ), void (__cdecl return glutCreateMenu( callback ); } +int FGAPIENTRY __glutCreateMenuUcallWithExit(void(*callback)(int, void*), void(__cdecl *exit_function)(int), void* user_data) +{ + __glutExitFunc = exit_function; + return glutCreateMenuUcall(callback, user_data); +}