X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_main.c;h=34e284b7bba524aa03040692187bdb43327a1895;hb=36c6530f942007c5a72c6a3bd6d00077027d8c06;hp=5fbce0c7ee3053cceffc5527fd695bff8191fb70;hpb=5800cecd9ce89911e948c2e0abc982bfb5e8b675;p=freeglut diff --git a/src/freeglut_main.c b/src/freeglut_main.c index 5fbce0c..34e284b 100644 --- a/src/freeglut_main.c +++ b/src/freeglut_main.c @@ -87,42 +87,49 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle, #elif TARGET_HOST_WIN32 { - RECT winRect; - int x, y; + RECT rect; - GetWindowRect( window->Window.Handle, &winRect ); - x = winRect.left; - y = winRect.top; + /* + * For windowed mode, get the current position of the + * window and resize taking the size of the frame + * decorations into account. + */ + + GetWindowRect( window->Window.Handle, &rect ); + rect.right = rect.left + width; + rect.bottom = rect.top + height; if ( window->Parent == NULL ) { - /* - * Adjust the size of the window to allow for the size of the - * frame, if we are not a menu - */ - if ( ! window->IsMenu ) + if ( ! window->IsMenu && !window->State.IsGameMode ) { - width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2; - height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + - GetSystemMetrics( SM_CYCAPTION ); + rect.right += GetSystemMetrics( SM_CXSIZEFRAME ) * 2; + rect.bottom += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + + GetSystemMetrics( SM_CYCAPTION ); } } else { - GetWindowRect( window->Parent->Window.Handle, - &winRect ); - x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME ); - y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + - GetSystemMetrics( SM_CYCAPTION ); + GetWindowRect( window->Parent->Window.Handle, &rect ); + AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | + WS_CLIPCHILDREN, FALSE ); } - MoveWindow( - window->Window.Handle, - x, - y, - width, - height, - TRUE + /* + * SWP_NOACTIVATE Do not activate the window + * SWP_NOOWNERZORDER Do not change position in z-order + * SWP_NOSENDCHANGING Supress WM_WINDOWPOSCHANGING message + * SWP_NOZORDER Retains the current Z order (ignore 2nd param) + */ + + SetWindowPos( window->Window.Handle, + HWND_TOP, + rect.left, + rect.top, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | + SWP_NOZORDER ); } @@ -192,40 +199,25 @@ static void fghRedrawWindowByHandle ( SFG_WindowHandleType handle ) static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) { + if( window->State.NeedToResize ) + { + SFG_Window *current_window = fgStructure.Window; + + fgSetWindow( window ); + + fghReshapeWindowByHandle( + window->Window.Handle, + window->State.Width, + window->State.Height + ); + + window->State.NeedToResize = GL_FALSE; + fgSetWindow( current_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; - - fgSetWindow( window ); - - fghReshapeWindowByHandle( - window->Window.Handle, - window->State.Width, - window->State.Height - ); - - window->State.NeedToResize = GL_FALSE; - fgSetWindow ( current_window ); - } - window->State.Redisplay = GL_FALSE; #if TARGET_HOST_UNIX_X11 @@ -296,10 +288,11 @@ static void fghCheckJoystickPolls( void ) static void fghCheckTimers( void ) { long checkTime = fgElapsedTime( ); - SFG_Timer *timer; - while( timer = fgState.Timers.First ) + while( fgState.Timers.First ) { + SFG_Timer *timer = fgState.Timers.First; + if( timer->TriggerTime > checkTime ) break; @@ -457,31 +450,34 @@ static long fgNextTimer( void ) */ static void fgSleepForEvents( void ) { -#if TARGET_HOST_UNIX_X11 - fd_set fdset; - int err; - int socket; - struct timeval wait; - long msec; - + long msec; + if( fgState.IdleCallback || fgHavePendingRedisplays( ) ) return; - socket = ConnectionNumber( fgDisplay.Display ); - FD_ZERO( &fdset ); - FD_SET( socket, &fdset ); msec = fgNextTimer( ); - if( fgHaveJoystick( ) ) - msec = MIN( msec, 10 ); + if( fgHaveJoystick( ) ) /* XXX Use GLUT timers for joysticks... */ + msec = MIN( msec, 10 ); /* XXX Dumb; forces granularity to .01sec */ - wait.tv_sec = msec / 1000; - wait.tv_usec = (msec % 1000) * 1000; - err = select( socket+1, &fdset, NULL, NULL, &wait ); - - if( -1 == err ) - fgWarning ( "freeglut select() error: %d\n", errno ); - +#if TARGET_HOST_UNIX_X11 + { + fd_set fdset; + int err; + int socket; + struct timeval wait; + + socket = ConnectionNumber( fgDisplay.Display ); + FD_ZERO( &fdset ); + FD_SET( socket, &fdset ); + wait.tv_sec = msec / 1000; + wait.tv_usec = (msec % 1000) * 1000; + err = select( socket+1, &fdset, NULL, NULL, &wait ); + + if( -1 == err ) + fgWarning ( "freeglut select() error: %d\n", errno ); + } #elif TARGET_HOST_WIN32 + MsgWaitForMultipleObjects( 0, NULL, FALSE, msec, QS_ALLEVENTS ); #endif } @@ -1088,16 +1084,27 @@ void FGAPIENTRY glutMainLoop( void ) fgState.ExecState = GLUT_EXEC_STATE_RUNNING ; while( fgState.ExecState == GLUT_EXEC_STATE_RUNNING ) { - glutMainLoopEvent( ); + SFG_Window *window; - if( fgStructure.Windows.First == NULL ) + glutMainLoopEvent( ); + /* + * Step through the list of windows, seeing if there are any + * that are not menus + */ + for( window = ( SFG_Window * )fgStructure.Windows.First; + window; + window = ( SFG_Window * )window->Node.Next ) + if ( ! ( window->IsMenu ) ) + break; + + if( ! window ) fgState.ExecState = GLUT_EXEC_STATE_STOP; else { if( fgState.IdleCallback ) fgState.IdleCallback( ); - fgSleepForEvents(); + fgSleepForEvents( ); } } @@ -1106,6 +1113,8 @@ void FGAPIENTRY glutMainLoop( void ) * of a freeglut session, so that another glutInit() call can happen */ fgDeinitialize( ); + if( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT ) + exit( 0 ); } /* @@ -1372,10 +1381,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, } if( GetSystemMetrics( SM_SWAPBUTTON ) ) + { if( button == GLUT_LEFT_BUTTON ) button = GLUT_RIGHT_BUTTON; - else if( button == GLUT_RIGHT_BUTTON ) - button = GLUT_LEFT_BUTTON; + else + if( button == GLUT_RIGHT_BUTTON ) + button = GLUT_LEFT_BUTTON; + } if( button == -1 ) return DefWindowProc( hWnd, uMsg, lParam, wParam );