#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:
* 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;
/*
* 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 );
/*
* 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;
* 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 );
/*
* This might speed up message processing. Is that true?
*/
winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
- ButtonPressMask | ButtonReleaseMask | KeyPressMask |
+ ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyRelease |
VisibilityChangeMask | EnterWindowMask | LeaveWindowMask |
PointerMotionMask | ButtonMotionMask;
winAttr.background_pixmap = None;
XMapWindow( fgDisplay.Display, window->Window.Handle );
/*
- * This somehow fixes the glutGet() GLUT_WINDOW_X and GLUT_WINDOW_Y problem...
- */
- //XMoveWindow( fgDisplay.Display, window->Window.Handle, x, y );
-
- /*
* In game mode, move the viewport a bit to hide the decorations.
* This code depends on the XFree86 video mode extensions.
*/
if( gameMode == TRUE )
{
+ /*
+ * This somehow fixes the glutGet() GLUT_WINDOW_X and GLUT_WINDOW_Y problem...
+ */
+ XMoveWindow( fgDisplay.Display, window->Window.Handle, x, y );
+
# ifdef X_XF86VidModeSetViewPort
/*
* 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
WNDCLASS wc;
int flags;
ATOM atom;
- HWND hWnd;
freeglut_assert_ready;
if( gameMode == FALSE )
{
+ if ( !isSubWindow )
+ {
/*
- * Update the window position and dimensions, taking account of window decorations
+ * Update the window dimensions, taking account of window decorations.
+ * "freeglut" is to create the window with the outside of its border at (x,y)
+ * and with dimensions (w,h).
*/
- 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 );
+ 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; }
#endif
/*
+ * Save the window's single- or double-buffering state
+ */
+ window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0 ;
+
+ /*
+ * 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 ) ;
+ }
+
+ /*
* Set the newly created window as the current one
*/
- glutSetWindow( window->ID );
+ fgSetWindow( 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 );
}
/*
- * 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 ;
}
/*
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 ) ;
}
/*
/*
* Set the current window's title
*/
-void FGAPIENTRY glutSetWindowTitle( char* title )
+void FGAPIENTRY glutSetWindowTitle( const char* title )
{
freeglut_assert_ready; freeglut_assert_window;
/*
* Set the current window's iconified title
*/
-void FGAPIENTRY glutSetIconTitle( char* title )
+void FGAPIENTRY glutSetIconTitle( const char* title )
{
freeglut_assert_ready; freeglut_assert_window;
#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 ) * 2;
+ height += GetSystemMetrics( SM_CYSIZEFRAME ) * 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
*/
GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
- /*
+ /*
* Reposition the window, forcing a redraw to happen
*/
MoveWindow(
);
}
+/*
+ * A.Donev: Set and retrieve the window's user data
+ */
+void* FGAPIENTRY glutGetWindowData( void )
+{
+ return(fgStructure.Window->UserData);
+}
+
+void FGAPIENTRY glutSetWindowData(void* data)
+{
+ fgStructure.Window->UserData=data;
+}
+
/*** END OF FILE ***/