X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_main.c;h=5fbce0c7ee3053cceffc5527fd695bff8191fb70;hb=f3714029b481bc31a1876e0d8ae3aa450eaf7924;hp=55e033a2788c0ede42f15819854a7915975e282c;hpb=fffd18193541999b2b5c00905dea0f1effa0ec07;p=freeglut diff --git a/src/freeglut_main.c b/src/freeglut_main.c index 55e033a..5fbce0c 100644 --- a/src/freeglut_main.c +++ b/src/freeglut_main.c @@ -126,15 +126,19 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle, ); } -#endif - - if( !( FETCH_WCB( *window, Reshape ) ) ) + /* + * XXX Should update {window->State.OldWidth, window->State.OldHeight} + * XXX to keep in lockstep with UNIX_X11 code. + */ + if( FETCH_WCB( *window, Reshape ) ) + INVOKE_WCB( *window, Reshape, ( width, height ) ); + else { fgSetWindow( window ); glViewport( 0, 0, width, height ); } - else - INVOKE_WCB( *window, Reshape, ( width, height ) ); + +#endif /* * Force a window redraw. In Windows at least this is only a partial @@ -191,6 +195,21 @@ static void fghcbDisplayWindow( SFG_Window *window, if( window->State.Redisplay && window->State.Visible ) { + /* + * XXX Resizing should *not* depend upon whether there + * XXX is a pending redisplay flag, as far as I can tell. + * XXX + * XXX Note, too, that the {NeedToResize} flag is a little + * XXX fuzzy in its meaning, since for WIN32, this also + * XXX means "we need to tell the application that the window has + * XXX changed size", while in X11, it only means "we need + * XXX to ask the window system to resize the window. + * XXX Splitting the flag's meaning might be desirable, but + * XXX that could complicate the code more. (On X11, the + * XXX user callback is called as soon as the event is + * XXX discovered, but resizing the window is postponed + * XXX until after other events.) + */ if( window->State.NeedToResize ) { SFG_Window *current_window = fgStructure.Window; @@ -423,10 +442,12 @@ static int fgHavePendingRedisplays (void) static long fgNextTimer( void ) { long ret = INT_MAX; - SFG_Timer *timer; + SFG_Timer *timer = fgState.Timers.First; - if( (timer = fgState.Timers.First) ) + if( timer ) ret = timer->TriggerTime - fgElapsedTime(); + if( ret < 0 ) + ret = 0; return ret; } @@ -452,7 +473,7 @@ static void fgSleepForEvents( void ) msec = fgNextTimer( ); if( fgHaveJoystick( ) ) msec = MIN( msec, 10 ); - + wait.tv_sec = msec / 1000; wait.tv_usec = (msec % 1000) * 1000; err = select( socket+1, &fdset, NULL, NULL, &wait ); @@ -542,19 +563,38 @@ void FGAPIENTRY glutMainLoopEvent( void ) * (in freeglut only) will not get an initial reshape event, * which can break things. * - * XXX NOTE that it is possible that you will more than one Reshape - * XXX event for your top-level window, but something like this - * XXX appears to be required for compatbility. - * * GLUT presumably does this because it generally tries to treat * sub-windows the same as windows. + * + * XXX Technically, GETWINDOW( xconfigure ) and + * XXX {event.xconfigure} may not be legit ways to get at + * XXX data for CreateNotify events. In practice, the data + * XXX is in a union which is laid out much the same either + * XXX way. But if you want to split hairs, this isn't legit, + * XXX and we should instead duplicate some code. */ case CreateNotify: case ConfigureNotify: GETWINDOW( xconfigure ); - window->State.NeedToResize = GL_TRUE ; - window->State.Width = event.xconfigure.width ; - window->State.Height = event.xconfigure.height; + { + int width = event.xconfigure.width; + int height = event.xconfigure.height; + + if( ( width != window->State.OldWidth ) || + ( height != window->State.OldHeight ) ) + { + window->State.OldWidth = width; + window->State.OldHeight = height; + if( FETCH_WCB( *window, Reshape ) ) + INVOKE_WCB( *window, Reshape, ( width, height ) ); + else + { + fgSetWindow( window ); + glViewport( 0, 0, width, height ); + } + glutPostRedisplay( ); + } + } break; case DestroyNotify: @@ -568,10 +608,15 @@ void FGAPIENTRY glutMainLoopEvent( void ) case Expose: /* * We are too dumb to process partial exposes... + * * XXX Well, we could do it. However, it seems to only * XXX be potentially useful for single-buffered (since * XXX double-buffered does not respect viewport when we * XXX do a buffer-swap). + * + * XXX GETWINDOW( xexpose ); + * XXX fgSetWindow( window ); + * XXX glutPostRedisplay( ); */ if( event.xexpose.count == 0 ) fghRedrawWindowByHandle( event.xexpose.window ); @@ -596,6 +641,9 @@ void FGAPIENTRY glutMainLoopEvent( void ) case VisibilityNotify: { GETWINDOW( xvisibility ); + /* + * XXX INVOKE_WCB() does this check for us. + */ if( ! FETCH_WCB( *window, WindowStatus ) ) break; fgSetWindow( window ); @@ -663,7 +711,9 @@ void FGAPIENTRY glutMainLoopEvent( void ) /* * XXX For more than 5 buttons, just check {event.xmotion.state}, - * XXX rather than a host of bit-masks? + * XXX rather than a host of bit-masks? Or maybe we need to + * XXX track ButtonPress/ButtonRelease events in our own + * XXX bit-mask? */ #define BUTTON_MASK \ ( Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) @@ -733,7 +783,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) window->ActiveMenu->Window->State.MouseY = event.xbutton.y_root - window->ActiveMenu->Y; } - + /* In the menu, invoke the callback and deactivate the menu*/ if( fgCheckActiveMenu( window->ActiveMenu->Window, window->ActiveMenu ) ) @@ -760,12 +810,19 @@ void FGAPIENTRY glutMainLoopEvent( void ) else if( pressed ) /* * Outside the menu, deactivate if it's a downclick + * * XXX This isn't enough. A downclick outside of * XXX the interior of our freeglut windows should also * XXX deactivate the menu. This is more complicated. */ fgDeactivateMenu( window->ActiveMenu->ParentWindow ); - + + /* + * XXX Why does an active menu require a redisplay at + * XXX this point? If this can come out cleanly, then + * XXX it probably should do so; if not, a comment should + * XXX explain it. + */ window->State.Redisplay = GL_TRUE; break; } @@ -778,6 +835,9 @@ void FGAPIENTRY glutMainLoopEvent( void ) ( window->Menu[ button ] ) && pressed ) { + /* + * XXX Posting a requisite Redisplay seems bogus. + */ window->State.Redisplay = GL_TRUE; fgSetWindow( window ); fgActivateMenu( window, button ); @@ -797,7 +857,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) /* * Finally execute the mouse or mouse wheel callback * - * XXX Use a symbolic constant, *not* "4"! + * XXX Use a symbolic constant, *not* "4"! ("3, sire!") */ if( ( button < 3 ) || ( ! FETCH_WCB( *window, MouseWheel ) ) ) INVOKE_WCB( *window, Mouse, ( button, @@ -1380,7 +1440,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, break; } - if ( window->Menu[ button ] && pressed ) + if( window->Menu[ button ] && pressed ) { window->State.Redisplay = GL_TRUE; fgSetWindow( window );