X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=freeglut-1.3%2Ffreeglut_window.c;h=7d67b61939ca103c4b1c82e56922b0b778cadff0;hb=4718a4ac2bad82816c5169dcdd16967d058d6810;hp=943b0276db60cef5cfcdd9ea282a70dca5276347;hpb=d51f09af4edcc7bfd0f1913a917ae405d302227e;p=freeglut diff --git a/freeglut-1.3/freeglut_window.c b/freeglut-1.3/freeglut_window.c index 943b027..7d67b61 100644 --- a/freeglut-1.3/freeglut_window.c +++ b/freeglut-1.3/freeglut_window.c @@ -32,7 +32,7 @@ #define G_LOG_DOMAIN "freeglut-window" #include "../include/GL/freeglut.h" -#include "../include/GL/freeglut_internal.h" +#include "freeglut_internal.h" /* * TODO BEFORE THE STABLE RELEASE: @@ -214,7 +214,7 @@ XVisualInfo* fgChooseVisual( void ) * Setup the pixel format for a Win32 window */ #if TARGET_HOST_WIN32 -GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly ) +GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ) { PIXELFORMATDESCRIPTOR* ppfd, pfd; int flags, pixelformat; @@ -232,51 +232,56 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly ) /* * It might be the case for us to use double buffering */ - if( fgState.DisplayMode & GLUT_DOUBLE ) - flags |= PFD_DOUBLEBUFFER; + if( fgState.DisplayMode & GLUT_DOUBLE ) + flags |= PFD_DOUBLEBUFFER; - /* - * Specify which pixel format do we opt for... - */ + /* + * Specify which pixel format do we opt for... + */ # pragma message( "fgSetupPixelFormat(): there is still some work to do here!" ) - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = flags; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cRedBits = 0; - pfd.cRedShift = 0; - pfd.cGreenBits = 0; - pfd.cGreenShift = 0; - pfd.cBlueBits = 0; - pfd.cBlueShift = 0; - pfd.cAlphaBits = 0; - pfd.cAlphaShift = 0; - pfd.cAccumBits = 0; - pfd.cAccumRedBits = 0; - pfd.cAccumGreenBits = 0; - pfd.cAccumBlueBits = 0; - pfd.cAccumAlphaBits = 0; - pfd.cDepthBits = 32; - pfd.cStencilBits = 0; - pfd.cAuxBuffers = 0; - pfd.iLayerType = PFD_MAIN_PLANE; - pfd.bReserved = 0; - pfd.dwLayerMask = 0; - pfd.dwVisibleMask = 0; - pfd.dwDamageMask = 0; - - /* - * Fill in the color bits... - */ - pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL ); - ppfd = &pfd; + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = flags; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cRedBits = 0; + pfd.cRedShift = 0; + pfd.cGreenBits = 0; + pfd.cGreenShift = 0; + pfd.cBlueBits = 0; + pfd.cBlueShift = 0; + pfd.cAlphaBits = 0; + pfd.cAlphaShift = 0; + pfd.cAccumBits = 0; + pfd.cAccumRedBits = 0; + pfd.cAccumGreenBits = 0; + pfd.cAccumBlueBits = 0; + pfd.cAccumAlphaBits = 0; +#if 0 + pfd.cDepthBits = 32; + pfd.cStencilBits = 0; +#else + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; +#endif + pfd.cAuxBuffers = 0; + pfd.iLayerType = layer_type; + pfd.bReserved = 0; + pfd.dwLayerMask = 0; + pfd.dwVisibleMask = 0; + pfd.dwDamageMask = 0; + + /* + * Fill in the color bits... + */ + pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL ); + ppfd = &pfd; /* * Choose the pixel format that matches our demand */ - pixelformat = ChoosePixelFormat( window->Window.Device, ppfd ); + pixelformat = ChoosePixelFormat( window->Window.Device, ppfd ); if( pixelformat == 0 ) return( FALSE ); @@ -289,18 +294,62 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly ) /* * Finally, set the window's pixel format */ - if( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) == FALSE ) - return( FALSE ); - - return( TRUE ); + return ( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) ) ; } #endif /* + * Sets the OpenGL context and the fgStructure "Current Window" pointer to the window + * structure passed in. + */ +void fgSetWindow ( SFG_Window *window ) +{ +#if TARGET_HOST_UNIX_X11 + /* + * Make the selected window's GLX context the current one + */ + glXMakeCurrent( + fgDisplay.Display, + window->Window.Handle, + window->Window.Context + ); + +#elif TARGET_HOST_WIN32 + /* + * Release the previous' context's device context + */ + if( fgStructure.Window != NULL ) + ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device ); + + if ( window ) + { + /* + * We will care about releasing the device context later + */ + window->Window.Device = GetDC( window->Window.Handle ); + + /* + * Set the new current context: + */ + wglMakeCurrent( + window->Window.Device, + window->Window.Context + ); + } +#endif + + /* + * Remember that we have changed the current window state + */ + fgStructure.Window = window; +} + + +/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ -void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode ) +void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, int isSubWindow ) { #if TARGET_HOST_UNIX_X11 XSetWindowAttributes winAttr; @@ -312,9 +361,35 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i freeglut_assert_ready; /* + * Save the window's single- or double-buffering state + */ + window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0 ; + + /* * Here we are upon the stage. Have the visual selected. */ window->Window.VisualInfo = fgChooseVisual(); + if ( ! window->Window.VisualInfo ) + { + /* + * The "fgChooseVisual" returned a null meaning that the visual context is not available. + * Try a couple of variations to see if they will work. + */ + if ( ! ( fgState.DisplayMode & GLUT_DOUBLE ) ) + { + /* + * Single buffering--try it doubled + */ + fgState.DisplayMode |= GLUT_DOUBLE ; + window->Window.VisualInfo = fgChooseVisual(); + } + + /* + * GLUT also checks for multi-sampling, but I don't see that anywhere else in FREEGLUT + * so I won't bother with it for the moment. + */ + } + assert( window->Window.VisualInfo != NULL ); /* @@ -451,7 +526,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i /* * Set the newly created window as the current one... */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Move the viewport a bit down and right from top-left corner to hide the decorations @@ -466,12 +541,20 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i # endif } + /* + * If it's not double-buffered, make sure the rendering is done to the front buffer. + */ + if ( ! window->Window.DoubleBuffered ) + { + glDrawBuffer ( GL_FRONT ) ; + glReadBuffer ( GL_FRONT ) ; + } + #elif TARGET_HOST_WIN32 WNDCLASS wc; int flags; ATOM atom; - HWND hWnd; freeglut_assert_ready; @@ -483,15 +566,20 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i if( gameMode == FALSE ) { + if ( !isSubWindow ) + { /* * Update the window position and dimensions, taking account of window decorations */ - x -= (GetSystemMetrics( SM_CXSIZEFRAME ) - 1); - y -= (GetSystemMetrics( SM_CYSIZEFRAME ) - 1); - w += (GetSystemMetrics( SM_CXSIZEFRAME ) - 1)*2; - h += (GetSystemMetrics( SM_CYSIZEFRAME ) - 1)*2 + GetSystemMetrics( SM_CYCAPTION ); - /* + x -= (GetSystemMetrics( SM_CXSIZEFRAME ) ); + y -= (GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ); + if ( y < 0 ) y = 0 ; + w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2; + h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); + } + + /* * Check if the user wants us to use the default position/size */ if( fgState.Position.Use == FALSE ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } @@ -551,7 +639,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i /* * Set the newly created window as the current one */ - glutSetWindow( window->ID ); + fgSetWindow( window ); } /* @@ -600,7 +688,7 @@ void fgCloseWindow( SFG_Window* window ) int FGAPIENTRY glutCreateWindow( const char* title ) { /* - * Create a new window and return it's unique ID number + * Create a new window and return its unique ID number */ return( fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y, fgState.Size.X, fgState.Size.Y, FALSE )->ID ); @@ -638,21 +726,29 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) } /* - * Destroys a window and all of it's subwindows + * Destroys a window and all of its subwindows */ void FGAPIENTRY glutDestroyWindow( int windowID ) { - /* - * Grab the freeglut window pointer from the structure - */ - SFG_Window* window = fgWindowByID( windowID ); - freeglut_return_if_fail( window != NULL ); - - /* - * There is a function that performs all needed steps - * defined in freeglut_structure.c. Let's use it: - */ - fgDestroyWindow( window, TRUE ); + fgExecutionState ExecState = fgState.ExecState ; + + /* + * Grab the freeglut window pointer from the structure + */ + SFG_Window* window = fgWindowByID( windowID ); + freeglut_return_if_fail( window != NULL ); + + /* + * There is a function that performs all needed steps + * defined in freeglut_structure.c. Let's use it: + */ + fgAddToWindowDestroyList( window, TRUE ); + + /* + * Since the "fgAddToWindowDestroyList" function could easily have set the "ExecState" + * to stop, let's set it back to what it was. + */ + fgState.ExecState = ExecState ; } /* @@ -691,42 +787,7 @@ void FGAPIENTRY glutSetWindow( int ID ) return; } -#if TARGET_HOST_UNIX_X11 - /* - * Make the selected window's GLX context the current one - */ - glXMakeCurrent( - fgDisplay.Display, - window->Window.Handle, - window->Window.Context - ); - -#elif TARGET_HOST_WIN32 - /* - * Release the previous' context's device context - */ - if( fgStructure.Window != NULL ) - ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device ); - - /* - * We will care about releasing the device context later - */ - window->Window.Device = GetDC( window->Window.Handle ); - - /* - * Set the new current context: - */ - wglMakeCurrent( - window->Window.Device, - window->Window.Context - ); - -#endif - - /* - * Remember that we have changed the current window state - */ - fgStructure.Window = window; + fgSetWindow ( window ) ; } /* @@ -843,7 +904,7 @@ void FGAPIENTRY glutIconifyWindow( void ) /* * Set the current window's title */ -void FGAPIENTRY glutSetWindowTitle( char* title ) +void FGAPIENTRY glutSetWindowTitle( const char* title ) { freeglut_assert_ready; freeglut_assert_window; @@ -892,7 +953,7 @@ void FGAPIENTRY glutSetWindowTitle( char* title ) /* * Set the current window's iconified title */ -void FGAPIENTRY glutSetIconTitle( char* title ) +void FGAPIENTRY glutSetIconTitle( const char* title ) { freeglut_assert_ready; freeglut_assert_window; @@ -955,19 +1016,37 @@ void FGAPIENTRY glutReshapeWindow( int width, int height ) #elif TARGET_HOST_WIN32 { RECT winRect; + int x, y ; /* * First off, grab the current window's position */ GetWindowRect( fgStructure.Window->Window.Handle, &winRect ); + x = winRect.left ; + y = winRect.top ; + + if ( fgStructure.Window->Parent == NULL ) /* If this is not a subwindow ... */ + { + /* + * Adjust the size of the window to allow for the size of the frame + */ + width += (GetSystemMetrics( SM_CXSIZEFRAME ) - 1)*2; + height += (GetSystemMetrics( SM_CYSIZEFRAME ) - 1)*2 + GetSystemMetrics( SM_CYCAPTION ); + } + else /* This is a subwindow, get the parent window's position and subtract it off */ + { + GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ; + x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME ) ; + y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ; + } /* * Resize the window, forcing a redraw to happen */ MoveWindow( fgStructure.Window->Window.Handle, - winRect.left, - winRect.top, + x, + y, width, height, TRUE @@ -999,7 +1078,17 @@ void FGAPIENTRY glutPositionWindow( int x, int y ) */ GetWindowRect( fgStructure.Window->Window.Handle, &winRect ); - /* + if ( fgStructure.Window->Parent == NULL ) /* If this is not a subwindow ... */ + { + /* + * Adjust the position of the window to allow for the size of the frame + */ + x -= (GetSystemMetrics( SM_CXSIZEFRAME ) - 1); + y -= (GetSystemMetrics( SM_CYSIZEFRAME ) - 1 + GetSystemMetrics( SM_CYCAPTION )); + if ( y < 0 ) y = 0 ; + } + + /* * Reposition the window, forcing a redraw to happen */ MoveWindow(