From 42858958aa7357b40e7aa29068054a26c020642e Mon Sep 17 00:00:00 2001 From: Diederick Niehorster Date: Fri, 1 Mar 2013 05:53:51 +0000 Subject: [PATCH] implemented somewhat better visibility/windowstatus support, some small cleanup git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1536 7f0cb862-5218-0410-a997-914c9d46530a --- progs/demos/CallbackMaker/CallbackMaker.c | 38 +++++++++----- src/mswin/fg_main_mswin.c | 81 ++++++++++++++++++++++------- src/mswin/fg_window_mswin.c | 2 +- 3 files changed, 88 insertions(+), 33 deletions(-) diff --git a/progs/demos/CallbackMaker/CallbackMaker.c b/progs/demos/CallbackMaker/CallbackMaker.c index 771a6cd..43c31ba 100644 --- a/progs/demos/CallbackMaker/CallbackMaker.c +++ b/progs/demos/CallbackMaker/CallbackMaker.c @@ -25,6 +25,7 @@ int windows[CALLBACKMAKER_N_WINDOWS] = {0}; CALLBACK_2V(reshape,width,height); CALLBACK_2V(position,top,left); CALLBACK_1V(visibility,vis); +CALLBACK_1V(windowStatus,state); CALLBACK_4V(key,key,x,y,mod); CALLBACK_4V(keyup,key,x,y,mod); CALLBACK_4V(special,key,x,y,mod); @@ -122,6 +123,11 @@ Display(void) bitmapPrintf ( "Visibility %d: %d\n", visibility_seq[winIdx], visibility_vis[winIdx] ); } + if ( windowStatus_called[winIdx] ) + { + bitmapPrintf ( "WindowStatus %d: %d\n", windowStatus_seq[winIdx], windowStatus_state[winIdx] ); + } + if ( reshape_called[winIdx] ) { bitmapPrintf ( "Reshape %d: %d %d\n", reshape_seq[winIdx], reshape_width[winIdx], reshape_height[winIdx] ); @@ -233,19 +239,6 @@ Error(const char *fmt, va_list ap) } static void -Visibility(int vis) -{ - int winIdx; - int window = getWindowAndIdx(&winIdx); - printf ( "%6d Window %d Visibility Callback: %d\n", - ++sequence_number, window, vis ) ; - visibility_called[winIdx] = 1 ; - visibility_vis[winIdx] = vis ; - visibility_seq[winIdx] = sequence_number ; - glutPostRedisplay () ; -} - -static void Reshape(int width, int height) { int winIdx; @@ -449,11 +442,28 @@ OverlayDisplay(void) } static void +Visibility(int vis) +{ + int winIdx; + int window = getWindowAndIdx(&winIdx); + printf ( "%6d Window %d Visibility Callback: %d\n", + ++sequence_number, window, vis ) ; + visibility_called[winIdx] = 1 ; + visibility_vis[winIdx] = vis ; + visibility_seq[winIdx] = sequence_number ; + glutPostRedisplay () ; +} + +static void WindowStatus(int state) { - int window = getWindowAndIdx(NULL); + int winIdx; + int window = getWindowAndIdx(&winIdx); printf ( "%6d Window %d WindowStatus Callback: %d\n", ++sequence_number, window, state ) ; + windowStatus_called[winIdx] = 1 ; + windowStatus_state[winIdx] = state ; + windowStatus_seq[winIdx] = sequence_number ; glutPostRedisplay () ; } diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index f00728e..bed1eb8 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -128,6 +128,40 @@ void fgPlatformProcessSingleEvent ( void ) +static void fghUpdateWindowStatus(SFG_Window *window, GLboolean visState) +{ + SFG_Window* child; + + if (window->State.Visible != visState) + { + window->State.Visible = visState; + INVOKE_WCB( *window, WindowStatus, ( visState ? GLUT_FULLY_RETAINED:GLUT_HIDDEN ) ); + } + + /* Also notify children */ + for( child = ( SFG_Window * )window->Children.First; + child; + child = ( SFG_Window * )child->Node.Next ) + { + fghUpdateWindowStatus(child, visState); + } +} + +static void fghNotifyWindowStatus(SFG_Window *window) +{ + SFG_Window* child; + + INVOKE_WCB( *window, WindowStatus, ( window->State.Visible?GLUT_FULLY_RETAINED:GLUT_HIDDEN ) ); + + /* Also notify children */ + for( child = ( SFG_Window * )window->Children.First; + child; + child = ( SFG_Window * )child->Node.Next ) + { + fghNotifyWindowStatus(child); + } +} + void fgPlatformMainLoopPreliminaryWork ( void ) { SFG_Window *window = (SFG_Window *)fgStructure.Windows.First ; @@ -147,7 +181,7 @@ void fgPlatformMainLoopPreliminaryWork ( void ) { SFG_Window *current_window = fgStructure.CurrentWindow ; - INVOKE_WCB( *window, WindowStatus, ( window->State.Visible?GLUT_FULLY_RETAINED:GLUT_HIDDEN ) ); + fghNotifyWindowStatus(window); fgSetWindow( current_window ); } @@ -466,6 +500,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR break; case WM_SIZE: + //printf("WM_SIZE (ID: %i): wParam: %i, new size: %ix%i \n",window->ID,wParam,LOWORD(lParam),HIWORD(lParam)); /* * If the window is visible, then it is the user manually resizing it. * If it is not, then it is the system sending us a dummy resize with @@ -488,28 +523,35 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR window->State.NeedToResize = GL_TRUE; } + /* according to docs, should return 0 */ + lRet = 0; break; case WM_MOVE: { SFG_Window* saved_window = fgStructure.CurrentWindow; RECT windowRect; - GetWindowRect( window->Window.Handle, &windowRect ); - - if (window->Parent) + + /* Check window visible, we don't want to call the position callback when the user minimized the window */ + if (window->State.Visible) { - /* For child window, we should return relative to upper-left - * of parent's client area. - */ - POINT topleft = {windowRect.left,windowRect.top}; - - ScreenToClient(window->Parent->Window.Handle,&topleft); - windowRect.left = topleft.x; - windowRect.top = topleft.y; - } + GetWindowRect( window->Window.Handle, &windowRect ); + + if (window->Parent) + { + /* For child window, we should return relative to upper-left + * of parent's client area. + */ + POINT topleft = {windowRect.left,windowRect.top}; - INVOKE_WCB( *window, Position, ( windowRect.left, windowRect.top ) ); - fgSetWindow(saved_window); + ScreenToClient(window->Parent->Window.Handle,&topleft); + windowRect.left = topleft.x; + windowRect.top = topleft.y; + } + + INVOKE_WCB( *window, Position, ( windowRect.left, windowRect.top ) ); + fgSetWindow(saved_window); + } } break; @@ -535,7 +577,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR #if 0 case WM_ACTIVATE: - //printf("WM_ACTIVATE: %x %d %d\n",lParam, HIWORD(wParam), LOWORD(wParam)); + //printf("WM_ACTIVATE: %x (ID: %i) %d %d\n",lParam, window->ID, HIWORD(wParam), LOWORD(wParam)); if (LOWORD(wParam) != WA_INACTIVE) { /* printf("WM_ACTIVATE: fgSetCursor( %p, %d)\n", window, @@ -596,7 +638,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR break; case WM_SHOWWINDOW: - window->State.Visible = GL_TRUE; + //printf("WM_SHOWWINDOW\n"); + fghUpdateWindowStatus(window, GL_TRUE); window->State.Redisplay = GL_TRUE; break; @@ -605,6 +648,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR PAINTSTRUCT ps; /* Turn on the visibility in case it was turned off somehow */ window->State.Visible = GL_TRUE; + InvalidateRect( hWnd, NULL, GL_FALSE ); /* Make sure whole window is repainted. Bit of a hack, but a safe one from what google turns up... */ BeginPaint( hWnd, &ps ); fghRedrawWindow( window ); @@ -939,7 +983,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR case SC_MINIMIZE : /* User has clicked on the "-" to minimize the window */ /* Turn off the visibility */ - window->State.Visible = GL_FALSE ; + fghUpdateWindowStatus(window, GL_FALSE); break ; @@ -972,6 +1016,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR break ; case SC_RESTORE : + fghUpdateWindowStatus(window, GL_TRUE); break ; case SC_TASKLIST : diff --git a/src/mswin/fg_window_mswin.c b/src/mswin/fg_window_mswin.c index ae30001..ea2dc15 100644 --- a/src/mswin/fg_window_mswin.c +++ b/src/mswin/fg_window_mswin.c @@ -751,7 +751,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, - fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); + fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOWNORMAL ); #endif /* defined(_WIN32_WCE) */ UpdateWindow( window->Window.Handle ); -- 1.7.10.4