#define G_LOG_DOMAIN "freeglut-state"
#include "../include/GL/freeglut.h"
-#include "../include/GL/freeglut_internal.h"
+#include "freeglut_internal.h"
/*
* TODO BEFORE THE STABLE RELEASE:
/* -- LOCAL DEFINITIONS ---------------------------------------------------- */
-/*
- * Those are definitions introduced to make the glutGet() more easy,
- * however they might introduce errors if someone ports GLX to Win32 :)
- *
- * Btw. this is not that a bad idea (wrapping WGL around GLX)...
- */
-#if TARGET_HOST_WIN32
-# define GLX_RGBA 0x01
-# define GLX_DOUBLEBUFFER 0x02
-# define GLX_BUFFER_SIZE 0x03
-# define GLX_STENCIL_SIZE 0x04
-# define GLX_DEPTH_SIZE 0x05
-# define GLX_RED_SIZE 0x06
-# define GLX_GREEN_SIZE 0x07
-# define GLX_BLUE_SIZE 0x08
-# define GLX_ALPHA_SIZE 0x09
-# define GLX_ACCUM_RED_SIZE 0x0A
-# define GLX_ACCUM_GREEN_SIZE 0x0B
-# define GLX_ACCUM_BLUE_SIZE 0x0C
-# define GLX_ACCUM_ALPHA_SIZE 0x0D
-# define GLX_STEREO 0x0E
-#endif
-
-
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+#if TARGET_HOST_UNIX_X11
/*
* Queries the GL context about some attributes
*/
static int fghGetConfig( int attribute )
{
- int returnValue;
+ int returnValue ;
- /*
- * Return nothing if there is no current window set
- */
- if( fgStructure.Window == NULL )
- return( 0 );
+ /*
+ * Return nothing if there is no current window set
+ */
+ if( fgStructure.Window == NULL )
+ return( 0 );
-#if TARGET_HOST_UNIX_X11
- /*
- * glXGetConfig should work fine
- */
- glXGetConfig( fgDisplay.Display, fgStructure.Window->Window.VisualInfo, attribute, &returnValue );
+ /*
+ * glXGetConfig should work fine
+ */
+ glXGetConfig( fgDisplay.Display, fgStructure.Window->Window.VisualInfo, attribute, &returnValue );
-#elif TARGET_HOST_WIN32
- /*
- * This is going to be a bit harder than the X11 version...
- */
-# pragma message( "freeglut_state.c::fghGetConfig() says hello world my name is not implemented!" )
- switch( attribute )
- {
- case GLX_RGBA:
- case GLX_DOUBLEBUFFER:
- case GLX_BUFFER_SIZE:
- case GLX_RED_SIZE:
- case GLX_GREEN_SIZE:
- case GLX_BLUE_SIZE:
- case GLX_DEPTH_SIZE:
- return( 1 );
-
- case GLX_STENCIL_SIZE:
- case GLX_ALPHA_SIZE:
- case GLX_ACCUM_RED_SIZE:
- case GLX_ACCUM_GREEN_SIZE:
- case GLX_ACCUM_BLUE_SIZE:
- case GLX_ACCUM_ALPHA_SIZE:
- case GLX_STEREO:
- default:
- /*
- * Well, this looks like not implemented to me :)
- */
- return( 0 );
- }
-#endif
-
- /*
- * Have the query results returned
- */
- return( returnValue );
+ /*
+ * Have the query results returned
+ */
+ return ( returnValue ) ;
}
+#endif
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
+ * General settings assignment method
+ */
+void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
+{
+ freeglut_assert_ready;
+
+ /*
+ * Check what is the caller querying for. In chronological code add order.
+ */
+ switch( eWhat )
+ {
+ case GLUT_INIT_WINDOW_X: fgState.Position.X = (GLint)value ;
+ break ;
+ case GLUT_INIT_WINDOW_Y: fgState.Position.Y = (GLint)value ;
+ break ;
+ case GLUT_INIT_WINDOW_WIDTH: fgState.Size.X = (GLint)value ;
+ break ;
+ case GLUT_INIT_WINDOW_HEIGHT: fgState.Size.Y = (GLint)value ;
+ break ;
+ case GLUT_INIT_DISPLAY_MODE: fgState.DisplayMode = (unsigned int)value ;
+ break ;
+
+ case GLUT_ACTION_ON_WINDOW_CLOSE: fgState.ActionOnWindowClose = value ;
+ break ;
+
+ case GLUT_WINDOW_CURSOR:
+ if( fgStructure.Window != NULL ) fgStructure.Window->State.Cursor = value ;
+ break ;
+
+ default:
+ /*
+ * Just have it reported, so that we can see what needs to be implemented
+ */
+ fgWarning( "glutSetOption(): missing enum handle %i\n", eWhat );
+ break;
+ }
+}
+
+/*
* General settings query method
*/
int FGAPIENTRY glutGet( GLenum eWhat )
{
+ int returnValue ;
+ GLboolean boolValue ;
+
+ if ( eWhat == GLUT_INIT_STATE )
+ return ( fgState.Time.Set ) ;
+
freeglut_assert_ready;
/*
*/
return( 0 );
+#if TARGET_HOST_UNIX_X11
/*
- * The rest of GLX queries is general enough to use a macro to check them
+ * The rest of GLX queries under X are general enough to use a macro to check them
*/
# define GLX_QUERY(a,b) case a: return( fghGetConfig( b ) );
# undef GLX_QUERY
-#if TARGET_HOST_UNIX_X11
/*
* Colormap size is handled in a bit different way than all the rest
*/
*/
case GLUT_WINDOW_X:
case GLUT_WINDOW_Y:
- {
- XWindowAttributes winAttributes;
- Window another, window;
- int x, y;
-
- /*
- * Return zero if there is no current window set
- */
- if( fgStructure.Window == NULL )
- return( 0 );
-
- /*
- * So, grab the current window's position
- */
- window = fgStructure.Window->Window.Handle;
-
- /*
- * Grab the current window's attributes now
- */
- XGetWindowAttributes(
- fgDisplay.Display,
- window,
- &winAttributes
- );
-
- /*
- * Correct the results for the parental relation and border size
- */
- XTranslateCoordinates(
- fgDisplay.Display,
- window,
- winAttributes.root,
- -winAttributes.border_width,
- -winAttributes.border_width,
- &x, &y,
- &another
- );
-
- /*
- * See if we have to return the X or Y coordinate
- */
- return( eWhat == GLUT_WINDOW_X ? x : y );
- }
-
case GLUT_WINDOW_WIDTH:
case GLUT_WINDOW_HEIGHT:
+ case GLUT_WINDOW_BORDER_WIDTH :
+ case GLUT_WINDOW_HEADER_HEIGHT :
{
XWindowAttributes winAttributes;
return( 0 );
/*
- * Checking for window's size is much easier:
+ * Grab the current window's attributes now
*/
XGetWindowAttributes(
fgDisplay.Display,
);
/*
- * See if to return the window's width or height
+ * See which window attribute to return
*/
- return( eWhat == GLUT_WINDOW_WIDTH ? winAttributes.width : winAttributes.height );
+ switch ( eWhat )
+ {
+ case GLUT_WINDOW_X: return winAttributes.x ;
+ case GLUT_WINDOW_Y: return winAttributes.y ;
+ case GLUT_WINDOW_WIDTH: return winAttributes.width ;
+ case GLUT_WINDOW_HEIGHT: return winAttributes.height ;
+ case GLUT_WINDOW_BORDER_WIDTH : return winAttributes.border_width ;
+ case GLUT_WINDOW_HEADER_HEIGHT : return winAttributes.border_width * 3 ; /* a kludge for now */
+ }
}
/*
#elif TARGET_HOST_WIN32
+ /*
+ * Handle the OpenGL inquiries
+ */
+ case GLUT_WINDOW_RGBA:
+ glGetBooleanv ( GL_RGBA_MODE, &boolValue ) ; /* True if color buffers store RGBA */
+ returnValue = boolValue ? 1 : 0 ;
+ return ( returnValue ) ;
+ case GLUT_WINDOW_DOUBLEBUFFER:
+ glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ) ; /* True if front and back buffers exist */
+ returnValue = boolValue ? 1 : 0 ;
+ return ( returnValue ) ;
+ case GLUT_WINDOW_STEREO:
+ glGetBooleanv ( GL_STEREO, &boolValue ) ; /* True if left and right buffers exist */
+ returnValue = boolValue ? 1 : 0 ;
+ return ( returnValue ) ;
+
+ case GLUT_WINDOW_RED_SIZE:
+ glGetIntegerv ( GL_RED_BITS, &returnValue ) ; /* Number of bits per red component in color buffers */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_GREEN_SIZE:
+ glGetIntegerv ( GL_GREEN_BITS, &returnValue ) ; /* Number of bits per green component in color buffers */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_BLUE_SIZE:
+ glGetIntegerv ( GL_BLUE_BITS, &returnValue ) ; /* Number of bits per blue component in color buffers */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_ALPHA_SIZE:
+ glGetIntegerv ( GL_ALPHA_BITS, &returnValue ) ; /* Number of bits per alpha component in color buffers */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_ACCUM_RED_SIZE:
+ glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ) ; /* Number of bits per red component in the accumulation buffer */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_ACCUM_GREEN_SIZE:
+ glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ) ; /* Number of bits per green component in the accumulation buffer */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_ACCUM_BLUE_SIZE:
+ glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ) ; /* Number of bits per blue component in the accumulation buffer */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
+ glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ) ; /* Number of bits per alpha component in the accumulation buffer */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_DEPTH_SIZE:
+ glGetIntegerv ( GL_DEPTH_BITS, &returnValue ) ; /* Number of depth-buffer bitplanes */
+ return ( returnValue ) ;
+
+ case GLUT_WINDOW_BUFFER_SIZE:
+ returnValue = 1 ; /* ????? */
+ return ( returnValue ) ;
+ case GLUT_WINDOW_STENCIL_SIZE:
+ returnValue = 0 ; /* ????? */
+ return ( returnValue ) ;
+
+ /*
+ * Window position and size
+ */
case GLUT_WINDOW_X:
case GLUT_WINDOW_Y:
case GLUT_WINDOW_WIDTH:
case GLUT_WINDOW_HEIGHT:
{
+ /*
+ * There is considerable confusion about the "right thing to do" concerning window
+ * size and position. GLUT itself is not consistent between Windows and Linux; since
+ * platform independence is a virtue for "freeglut", we decided to break with GLUT's
+ * behaviour.
+ * Under Linux, it is apparently not possible to get the window border sizes in order
+ * to subtract them off the window's initial position until some time after the window
+ * has been created. Therefore we decided on the following behaviour, both under
+ * Windows and under Linux:
+ * - When you create a window with position (x,y) and size (w,h), the upper left hand
+ * corner of the outside of the window is at (x,y) and the size of the drawable area
+ * is (w,h).
+ * - When you query the size and position of the window--as is happening here for
+ * Windows--"freeglut" will return the size of the drawable area--the (w,h) that you
+ * specified when you created the window--and the coordinates of the upper left hand
+ * corner of the drawable area--which is NOT the (x,y) you specified.
+ */
+
RECT winRect;
/*
/*
* We need to call GetWindowRect() first...
+ * (this returns the pixel coordinates of the outside of the window)
*/
GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
/*
* ...then we've got to correct the results we've just received...
*/
- winRect.left += GetSystemMetrics( SM_CXSIZEFRAME ) - 1;
- winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME ) - 1;
- winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) - 1 + GetSystemMetrics( SM_CYCAPTION );
- winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME ) + 1;
+ if (fgStructure.GameMode != fgStructure.Window &&
+ fgStructure.Window->Parent == NULL )
+ {
+ winRect.left += GetSystemMetrics( SM_CXSIZEFRAME );
+ winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME );
+ winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
+ winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME );
+ }
/*
* ...and finally return the caller the desired value:
}
break;
+ case GLUT_WINDOW_BORDER_WIDTH :
+ return ( GetSystemMetrics( SM_CXSIZEFRAME ) ) ;
+
+ case GLUT_WINDOW_HEADER_HEIGHT :
+ return ( GetSystemMetrics( SM_CYCAPTION ) ) ;
+
case GLUT_DISPLAY_MODE_POSSIBLE:
/*
* Check if the current display mode is possible
*/
- return( fgSetupPixelFormat( fgStructure.Window, TRUE ) );
+ return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_MAIN_PLANE ) );
case GLUT_WINDOW_FORMAT_ID:
/*
return( fgListLength( &fgStructure.Menu->Entries ) );
+ case GLUT_ACTION_ON_WINDOW_CLOSE:
+ return fgState.ActionOnWindowClose;
+
+ case GLUT_VERSION:
+ return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH;
+
default:
/*
* Just have it reported, so that we can see what needs to be implemented
*/
switch( eWhat )
{
+
+#if TARGET_HOST_UNIX_X11
+
case GLUT_OVERLAY_POSSIBLE:
/*
* Nope, overlays are not possible.
*/
return( -1 );
+#elif TARGET_HOST_WIN32
+
+ case GLUT_OVERLAY_POSSIBLE:
+ /*
+ * Check if an overlay display mode is possible
+ */
+ return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_OVERLAY_PLANE ) );
+
+ case GLUT_LAYER_IN_USE:
+ /*
+ * The normal plane is always in use
+ */
+ return( GLUT_NORMAL );
+
+ case GLUT_HAS_OVERLAY:
+ /*
+ * No window is allowed to have an overlay
+ */
+ return( FALSE );
+
+ case GLUT_TRANSPARENT_INDEX:
+ /*
+ * Return just anything, which is always defined as zero
+ */
+ return( 0 );
+
+ case GLUT_NORMAL_DAMAGED:
+ /*
+ * Actually I do not know. Maybe.
+ */
+ return( FALSE );
+
+ case GLUT_OVERLAY_DAMAGED:
+ /*
+ * Return minus one to mark that no layer is in use
+ */
+ return( -1 );
+#endif
+
default:
/*
* Complain to the user about the obvious bug