X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=be412baaa6dfed0f93b3b3075b6caeabc7f6e629;hb=e5f1f71e1417e64b104f9a82987665a75b7a9585;hp=baf4b3b0dbb5acc85445c8e039d1fc5d0365b812;hpb=c21722a39780abcd692cb01978fbf57fc7d06a45;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index baf4b3b..be412ba 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -128,26 +128,61 @@ 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 set visibility state for 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 ; /* * Processing before the main loop: If there is a window which is open and - * which has a visibility callback, call it. I know this is an ugly hack, - * but I'm not sure what else to do about it. Ideally we should leave - * something uninitialized in the create window code and initialize it in - * the main loop, and have that initialization create a "WM_ACTIVATE" - * message. Then we would put the visibility callback code in the - * "case WM_ACTIVATE" block below. - John Fay -- 10/24/02 + * which has a visibility/windowStatus callback, call it to inform the client + * code that the window is visible. I know this is an ugly hack, + * but I'm not sure what else to do about it. Depending on WM_ACTIVATE would + * not work as not all windows get this when you are opening multiple before + * the mainloop starts. WM_SHOWWINDOW looked like an interesting candidate, but + * it is generated and processed before glutCreate(Sub)Window returns, so no + * callback can yet be set on the window. */ while( window ) { - if ( FETCH_WCB( *window, Visibility ) ) + if ( FETCH_WCB( *window, WindowStatus ) ) { SFG_Window *current_window = fgStructure.CurrentWindow ; - INVOKE_WCB( *window, Visibility, ( window->State.Visible ) ); + fghNotifyWindowStatus(window); fgSetWindow( current_window ); } @@ -466,6 +501,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 +524,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 +578,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 +639,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 +649,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 ); @@ -624,17 +669,6 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR */ return 0; - case WM_CANCELMODE: - /* - * The window manager sends this message when it detects a change - * that requires that an application cancel any modal state it has - * entered. If we've called SetCapture in the mouse button handler, - * call ReleaseCapture. - */ - if (setCaptureActive) - ReleaseCapture(); - break; - case WM_MOUSEMOVE: { #if defined(_WIN32_WCE) @@ -883,8 +917,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR if (!lParam || !fgWindowByHandle((HWND)lParam)) /* Capture released or capture taken by non-FreeGLUT window */ setCaptureActive = 0; - /* User has finished resizing the window, force a redraw */ - INVOKE_WCB( *window, Display, ( ) ); + /* Docs advise a redraw */ + InvalidateRect( hWnd, NULL, GL_FALSE ); + UpdateWindow(hWnd); lRet = 0; /* Per docs, should return zero */ break; @@ -949,7 +984,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 ; @@ -982,6 +1017,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR break ; case SC_RESTORE : + fghUpdateWindowStatus(window, GL_TRUE); break ; case SC_TASKLIST :