X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_main.c;h=85bab79d8ae6b4ffaccd542b2a109b95ea90fe26;hb=99532b98a9b24cbf41fdf83789f74fef2dbc8b6c;hp=3982d4b4b26e14ac0037d7d87ba66300bc3e5d31;hpb=5d724da03c1b5988304888c17c5eba8a40c0a529;p=freeglut diff --git a/src/freeglut_main.c b/src/freeglut_main.c index 3982d4b..85bab79 100644 --- a/src/freeglut_main.c +++ b/src/freeglut_main.c @@ -83,12 +83,27 @@ static void fghRedrawWindowByHandle { SFG_Window* window = fgWindowByHandle( handle ); freeglut_return_if_fail( window != NULL ); + + /* + * XXX Other than clearing the Redisplay flag or not, + * XXX we may as well rely on the INVOK_WCB() doing this + * XXX pointer-check. + * XXX + * XXX If we do not invoke the display because the pointer + * XXX is not defined (should never happen, really), then + * XXX we may enter an infinite busy-loop trying to update + * XXX the window. Similarly, if we skip because the window + * XXX is not visible. However, if the window becomes visible + * XXX at a later time, the window should get its callback + * XXX invoked. I would recommend removing the first check, + * XXX and making the second check only affect whether the + * XXX callback is invoked---but always clear the flag, if + * XXX the {window} pointer is defined. + */ freeglut_return_if_fail( FETCH_WCB( *window, Display ) ); - freeglut_return_if_fail( window->State.Visible == TRUE ); + freeglut_return_if_fail( window->State.Visible ); - /* fgSetWindow( window ); */ - window->State.Redisplay = FALSE; - /* window->Callbacks.Display( ); */ + window->State.Redisplay = GL_FALSE; INVOKE_WCB( *window, Display, ( ) ); } @@ -109,13 +124,6 @@ static void fghReshapeWindowByHandle SFG_Window* window = fgWindowByHandle( handle ); freeglut_return_if_fail( window != NULL ); - /* - * fgSetWindow( window ); - * if( window->Callbacks.Reshape != NULL ) - * window->Callbacks.Reshape( width, height ); - * else - * glViewport( 0, 0, width, height ); - */ if( !( FETCH_WCB( *window, Reshape ) ) ) { fgSetWindow( window ); @@ -131,7 +139,7 @@ static void fghReshapeWindowByHandle * But without this we get this bad behaviour whenever we resize the * window. */ - window->State.Redisplay = TRUE; + window->State.Redisplay = GL_TRUE; if( window->IsMenu ) fgSetWindow( current_window ); @@ -143,15 +151,22 @@ static void fghReshapeWindowByHandle static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) { #if TARGET_HOST_UNIX_X11 + /* + * XXX Do we need/want to check the callback pointer here? + * XXX INVOKE_WCB() will check for us. Arguably, the + * XXX Redisplay status flag should be cleared regardless + * XXX of any concern but that {window} is a valid pointer + * XXX (which this function is assuming anyway). + * XXX Especially since old GLUT wouldn't even enter its main + * XXX loop if you didn't have a display callback defined... + */ if( ( FETCH_WCB( *window, Display ) ) && - ( window->State.Redisplay == TRUE ) && - ( window->State.Visible == TRUE ) ) + window->State.Redisplay && + window->State.Visible ) { - SFG_Window *current_window = fgStructure.Window ; + SFG_Window *current_window = fgStructure.Window; - /* fgSetWindow( window ); */ - window->State.Redisplay = FALSE; - /* window->Callbacks.Display( ); */ + window->State.Redisplay = GL_FALSE; INVOKE_WCB( *window, Display, ( ) ); fgSetWindow( current_window ); } @@ -170,15 +185,18 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) glutGet( GLUT_WINDOW_HEIGHT ) ); - window->State.NeedToResize = FALSE; + window->State.NeedToResize = GL_FALSE; fgSetWindow ( current_window ); } + /* + * XXX See above comment about the Redisplay flag... + */ if( ( FETCH_WCB( *window, Display ) ) && - ( window->State.Redisplay == TRUE ) && - ( window->State.Visible == TRUE ) ) + window->State.Redisplay && + window->State.Visible ) { - window->State.Redisplay = FALSE; + window->State.Redisplay = GL_FALSE; RedrawWindow( window->Window.Handle, NULL, NULL, @@ -198,8 +216,8 @@ static void fghDisplayAll( void ) { SFG_Enumerator enumerator; - enumerator.found = FALSE; - enumerator.data = NULL; + enumerator.found = GL_FALSE; + enumerator.data = NULL; fgEnumWindows( fghcbDisplayWindow, &enumerator ); } @@ -229,8 +247,8 @@ static void fghCheckJoystickPolls( void ) { SFG_Enumerator enumerator; - enumerator.found = FALSE; - enumerator.data = NULL; + enumerator.found = GL_FALSE; + enumerator.data = NULL; fgEnumWindows( fghcbCheckJoystickPolls, &enumerator ); } @@ -278,19 +296,31 @@ static void fghCheckTimers( void ) */ long fgElapsedTime( void ) { + if (fgState.Time.Set) + { #if TARGET_HOST_UNIX_X11 - struct timeval now; - long elapsed; + struct timeval now; + long elapsed; - gettimeofday( &now, NULL ); + gettimeofday( &now, NULL ); - elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000; - elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000; + elapsed = ( now.tv_usec - fgState.Time.Value.tv_usec ) / 1000; + elapsed += ( now.tv_sec - fgState.Time.Value.tv_sec ) * 1000; - return elapsed; + return elapsed; +#elif TARGET_HOST_WIN32 + return timeGetTime( ) - fgState.Time.Value; +#endif + } + else + { +#if TARGET_HOST_UNIX_X11 + gettimeofday( &fgState.Time.Value, NULL ); #elif TARGET_HOST_WIN32 - return timeGetTime() - fgState.Time.Value; + fgState.Time.Value = timeGetTime( ); #endif + fgState.Time.Set = GL_TRUE; + } } /* @@ -302,14 +332,17 @@ void fgError( const char *fmt, ... ) va_start( ap, fmt ); - fprintf( stderr, "freeglut "); + fprintf( stderr, "freeglut " ); if( fgState.ProgramName ) - fprintf (stderr, "(%s): ", fgState.ProgramName); + fprintf( stderr, "(%s): ", fgState.ProgramName ); vfprintf( stderr, fmt, ap ); fprintf( stderr, "\n" ); va_end( ap ); + if ( fgState.Initialised ) + fgDeinitialize( ); + exit( 1 ); } @@ -319,7 +352,7 @@ void fgWarning( const char *fmt, ... ) va_start( ap, fmt ); - fprintf( stderr, "freeglut "); + fprintf( stderr, "freeglut " ); if( fgState.ProgramName ) fprintf( stderr, "(%s): ", fgState.ProgramName ); vfprintf( stderr, fmt, ap ); @@ -348,11 +381,11 @@ void fgWarning( const char *fmt, ... ) * an opaque wall. * */ -static void fgCheckJoystickCallback( SFG_Window* w, SFG_Enumerator* e) +static void fgCheckJoystickCallback( SFG_Window* w, SFG_Enumerator* e ) { if( FETCH_WCB( *w, Joystick ) ) { - e->found = TRUE; + e->found = GL_TRUE; e->data = w; } fgEnumSubWindows( w, fgCheckJoystickCallback, e ); @@ -360,24 +393,24 @@ static void fgCheckJoystickCallback( SFG_Window* w, SFG_Enumerator* e) static int fgHaveJoystick( void ) { SFG_Enumerator enumerator; - enumerator.found = FALSE; + enumerator.found = GL_FALSE; enumerator.data = NULL; fgEnumWindows( fgCheckJoystickCallback, &enumerator ); return !!enumerator.data; } -static void fgHavePendingRedisplaysCallback( SFG_Window* w, SFG_Enumerator* e) +static void fgHavePendingRedisplaysCallback( SFG_Window* w, SFG_Enumerator* e ) { if( w->State.Redisplay ) { - e->found = TRUE; + e->found = GL_TRUE; e->data = w; } fgEnumSubWindows( w, fgHavePendingRedisplaysCallback, e ); } -static int fgHavePendingRedisplays (void) +static int fgHavePendingRedisplays( void ) { SFG_Enumerator enumerator; - enumerator.found = FALSE; + enumerator.found = GL_FALSE; enumerator.data = NULL; fgEnumWindows( fgHavePendingRedisplaysCallback, &enumerator ); return !!enumerator.data; @@ -394,14 +427,14 @@ static int fgHaveTimers( void ) */ static long fgNextTimer( void ) { - long now = fgElapsedTime(); + long now = fgElapsedTime( ); long ret = INT_MAX; SFG_Timer *timer; - for( timer = (SFG_Timer *)fgState.Timers.First; + for( timer = ( SFG_Timer * )fgState.Timers.First; timer; - timer = (SFG_Timer *)timer->Node.Next ) - ret = MIN( ret, MAX( 0, (timer->TriggerTime) - now ) ); + timer = ( SFG_Timer * )timer->Node.Next ) + ret = MIN( ret, MAX( 0, timer->TriggerTime - now ) ); return ret; } @@ -428,12 +461,12 @@ static void fgSleepForEvents( void ) if( fgHaveJoystick( ) ) msec = MIN( msec, 10 ); - wait.tv_sec = msec / 1000; - wait.tv_usec = (msec % 1000) * 1000; + wait.tv_sec = msec / 1000; + wait.tv_usec = ( msec % 1000 ) * 1000; err = select( socket+1, &fdset, NULL, NULL, &wait ); if( -1 == err ) - printf( "freeglut select() error: %d\n", errno ); + fgWarning( "freeglut select() error: %d\n", errno ); #elif TARGET_HOST_WIN32 #endif @@ -490,14 +523,6 @@ void FGAPIENTRY glutMainLoopEvent( void ) switch( event.type ) { - case DestroyNotify: - /* - * This is sent to confirm the XDestroyWindow call. - * XXX WHY is this commented out? Should we re-enable it? - */ - /* fgAddToWindowDestroyList ( window, FALSE ); */ - break; - case ClientMessage: /* * Destroy the window when the WM_DELETE_WINDOW message arrives @@ -506,31 +531,11 @@ void FGAPIENTRY glutMainLoopEvent( void ) { GETWINDOW( xclient ); - fgCloseWindow ( window ) ; - fgAddToWindowDestroyList ( window, FALSE ); + fgCloseWindow ( window ); + fgAddToWindowDestroyList ( window, GL_FALSE ); } break; - case MapNotify: - case UnmapNotify: - /* - * If we never do anything with this, can we just not ask to - * get these messages? - */ - break; - - 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). - */ - if( event.xexpose.count == 0 ) - fghRedrawWindowByHandle( event.xexpose.window ); - break; - /* * CreateNotify causes a configure-event so that sub-windows are * handled compatibly with GLUT. Otherwise, your sub-windows @@ -553,6 +558,34 @@ void FGAPIENTRY glutMainLoopEvent( void ) ); break; + case DestroyNotify: + /* + * This is sent to confirm the XDestroyWindow call. + * XXX WHY is this commented out? Should we re-enable it? + */ + /* fgAddToWindowDestroyList ( window, GL_FALSE ); */ + break; + + 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). + */ + if( event.xexpose.count == 0 ) + fghRedrawWindowByHandle( event.xexpose.window ); + break; + + case MapNotify: + case UnmapNotify: + /* + * If we never do anything with this, can we just not ask to + * get these messages? + */ + break; + case MappingNotify: /* * Have the client's keyboard knowledge updated (xlib.ps, @@ -578,18 +611,18 @@ void FGAPIENTRY glutMainLoopEvent( void ) { case VisibilityUnobscured: INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) ); - window->State.Visible = TRUE; + window->State.Visible = GL_TRUE; break; case VisibilityPartiallyObscured: INVOKE_WCB( *window, WindowStatus, ( GLUT_PARTIALLY_RETAINED ) ); - window->State.Visible = TRUE; + window->State.Visible = GL_TRUE; break; case VisibilityFullyObscured: INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_COVERED ) ); - window->State.Visible = FALSE; + window->State.Visible = GL_FALSE; break; default: @@ -601,34 +634,13 @@ void FGAPIENTRY glutMainLoopEvent( void ) break; case EnterNotify: - { - GETWINDOW( xcrossing ); - GETMOUSE( xcrossing ); - /* - * if( window->Callbacks.Entry ) - * { - * fgSetWindow( window ) ; - * window->Callbacks.Entry( GLUT_ENTERED ); - * } - */ - INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); - } - break; - /* XXX Combine EnterNotify and LeaveNotify */ case LeaveNotify: - { GETWINDOW( xcrossing ); GETMOUSE( xcrossing ); - /* - * if( window->Callbacks.Entry ) - * { - * fgSetWindow( window ) ; - * window->Callbacks.Entry( GLUT_LEFT ); - * } - */ - INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) ); - } - break; + INVOKE_WCB( *window, Entry, ( ( EnterNotify == event.type ) ? + GLUT_ENTERED : + GLUT_LEFT ) ); + break; case MotionNotify: { @@ -644,8 +656,8 @@ void FGAPIENTRY glutMainLoopEvent( void ) window->ActiveMenu->Window->State.MouseY = event.xmotion.y_root - window->ActiveMenu->Y; } - window->ActiveMenu->Window->State.Redisplay = TRUE ; - fgSetWindow( window->ActiveMenu->ParentWindow ) ; + window->ActiveMenu->Window->State.Redisplay = GL_TRUE; + fgSetWindow( window->ActiveMenu->ParentWindow ); break; } @@ -654,51 +666,25 @@ void FGAPIENTRY glutMainLoopEvent( void ) * XXX For more than 5 buttons, just check {event.xmotion.state}, * XXX rather than a host of bit-masks? */ - if( (event.xmotion.state & Button1Mask) || - (event.xmotion.state & Button2Mask) || - (event.xmotion.state & Button3Mask) || - (event.xmotion.state & Button4Mask) || - (event.xmotion.state & Button5Mask) ) - { - /* - * A mouse button was pressed during the movement... - * Is there a motion callback hooked to the window? - */ - /* - * if( window->Callbacks.Motion ) - * { - * fgSetWindow ( window ) ; - * window->Callbacks.Motion( event.xmotion.x, - * event.xmotion.y ); - * } - */ +#define BUTTON_MASK \ + ( Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) + if( event.xmotion.state & BUTTON_MASK ) INVOKE_WCB( *window, Motion, ( event.xmotion.x, - event.xmotion.y ) ); - } + event.xmotion.y ) ); else - { - /* - * if( window->Callbacks.Passive ) - * { - * fgSetWindow( window ); - * window->Callbacks.Passive( event.xmotion.x, - * event.xmotion.y ); - * } - */ INVOKE_WCB( *window, Passive, ( event.xmotion.x, - event.xmotion.y ) ); - } + event.xmotion.y ) ); } break; case ButtonRelease: case ButtonPress: { - GLboolean pressed = TRUE; + GLboolean pressed = GL_TRUE; int button; if( event.type == ButtonRelease ) - pressed = FALSE ; + pressed = GL_FALSE; /* * A mouse button has been pressed or released. Traditionally, @@ -717,6 +703,10 @@ void FGAPIENTRY glutMainLoopEvent( void ) button = event.xbutton.button - 1; /* + * XXX This comment is replicated in the WIN32 section and + * XXX maybe also in the menu code. Can we move the info + * XXX to one central place and *reference* it from here? + * * Do not execute the application's mouse callback if a menu * is hooked to this button. In that case an appropriate * private call should be generated. @@ -747,7 +737,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) /* In the menu, invoke the callback and deactivate the menu*/ if( fgCheckActiveMenu( window->ActiveMenu->Window, - window->ActiveMenu ) == TRUE ) + window->ActiveMenu ) ) { /* * Save the current window and menu and set the current @@ -777,7 +767,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) */ fgDeactivateMenu( window->ActiveMenu->ParentWindow ); - window->State.Redisplay = TRUE; + window->State.Redisplay = GL_TRUE; break; } @@ -785,11 +775,11 @@ void FGAPIENTRY glutMainLoopEvent( void ) * No active menu, let's check whether we need to activate one. */ if( ( 0 <= button ) && - ( 2 >= button ) && + ( FREEGLUT_MAX_MENUS > button ) && ( window->Menu[ button ] ) && pressed ) { - window->State.Redisplay = TRUE; + window->State.Redisplay = GL_TRUE; fgSetWindow( window ); fgActivateMenu( window, button ); break; @@ -803,35 +793,22 @@ void FGAPIENTRY glutMainLoopEvent( void ) ! FETCH_WCB( *window, MouseWheel ) ) break; - /* fgSetWindow( window ); */ - /* * XXX Why don't we use {window}? Other code here does... */ - fgStructure.Window->State.Modifiers = fgGetXModifiers( &event ); + fgState.Modifiers = fgGetXModifiers( &event ); /* * Finally execute the mouse or mouse wheel callback * * XXX Use a symbolic constant, *not* "4"! */ - if( ( button < 4 ) || ( ! FETCH_WCB( *window, MouseWheel ) ) ) - { - /* - * if( window->Callbacks.Mouse ) - * fgStructure.Window->Callbacks.Mouse( - * button, - * pressed ? GLUT_DOWN : GLUT_UP, - * event.xbutton.x, - * event.xbutton.y - * ); - */ + if( ( button < 3 ) || ( ! FETCH_WCB( *window, MouseWheel ) ) ) INVOKE_WCB( *window, Mouse, ( button, pressed ? GLUT_DOWN : GLUT_UP, event.xbutton.x, event.xbutton.y ) ); - } else { /* @@ -842,19 +819,15 @@ void FGAPIENTRY glutMainLoopEvent( void ) * XXX since the order and numbering isn't certain * XXX See XFree86 configuration docs (even back in the * XXX 3.x days, and especially with 4.x). + * + * XXX Note that {button} has already been decremeted + * XXX in mapping from X button numbering to GLUT. */ - int wheel_number = (button - 4) / 2; - int direction = (button & 1)*2 - 1; + int wheel_number = ( button - 3 ) / 2; + int direction = -1; + if( button % 2 ) + direction = 1; - /* - * if( pressed ) - * fgStructure.Window->Callbacks.MouseWheel( - * wheel_number, - * direction, - * event.xbutton.x, - * event.xbutton.y - * ); - */ if( pressed ) INVOKE_WCB( *window, MouseWheel, ( wheel_number, direction, @@ -866,7 +839,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) /* * Trash the modifiers state */ - fgStructure.Window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } break; @@ -904,7 +877,8 @@ void FGAPIENTRY glutMainLoopEvent( void ) * Check for the ASCII/KeySym codes associated with the event: */ len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode), - &keySym, &composeStatus ); + &keySym, &composeStatus + ); /* * GLUT API tells us to have two separate callbacks... @@ -917,10 +891,11 @@ void FGAPIENTRY glutMainLoopEvent( void ) if( keyboard_cb ) { fgSetWindow( window ); - window->State.Modifiers = fgGetXModifiers( &event ); + fgState.Modifiers = fgGetXModifiers( &event ); keyboard_cb( asciiCode[ 0 ], - event.xkey.x, event.xkey.y ); - window->State.Modifiers = 0xffffffff; + event.xkey.x, event.xkey.y + ); + fgState.Modifiers = 0xffffffff; } } else @@ -967,20 +942,23 @@ void FGAPIENTRY glutMainLoopEvent( void ) * Execute the callback (if one has been specified), * given that the special code seems to be valid... */ - if( special_cb && (special != -1) ) + if( special_cb && ( special != -1 ) ) { fgSetWindow( window ); - window->State.Modifiers = fgGetXModifiers( &event ); + fgState.Modifiers = fgGetXModifiers( &event ); special_cb( special, event.xkey.x, event.xkey.y ); - window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } } } } break; + case ReparentNotify: + break; /* XXX Should disable this event */ + default: - fgWarning ("Unknown X event type: %d", event.type); + fgWarning( "Unknown X event type: %d", event.type ); break; } } @@ -992,7 +970,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) while( PeekMessage( &stMsg, NULL, 0, 0, PM_NOREMOVE ) ) { if( GetMessage( &stMsg, NULL, 0, 0 ) == 0 ) - fgState.ExecState = GLUT_EXEC_STATE_STOP ; + fgState.ExecState = GLUT_EXEC_STATE_STOP; TranslateMessage( &stMsg ); DispatchMessage( &stMsg ); @@ -1013,7 +991,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) void FGAPIENTRY glutMainLoop( void ) { #if TARGET_HOST_WIN32 - SFG_Window *window = (SFG_Window *)fgStructure.Windows.First ; + SFG_Window *window = (SFG_Window *)fgStructure.Windows.First; #endif freeglut_assert_ready; @@ -1030,23 +1008,19 @@ void FGAPIENTRY glutMainLoop( void ) */ while( window ) { - if ( FETCH_WCB( *window, Visibility ) ) + if( FETCH_WCB( *window, Visibility ) ) { - SFG_Window *current_window = fgStructure.Window ; + SFG_Window *current_window = fgStructure.Window; - /* - * fgSetWindow( window ); - * window->Callbacks.Visibility ( window->State.Visible ) ; - */ INVOKE_WCB( *window, Visibility, ( window->State.Visible ) ); fgSetWindow( current_window ); } - window = (SFG_Window *)window->Node.Next ; + window = (SFG_Window *)window->Node.Next; } #endif - fgState.ExecState = GLUT_EXEC_STATE_RUNNING ; + fgState.ExecState = GLUT_EXEC_STATE_RUNNING; while( fgState.ExecState == GLUT_EXEC_STATE_RUNNING ) { glutMainLoopEvent( ); @@ -1058,7 +1032,7 @@ void FGAPIENTRY glutMainLoop( void ) if( fgState.IdleCallback ) fgState.IdleCallback( ); - fgSleepForEvents(); + fgSleepForEvents( ); } } @@ -1072,7 +1046,7 @@ void FGAPIENTRY glutMainLoop( void ) fgDeinitialize( ); if( execState == GLUT_ACTION_EXIT ) - exit( 0 ) ; + exit( 0 ); } } @@ -1081,7 +1055,7 @@ void FGAPIENTRY glutMainLoop( void ) */ void FGAPIENTRY glutLeaveMainLoop( void ) { - fgState.ExecState = GLUT_EXEC_STATE_STOP ; + fgState.ExecState = GLUT_EXEC_STATE_STOP; } @@ -1111,7 +1085,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LONG lRet = 1; if ( ( window == NULL ) && ( uMsg != WM_CREATE ) ) - return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ); + return DefWindowProc( hWnd, uMsg, wParam, lParam ); /* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, uMsg, wParam, lParam ); */ @@ -1126,16 +1100,17 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, window->Window.Handle = hWnd; window->Window.Device = GetDC( hWnd ); - if( fgState.BuildingAMenu ) + if( window->IsMenu ) { unsigned int current_DisplayMode = fgState.DisplayMode; fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH; - fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE ); + fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE ); fgState.DisplayMode = current_DisplayMode; if( fgStructure.MenuContext ) wglMakeCurrent( window->Window.Device, - fgStructure.MenuContext->Context ) ; + fgStructure.MenuContext->Context + ); else { fgStructure.MenuContext = @@ -1144,14 +1119,14 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, wglCreateContext( window->Window.Device ); } - /* window->Window.Context = wglGetCurrentContext () ; */ + /* window->Window.Context = wglGetCurrentContext( ); */ window->Window.Context = wglCreateContext( window->Window.Device ); } else { - fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE ); + fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE ); - if( fgState.UseCurrentContext != TRUE ) + if( ! fgState.UseCurrentContext ) window->Window.Context = wglCreateContext( window->Window.Device ); else @@ -1163,7 +1138,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, } } - window->State.NeedToResize = TRUE; + window->State.NeedToResize = GL_TRUE; ReleaseDC( window->Window.Handle, window->Window.Device ); break; @@ -1175,12 +1150,12 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, break; #if 0 case WM_SETFOCUS: - printf("WM_SETFOCUS: %p\n", window ); + printf( "WM_SETFOCUS: %p\n", window ); lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); break; case WM_ACTIVATE: - if (LOWORD(wParam) != WA_INACTIVE) + if( LOWORD( wParam ) != WA_INACTIVE ) { /* glutSetCursor( fgStructure.Window->State.Cursor ); */ printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window, @@ -1196,23 +1171,30 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* * Windows seems to need reminding to erase the cursor for NONE. */ + + /* + * XXX Is this #if 0 section anything that we need to worry + * XXX about? Can we delete it? If it will ever be used, + * XXX why not re-use some common code with the glutSetCursor() + * XXX function (or perhaps invoke glutSetCursor())? + */ #if 0 - if ((LOWORD(lParam) == HTCLIENT) && - (fgStructure.Window->State.Cursor == GLUT_CURSOR_NONE)) + if( ( LOWORD( lParam ) == HTCLIENT ) && + ( fgStructure.Window->State.Cursor == GLUT_CURSOR_NONE ) ) SetCursor( NULL ); #else /* Set the cursor AND change it for this window class. */ -#define MAP_CURSOR(a,b) \ - case a: \ - SetCursor( LoadCursor( NULL, b ) ); \ - break; +#define MAP_CURSOR(a,b) \ + case a: \ + SetCursor( LoadCursor( NULL, b ) ); \ + break; /* Nuke the cursor AND change it for this window class. */ -#define ZAP_CURSOR(a,b) \ - case a: \ - SetCursor( NULL ); \ - break; +#define ZAP_CURSOR(a,b) \ + case a: \ + SetCursor( NULL ); \ + break; if( LOWORD( lParam ) == HTCLIENT ) switch( window->State.Cursor ) @@ -1239,11 +1221,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, break; case WM_SHOWWINDOW: - window->State.Visible = TRUE; - window->State.Redisplay = TRUE; + window->State.Visible = GL_TRUE; + window->State.Redisplay = GL_TRUE; break; case WM_PAINT: + /* Turn on the visibility in case it was turned off somehow */ + window->State.Visible = GL_TRUE; BeginPaint( hWnd, &ps ); fghRedrawWindowByHandle( hWnd ); EndPaint( hWnd, &ps ); @@ -1255,8 +1239,8 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, */ if( fgStructure.Window == window ) { - int used = FALSE ; - SFG_Window *iter ; + int used = FALSE; + SFG_Window *iter; wglMakeCurrent( NULL, NULL ); /* @@ -1280,7 +1264,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, * Put on a linked list of windows to be removed after all the * callbacks have returned */ - fgAddToWindowDestroyList( window, FALSE ); + fgAddToWindowDestroyList( window, GL_FALSE ); DestroyWindow( hWnd ); break; @@ -1297,43 +1281,23 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( window->ActiveMenu ) { - window->State.Redisplay = TRUE; + window->State.Redisplay = GL_TRUE; fgSetWindow ( window->ActiveMenu->ParentWindow ); break; } - window->State.Modifiers = fgGetWin32Modifiers( ); + fgState.Modifiers = fgGetWin32Modifiers( ); if( ( wParam & MK_LBUTTON ) || ( wParam & MK_MBUTTON ) || ( wParam & MK_RBUTTON ) ) - { - /* - * if( window->Callbacks.Motion ) - * { - * fgSetWindow( window ); - * window->Callbacks.Motion( window->State.MouseX, - * window->State.MouseY ); - * } - */ INVOKE_WCB( *window, Motion, ( window->State.MouseX, window->State.MouseY ) ); - } else - { - /* - * if( window->Callbacks.Passive ) - * { - * fgSetWindow( window ); - * window->Callbacks.Passive( window->State.MouseX, - * window->State.MouseY ); - * } - */ INVOKE_WCB( *window, Passive, ( window->State.MouseX, window->State.MouseY ) ); - } - window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } break; @@ -1344,28 +1308,37 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_MBUTTONUP: case WM_RBUTTONUP: { - GLboolean pressed = TRUE; + GLboolean pressed = GL_TRUE; int button; window->State.MouseX = LOWORD( lParam ); window->State.MouseY = HIWORD( lParam ); + /* + * XXX Either these multi-statement lines should be broken + * XXX in the form: + * XXX pressed = GL_TRUE; + * XXX button = GLUT_LEFT_BUTTON; + * XXX break; + * XXX ...or we should use a macro (much as I dislike freeglut's + * XXX preponderance of using macros to "compress" code). + */ switch( uMsg ) { case WM_LBUTTONDOWN: - pressed = TRUE; button = GLUT_LEFT_BUTTON; break; + pressed = GL_TRUE; button = GLUT_LEFT_BUTTON; break; case WM_MBUTTONDOWN: - pressed = TRUE; button = GLUT_MIDDLE_BUTTON; break; + pressed = GL_TRUE; button = GLUT_MIDDLE_BUTTON; break; case WM_RBUTTONDOWN: - pressed = TRUE; button = GLUT_RIGHT_BUTTON; break; + pressed = GL_TRUE; button = GLUT_RIGHT_BUTTON; break; case WM_LBUTTONUP: - pressed = FALSE; button = GLUT_LEFT_BUTTON; break; + pressed = GL_FALSE; button = GLUT_LEFT_BUTTON; break; case WM_MBUTTONUP: - pressed = FALSE; button = GLUT_MIDDLE_BUTTON; break; + pressed = GL_FALSE; button = GLUT_MIDDLE_BUTTON; break; case WM_RBUTTONUP: - pressed = FALSE; button = GLUT_RIGHT_BUTTON; break; + pressed = GL_FALSE; button = GLUT_RIGHT_BUTTON; break; default: - pressed = FALSE; button = -1; break; + pressed = GL_FALSE; button = -1; break; } if( GetSystemMetrics( SM_SWAPBUTTON ) ) @@ -1378,6 +1351,9 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, return DefWindowProc( hWnd, uMsg, lParam, wParam ); /* + * XXX This comment is duplicated in two other spots. + * XXX Can we centralize it? + * * Do not execute the application's mouse callback if a * menu is hooked to this button. * In that case an appropriate private call should be generated. @@ -1397,8 +1373,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* Window has an active menu, it absorbs any mouse click */ if( window->ActiveMenu ) { - /* Inside the menu, invoke the callback and deactivate the menu*/ - if( fgCheckActiveMenu( window, window->ActiveMenu ) == TRUE ) + /* Outside the menu, deactivate the menu if it's a downclick */ + if( ! fgCheckActiveMenu( window, window->ActiveMenu ) ) + { + if( pressed ) + fgDeactivateMenu( window->ActiveMenu->ParentWindow ); + } + else /* In menu, invoke the callback and deactivate the menu*/ { /* * Save the current window and menu and set the current @@ -1418,25 +1399,20 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, fgSetWindow( save_window ); fgStructure.Menu = save_menu; } - else /* Out of menu, deactivate the menu if it's a downclick */ - { - if( pressed == TRUE ) - fgDeactivateMenu( window->ActiveMenu->ParentWindow ); - } /* * Let's make the window redraw as a result of the mouse * click and menu activity. */ if( ! window->IsMenu ) - window->State.Redisplay = TRUE; + window->State.Redisplay = GL_TRUE; break; } - if ( ( window->Menu[ button ] ) && ( pressed == TRUE ) ) + if ( window->Menu[ button ] && pressed ) { - window->State.Redisplay = TRUE; + window->State.Redisplay = GL_TRUE; fgSetWindow( window ); fgActivateMenu( window, button ); @@ -1447,36 +1423,30 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, break; fgSetWindow( window ); - fgStructure.Window->State.Modifiers = fgGetWin32Modifiers( ); + fgState.Modifiers = fgGetWin32Modifiers( ); INVOKE_WCB( *window, Mouse, ( button, - pressed == TRUE ? GLUT_DOWN : GLUT_UP, + pressed ? GLUT_DOWN : GLUT_UP, window->State.MouseX, window->State.MouseY ) ); - /* - * window->Callbacks.Mouse( - * button, - * pressed == TRUE ? GLUT_DOWN : GLUT_UP, - * window->State.MouseX, - * window->State.MouseY - * ); - */ - fgStructure.Window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } break; case 0x020a: /* Should be WM_MOUSEWHEEL but my compiler doesn't recognize it */ { + /* + * XXX THIS IS SPECULATIVE -- John Fay, 10/2/03 + * XXX Should use WHEEL_DELTA instead of 120 + */ int wheel_number = LOWORD( wParam ); - /* THIS IS SPECULATIVE -- John Fay, 10/2/03 */ - short ticks = HIWORD( lParam ) / 120; - /* Should be WHEEL_DELTA instead of 120 */ + short ticks = ( short )HIWORD( wParam ) / 120; int direction = 1; if( ticks < 0 ) @@ -1498,11 +1468,10 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, break; fgSetWindow( window ); - fgStructure.Window->State.Modifiers = fgGetWin32Modifiers( ); + fgState.Modifiers = fgGetWin32Modifiers( ); while( ticks-- ) if( FETCH_WCB( *window, MouseWheel ) ) - { INVOKE_WCB( *window, MouseWheel, ( wheel_number, direction, @@ -1510,16 +1479,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, window->State.MouseY ) ); - } - /* - * if( window->Callbacks.MouseWheel ) - * window->Callbacks.MouseWheel( - * wheel_number, - * direction, - * window->State.MouseX, - * window->State.MouseY - * ); - */ else /* No mouse wheel, call the mouse button callback twice */ { /* @@ -1537,28 +1496,17 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, ( button, GLUT_UP, window->State.MouseX, window->State.MouseX ) ); - - /* - * window->Callbacks.Mouse( button, GLUT_DOWN, - * window->State.MouseX, - * window->State.MouseY - * ); - * window->Callbacks.Mouse( button, GLUT_UP, - * window->State.MouseX, - * window->State.MouseY - * ); - */ } - fgStructure.Window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } - break ; + break; case WM_SYSKEYDOWN: case WM_KEYDOWN: { int keypress = -1; - POINT mouse_pos ; + POINT mouse_pos; if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) ) break; @@ -1567,7 +1515,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, * Remember the current modifiers state. This is done here in order * to make sure the VK_DELETE keyboard callback is executed properly. */ - window->State.Modifiers = fgGetWin32Modifiers( ); + fgState.Modifiers = fgGetWin32Modifiers( ); GetCursorPos( &mouse_pos ); ScreenToClient( window->Window.Handle, &mouse_pos ); @@ -1608,32 +1556,18 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* * The delete key should be treated as an ASCII keypress: */ - /* - * if( window->Callbacks.Keyboard ) - * { - * fgSetWindow( window ); - * window->Callbacks.Keyboard( 127, window->State.MouseX, - * window->State.MouseY ); - * } - */ INVOKE_WCB( *window, Keyboard, ( 127, window->State.MouseX, window->State.MouseY ) ); } - /* if( ( keypress != -1 ) && window->Callbacks.Special ) - * { - * fgSetWindow( window ); - * window->Callbacks.Special( keypress, window->State.MouseX, - * window->State.MouseY ); - * } - */ if( keypress != -1 ) INVOKE_WCB( *window, Special, - ( keypress, window->State.MouseX, window->State.MouseY ) + ( keypress, + window->State.MouseX, window->State.MouseY ) ); - window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } break; @@ -1647,7 +1581,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, * Remember the current modifiers state. This is done here in order * to make sure the VK_DELETE keyboard callback is executed properly. */ - window->State.Modifiers = fgGetWin32Modifiers( ); + fgState.Modifiers = fgGetWin32Modifiers( ); GetCursorPos( &mouse_pos ); ScreenToClient( window->Window.Handle, &mouse_pos ); @@ -1688,13 +1622,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* * The delete key should be treated as an ASCII keypress: */ - /* if( window->Callbacks.KeyboardUp ) - * { - * fgSetWindow( window ); - * window->Callbacks.KeyboardUp( 127, window->State.MouseX, - * window->State.MouseY ); - * } - */ INVOKE_WCB( *window, KeyboardUp, ( 127, window->State.MouseX, window->State.MouseY ) ); @@ -1710,15 +1637,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if( ToAscii( wParam, 0, state, code, 0 ) == 1 ) wParam=code[ 0 ]; - /* - * if( window->Callbacks.KeyboardUp ) - * { - * fgSetWindow( window ); - * window->Callbacks.KeyboardUp( (char)wParam, - * window->State.MouseX, - * window->State.MouseY ); - * } - */ INVOKE_WCB( *window, KeyboardUp, ( (char)wParam, window->State.MouseX, window->State.MouseY ) @@ -1726,21 +1644,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, } } - /* - * if( (keypress != -1) && window->Callbacks.SpecialUp ) - * { - * fgSetWindow( window ); - * window->Callbacks.SpecialUp( keypress, window->State.MouseX, - * window->State.MouseY ); - * } - */ if( keypress != -1 ) INVOKE_WCB( *window, SpecialUp, ( keypress, window->State.MouseX, window->State.MouseY ) ); - window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } break; @@ -1750,30 +1660,26 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) ) break; + /* + * XXX INVOKE_WCB() takes care of the callback-pointer check. + * XXX We could just uncoditionally find/trash the Modifiers + * XXX and get rid of the "if( ... ) {" and "}". Unconditinal + * XXX code is simpler code. (^& + */ if( FETCH_WCB( *window, Keyboard ) ) { - /* fgSetWindow( window ); */ - window->State.Modifiers = fgGetWin32Modifiers( ); - /* window->Callbacks.Keyboard( (char)wParam, window->State.MouseX, - window->State.MouseY ); */ + fgState.Modifiers = fgGetWin32Modifiers( ); INVOKE_WCB( *window, Keyboard, ( (char)wParam, window->State.MouseX, window->State.MouseY ) ); - window->State.Modifiers = 0xffffffff; + fgState.Modifiers = 0xffffffff; } } break; case WM_CAPTURECHANGED: /* User has finished resizing the window, force a redraw */ - /* - * if( window->Callbacks.Display ) - * { - * fgSetWindow( window ); - * window->Callbacks.Display( ); - * } - */ INVOKE_WCB( *window, Display, ( ) ); /*lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ) ; */ @@ -1807,7 +1713,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_SYNCPAINT: /* 0x0088 */ /* Another window has moved, need to update this one */ - window->State.Redisplay = TRUE; + window->State.Redisplay = GL_TRUE; lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Help screen says this message must be passed to "DefWindowProc" */ break; @@ -1818,6 +1724,74 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* Pass it on to "DefWindowProc" to repaint a standard border */ break; + case WM_SYSCOMMAND : /* 0x0112 */ + { + /* + * We have received a system command message. Try to act on it. + * The commands are passed in through the "lParam" parameter: + * Clicking on a corner to resize the window gives a "F004" message + * but this is not defined in my header file. + */ + switch ( lParam ) + { + case SC_SIZE: + break; + + case SC_MOVE: + break; + + case SC_MINIMIZE: + /* User has clicked on the "-" to minimize the window */ + /* Turn off the visibility */ + window->State.Visible = GL_FALSE; + break; + + case SC_MAXIMIZE: + break; + + case SC_NEXTWINDOW: + break; + + case SC_PREVWINDOW: + break; + + case SC_CLOSE: + /* Followed very closely by a WM_CLOSE message */ + break; + + case SC_VSCROLL: + break; + + case SC_HSCROLL: + break; + + case SC_MOUSEMENU: + break; + + case SC_KEYMENU: + break; + + case SC_ARRANGE: + break; + + case SC_RESTORE: + break; + + case SC_TASKLIST: + break; + + case SC_SCREENSAVE: + break; + + case SC_HOTKEY: + break; + } + } + + /* We need to pass the message on to the operating system as well */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break; + default: /* * Handle unhandled messages