/* * This functions checks if an OpenGL extension is supported or not * * XXX Wouldn't this be simpler and clearer if we used strtok()? */ int FGAPIENTRY glutExtensionSupported( const char* extension ) { const char *extensions, *start; const int len = (int)strlen( extension ); /* Make sure there is a current window, and thus a current context available */ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutExtensionSupported" ); freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 ); if (strchr(extension, ' ')) return 0; start = extensions = (const char *) glGetString(GL_EXTENSIONS); /* XXX consider printing a warning to stderr that there's no current * rendering context. */ freeglut_return_val_if_fail( extensions != NULL, 0 ); while (1) { const char *p = strstr(extensions, extension); if (!p) return 0; /* not found */ /* check that the match isn't a super string */ if ((p == start || p[-1] == ' ') && (p[len] == ' ' || p[len] == 0)) return 1; /* skip the false match and continue */ extensions = p + len; } return 0 ; }
/* * Returns the width in pixels of a font's character */ int FGAPIENTRY glutBitmapWidth( void* fontID, int character ) { SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapWidth" ); font = fghFontByID( fontID ); freeglut_return_val_if_fail( character > 0 && character < 256, 0 ); freeglut_return_val_if_fail( font, 0 ); return *( font->Characters[ character ] ); }
/* * Return the width in pixels of a stroke character */ int glutStrokeWidth( void* fontID, int character ) { const SFG_StrokeChar *schar; SFG_StrokeFont* font = fghStrokeByID( fontID ); freeglut_return_val_if_fail( ( character >= 0 ) && ( character < font->Quantity ), 0 ); schar = font->Characters[ character ]; freeglut_return_val_if_fail( schar, 0 ); return ( int )( schar->Right + 0.5 ); }
/* * Return the width of a string drawn using a bitmap font */ int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string ) { unsigned char c; int length = 0, this_line_length = 0; SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapLength" ); font = fghFontByID( fontID ); freeglut_return_val_if_fail( font, 0 ); if ( !string || ! *string ) return 0; while( ( c = *string++) ) { if( c != '\n' )/* Not an EOL, increment length of line */ this_line_length += *( font->Characters[ c ]); else /* EOL; reset the length of this line */ { if( length < this_line_length ) length = this_line_length; this_line_length = 0; } } if ( length < this_line_length ) length = this_line_length; return length; }
/* * Returns the width in pixels of a font's character */ int glutBitmapWidth( void* fontID, int character ) { SFG_Font* font = fghFontByID( fontID ); freeglut_return_val_if_fail( character > 0 && character < 256, 0 ); return *( font->Characters[ character - 1 ] ); }
/* * Return the width in pixels of a stroke character */ int FGAPIENTRY glutStrokeWidth( void* fontID, int character ) { const SFG_StrokeChar *schar; SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" ); font = fghStrokeByID( fontID ); freeglut_return_val_if_fail( ( character >= 0 ) && ( character < font->Quantity ), 0 ); freeglut_return_val_if_fail( font, 0 ); schar = font->Characters[ character ]; freeglut_return_val_if_fail( schar, 0 ); return ( int )( schar->Right + 0.5 ); }
/* * Return the width of a string drawn using a stroke font */ int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string ) { unsigned char c; float length = 0.0; float this_line_length = 0.0; SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeLength" ); font = fghStrokeByID( fontID ); freeglut_return_val_if_fail( font, 0 ); if ( !string || ! *string ) return 0; while( ( c = *string++) ) if( c < font->Quantity ) { if( c == '\n' ) /* EOL; reset the length of this line */ { if( length < this_line_length ) length = this_line_length; this_line_length = 0.0; } else /* Not an EOL, increment the length of this line */ { const SFG_StrokeChar *schar = font->Characters[ c ]; if( schar ) this_line_length += schar->Right; } } if( length < this_line_length ) length = this_line_length; return( int )( length + 0.5 ); }
/* * Returns the height of a stroke font */ GLfloat FGAPIENTRY glutStrokeHeight( void* fontID ) { SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeHeight" ); font = fghStrokeByID( fontID ); freeglut_return_val_if_fail( font, 0.0 ); return font->Height; }
/* * Returns the height of a bitmap font */ int FGAPIENTRY glutBitmapHeight( void* fontID ) { SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapHeight" ); font = fghFontByID( fontID ); freeglut_return_val_if_fail( font, 0 ); return font->Height; }
/* * Return the width in pixels of a stroke character */ int FGAPIENTRY glutStrokeWidth( void* fontID, int character ) { const SFG_StrokeChar *schar; SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" ); font = fghStrokeByID( fontID ); if (!font) { fgWarning("glutStrokeWidth: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID); return 0; } freeglut_return_val_if_fail( ( character >= 0 ) && ( character < font->Quantity ), 0 ); schar = font->Characters[ character ]; freeglut_return_val_if_fail( schar, 0 ); return ( int )( schar->Right + 0.5 ); }
/* * Returns the width in pixels of a font's character */ int FGAPIENTRY glutBitmapWidth( void* fontID, int character ) { SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapWidth" ); freeglut_return_val_if_fail( character > 0 && character < 256, 0 ); font = fghFontByID( fontID ); if (!font) { fgWarning("glutBitmapWidth: bitmap font 0x%08x not found. Make sure you're not passing a stroke font.\n",fontID); return 0; } return *( font->Characters[ character ] ); }
/* * This function creates a sub window. */ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) { int ret = 0; SFG_Window* window = NULL; SFG_Window* parent = NULL; freeglut_assert_ready; parent = fgWindowByID( parentID ); freeglut_return_val_if_fail( parent != NULL, 0 ); window = fgCreateWindow( parent, "", x, y, w, h, GL_FALSE, GL_FALSE ); ret = window->ID; return ret; }
/* Gets the rect describing the client area (drawable area) of the * specified window. * Returns an empty rect if window pointer or window handle is NULL. * If wantPosOutside is set to true, the output client Rect * will follow freeGLUT's window specification convention in which the * top-left corner is at the outside of the window, while the size * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable * area. */ RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside ) { RECT windowRect = {0,0,0,0}; freeglut_return_val_if_fail((window && window->Window.Handle),windowRect); /* * call GetWindowRect() * (this returns the pixel coordinates of the outside of the window) */ GetWindowRect( window->Window.Handle, &windowRect ); /* Then correct the results */ fghComputeClientAreaFromWindowRect(window, &windowRect, wantPosOutside); return windowRect; }
/* * This function creates a sub window. */ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) { int ret = 0; SFG_Window* window = NULL; SFG_Window* parent = NULL; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" ); parent = fgWindowByID( parentID ); freeglut_return_val_if_fail( parent != NULL, 0 ); if ( x < 0 ) { x = parent->State.Width + x ; if ( w >= 0 ) x -= w ; } if ( w < 0 ) w = parent->State.Width - x + w ; if ( w < 0 ) { x += w ; w = -w ; } if ( y < 0 ) { y = parent->State.Height + y ; if ( h >= 0 ) y -= h ; } if ( h < 0 ) h = parent->State.Height - y + h ; if ( h < 0 ) { y += h ; h = -h ; } window = fgCreateWindow( parent, "", x, y, w, h, GL_FALSE, GL_FALSE ); ret = window->ID; return ret; }
/* * General settings query method */ int FGAPIENTRY glutGet( GLenum eWhat ) { #if TARGET_HOST_MS_WINDOWS int returnValue ; GLboolean boolValue ; #endif int nsamples = 0; switch (eWhat) { case GLUT_INIT_STATE: return fgState.Initialised; case GLUT_ELAPSED_TIME: return fgElapsedTime(); } FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGet" ); /* XXX In chronological code add order. (WHY in that order?) */ switch( eWhat ) { /* Following values are stored in fgState and fgDisplay global structures */ case GLUT_SCREEN_WIDTH: return fgDisplay.ScreenWidth ; case GLUT_SCREEN_HEIGHT: return fgDisplay.ScreenHeight ; case GLUT_SCREEN_WIDTH_MM: return fgDisplay.ScreenWidthMM ; case GLUT_SCREEN_HEIGHT_MM: return fgDisplay.ScreenHeightMM; case GLUT_INIT_WINDOW_X: return fgState.Position.Use ? fgState.Position.X : -1 ; case GLUT_INIT_WINDOW_Y: return fgState.Position.Use ? fgState.Position.Y : -1 ; case GLUT_INIT_WINDOW_WIDTH: return fgState.Size.Use ? fgState.Size.X : -1 ; case GLUT_INIT_WINDOW_HEIGHT: return fgState.Size.Use ? fgState.Size.Y : -1 ; case GLUT_INIT_DISPLAY_MODE: return fgState.DisplayMode ; case GLUT_INIT_MAJOR_VERSION: return fgState.MajorVersion ; case GLUT_INIT_MINOR_VERSION: return fgState.MinorVersion ; case GLUT_INIT_FLAGS: return fgState.ContextFlags ; case GLUT_INIT_PROFILE: return fgState.ContextProfile ; #if TARGET_HOST_POSIX_X11 /* * The window/context specific queries are handled mostly by * fghGetConfig(). */ case GLUT_WINDOW_NUM_SAMPLES: #ifdef GLX_VERSION_1_3 glGetIntegerv(GL_SAMPLES, &nsamples); #endif return nsamples; /* * 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 ); GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA ); GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER ); GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE ); GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE ); GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE ); GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE ); GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE ); GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE ); GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE ); GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO ); # undef GLX_QUERY /* Colormap size is handled in a bit different way than all the rest */ case GLUT_WINDOW_COLORMAP_SIZE: if( (fghGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) ) { /* * We've got a RGBA visual, so there is no colormap at all. * The other possibility is that we have no current window set. */ return 0; } else { const GLXFBConfig * fbconfig = fgStructure.CurrentWindow->Window.FBConfig; XVisualInfo * visualInfo = glXGetVisualFromFBConfig( fgDisplay.Display, *fbconfig ); const int result = visualInfo->visual->map_entries; XFree(visualInfo); return result; } /* * Those calls are somewhat similiar, as they use XGetWindowAttributes() * function */ case GLUT_WINDOW_X: case GLUT_WINDOW_Y: case GLUT_WINDOW_BORDER_WIDTH: case GLUT_WINDOW_HEADER_HEIGHT: { int x, y; Window w; if( fgStructure.CurrentWindow == NULL ) return 0; XTranslateCoordinates( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, fgDisplay.RootWindow, 0, 0, &x, &y, &w); switch ( eWhat ) { case GLUT_WINDOW_X: return x; case GLUT_WINDOW_Y: return y; } if ( w == 0 ) return 0; XTranslateCoordinates( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, w, 0, 0, &x, &y, &w); switch ( eWhat ) { case GLUT_WINDOW_BORDER_WIDTH: return x; case GLUT_WINDOW_HEADER_HEIGHT: return y; } } case GLUT_WINDOW_WIDTH: case GLUT_WINDOW_HEIGHT: { XWindowAttributes winAttributes; if( fgStructure.CurrentWindow == NULL ) return 0; XGetWindowAttributes( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, &winAttributes ); switch ( eWhat ) { case GLUT_WINDOW_WIDTH: return winAttributes.width ; case GLUT_WINDOW_HEIGHT: return winAttributes.height ; } } /* I do not know yet if there will be a fgChooseVisual() function for Win32 */ case GLUT_DISPLAY_MODE_POSSIBLE: { /* We should not have to call fgChooseFBConfig again here. */ GLXFBConfig * fbconfig; int isPossible; fbconfig = fgChooseFBConfig(); if (fbconfig == NULL) { isPossible = 0; } else { isPossible = 1; XFree(fbconfig); } return isPossible; } /* This is system-dependant */ case GLUT_WINDOW_FORMAT_ID: if( fgStructure.CurrentWindow == NULL ) return 0; return fghGetConfig( GLX_VISUAL_ID ); #elif TARGET_HOST_MS_WINDOWS case GLUT_WINDOW_NUM_SAMPLES: glGetIntegerv(WGL_SAMPLES_ARB, &nsamples); return nsamples; /* Handle the OpenGL inquiries */ case GLUT_WINDOW_RGBA: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_RGBA_MODE, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_DOUBLEBUFFER: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_STEREO: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_STEREO, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_RED_SIZE: glGetIntegerv ( GL_RED_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_GREEN_SIZE: glGetIntegerv ( GL_GREEN_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_BLUE_SIZE: glGetIntegerv ( GL_BLUE_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_ALPHA_SIZE: glGetIntegerv ( GL_ALPHA_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_ACCUM_RED_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_GREEN_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_BLUE_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_ALPHA_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_DEPTH_SIZE: glGetIntegerv ( GL_DEPTH_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_BUFFER_SIZE: returnValue = 1 ; /* ????? */ return returnValue; case GLUT_WINDOW_STENCIL_SIZE: returnValue = 0 ; /* ????? */ return returnValue; 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 UNIX/X11; since * platform independence is a virtue for "freeglut", we * decided to break with GLUT's behaviour. * * Under UNIX/X11, 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 UNIX/X11: * - 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; freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 ); /* * We need to call GetWindowRect() first... * (this returns the pixel coordinates of the outside of the window) */ GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect ); /* ...then we've got to correct the results we've just received... */ #if !defined(_WIN32_WCE) if ( ( fgStructure.GameModeWindow != fgStructure.CurrentWindow ) && ( fgStructure.CurrentWindow->Parent == NULL ) && ( ! fgStructure.CurrentWindow->IsMenu ) ) { winRect.left += GetSystemMetrics( SM_CXSIZEFRAME ); winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME ); winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ); winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME ); } #endif /* !defined(_WIN32_WCE) */ switch( eWhat ) { case GLUT_WINDOW_X: return winRect.left ; case GLUT_WINDOW_Y: return winRect.top ; case GLUT_WINDOW_WIDTH: return winRect.right - winRect.left; case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top; } } break; case GLUT_WINDOW_BORDER_WIDTH : #if defined(_WIN32_WCE) return 0; #else return GetSystemMetrics( SM_CXSIZEFRAME ); #endif /* !defined(_WIN32_WCE) */ case GLUT_WINDOW_HEADER_HEIGHT : #if defined(_WIN32_WCE) return 0; #else return GetSystemMetrics( SM_CYCAPTION ); #endif /* defined(_WIN32_WCE) */ case GLUT_DISPLAY_MODE_POSSIBLE: #if defined(_WIN32_WCE) return 0; #else return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE, PFD_MAIN_PLANE ); #endif /* defined(_WIN32_WCE) */ case GLUT_WINDOW_FORMAT_ID: #if !defined(_WIN32_WCE) if( fgStructure.CurrentWindow != NULL ) return GetPixelFormat( fgStructure.CurrentWindow->Window.Device ); #endif /* defined(_WIN32_WCE) */ return 0; #endif /* The window structure queries */ case GLUT_WINDOW_PARENT: if( fgStructure.CurrentWindow == NULL ) return 0; if( fgStructure.CurrentWindow->Parent == NULL ) return 0; return fgStructure.CurrentWindow->Parent->ID; case GLUT_WINDOW_NUM_CHILDREN: if( fgStructure.CurrentWindow == NULL ) return 0; return fgListLength( &fgStructure.CurrentWindow->Children ); case GLUT_WINDOW_CURSOR: if( fgStructure.CurrentWindow == NULL ) return 0; return fgStructure.CurrentWindow->State.Cursor; case GLUT_MENU_NUM_ITEMS: if( fgStructure.CurrentMenu == NULL ) return 0; return fgListLength( &fgStructure.CurrentMenu->Entries ); case GLUT_ACTION_ON_WINDOW_CLOSE: return fgState.ActionOnWindowClose; case GLUT_VERSION : return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH; case GLUT_RENDERING_CONTEXT: return fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT : GLUT_CREATE_NEW_CONTEXT; case GLUT_DIRECT_RENDERING: return fgState.DirectContext; case GLUT_FULL_SCREEN: return fghCheckFullScreen(); case GLUT_AUX: return fgState.AuxiliaryBufferNumber; case GLUT_MULTISAMPLE: return fgState.SampleNumber; default: fgWarning( "glutGet(): missing enum handle %d", eWhat ); break; } return -1; }
GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ) { #if TARGET_HOST_WINCE return GL_TRUE; #else PIXELFORMATDESCRIPTOR* ppfd, pfd; int flags, pixelformat; freeglut_return_val_if_fail( window != NULL, 0 ); flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; if( fgState.DisplayMode & GLUT_DOUBLE ) flags |= PFD_DOUBLEBUFFER; #if defined(_MSC_VER) // MODIFIED FOR MRPT // JLBC //#pragma message( "fgSetupPixelFormat(): there is still some work to do here!" ) #endif /* Specify which pixel format do we opt for... */ 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 if( fgState.DisplayMode & GLUT_AUX4 ) pfd.cAuxBuffers = 4; else if( fgState.DisplayMode & GLUT_AUX3 ) pfd.cAuxBuffers = 3; else if( fgState.DisplayMode & GLUT_AUX2 ) pfd.cAuxBuffers = 2; else if( fgState.DisplayMode & GLUT_AUX1 ) pfd.cAuxBuffers = 1; else pfd.cAuxBuffers = 0; pfd.iLayerType = layer_type; pfd.bReserved = 0; pfd.dwLayerMask = 0; pfd.dwVisibleMask = 0; pfd.dwDamageMask = 0; pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL ); ppfd = &pfd; pixelformat = ChoosePixelFormat( window->Window.Device, ppfd ); if( pixelformat == 0 ) return GL_FALSE; if( checkOnly ) return GL_TRUE; return SetPixelFormat( window->Window.Device, pixelformat, ppfd ); #endif /* TARGET_HOST_WINCE */ }
int fgPlatformGlutGet ( GLenum eWhat ) { int returnValue ; GLboolean boolValue ; int nsamples = 0; switch( eWhat ) { case GLUT_WINDOW_NUM_SAMPLES: glGetIntegerv(WGL_SAMPLES_ARB, &nsamples); return nsamples; /* Handle the OpenGL inquiries */ case GLUT_WINDOW_RGBA: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_RGBA_MODE, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_DOUBLEBUFFER: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_STEREO: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_STEREO, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_RED_SIZE: glGetIntegerv ( GL_RED_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_GREEN_SIZE: glGetIntegerv ( GL_GREEN_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_BLUE_SIZE: glGetIntegerv ( GL_BLUE_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_ALPHA_SIZE: glGetIntegerv ( GL_ALPHA_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_ACCUM_RED_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_GREEN_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_BLUE_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_ALPHA_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_DEPTH_SIZE: glGetIntegerv ( GL_DEPTH_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_BUFFER_SIZE: returnValue = 1 ; /* ????? */ return returnValue; case GLUT_WINDOW_STENCIL_SIZE: returnValue = 0 ; /* ????? */ return returnValue; 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 UNIX/X11; since * platform independence is a virtue for "freeglut", we * decided to break with GLUT's behaviour. * * Under UNIX/X11, 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 UNIX/X11: * - 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; freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 ); #if defined(_WIN32_WCE) GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect ); #else winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE); #endif /* defined(_WIN32_WCE) */ switch( eWhat ) { case GLUT_WINDOW_X: return winRect.left ; case GLUT_WINDOW_Y: return winRect.top ; case GLUT_WINDOW_WIDTH: return winRect.right - winRect.left; case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top; } } break; case GLUT_WINDOW_BORDER_WIDTH : case GLUT_WINDOW_HEADER_HEIGHT : #if defined(_WIN32_WCE) return 0; #else { DWORD windowStyle; if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle) windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE); else /* If no window, return sizes for a default window with title bar and border */ windowStyle = WS_OVERLAPPEDWINDOW; switch( eWhat ) { case GLUT_WINDOW_BORDER_WIDTH: { int xBorderWidth, yBorderWidth; fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth); return xBorderWidth; } case GLUT_WINDOW_HEADER_HEIGHT: /* Need to query for WS_MAXIMIZEBOX to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */ return (windowStyle & WS_MAXIMIZEBOX)? GetSystemMetrics( SM_CYCAPTION ) : 0; } } #endif /* defined(_WIN32_WCE) */ case GLUT_DISPLAY_MODE_POSSIBLE: #if defined(_WIN32_WCE) return 0; #else return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE, PFD_MAIN_PLANE ); #endif /* defined(_WIN32_WCE) */ case GLUT_WINDOW_FORMAT_ID: #if !defined(_WIN32_WCE) if( fgStructure.CurrentWindow != NULL ) return GetPixelFormat( fgStructure.CurrentWindow->Window.pContext.Device ); #endif /* defined(_WIN32_WCE) */ return 0; default: fgWarning( "glutGet(): missing enum handle %d", eWhat ); break; } return -1; }
/* * General settings query method */ int FGAPIENTRY glutGet( GLenum eWhat ) { #if TARGET_HOST_MS_WINDOWS int returnValue ; GLboolean boolValue ; #endif int nsamples = 0; switch (eWhat) { case GLUT_INIT_STATE: return fgState.Initialised; case GLUT_ELAPSED_TIME: return fgElapsedTime(); } FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGet" ); /* XXX In chronological code add order. (WHY in that order?) */ switch( eWhat ) { /* Following values are stored in fgState and fgDisplay global structures */ case GLUT_SCREEN_WIDTH: return fgDisplay.ScreenWidth ; case GLUT_SCREEN_HEIGHT: return fgDisplay.ScreenHeight ; case GLUT_SCREEN_WIDTH_MM: return fgDisplay.ScreenWidthMM ; case GLUT_SCREEN_HEIGHT_MM: return fgDisplay.ScreenHeightMM; case GLUT_INIT_WINDOW_X: return fgState.Position.Use ? fgState.Position.X : -1 ; case GLUT_INIT_WINDOW_Y: return fgState.Position.Use ? fgState.Position.Y : -1 ; case GLUT_INIT_WINDOW_WIDTH: return fgState.Size.Use ? fgState.Size.X : -1 ; case GLUT_INIT_WINDOW_HEIGHT: return fgState.Size.Use ? fgState.Size.Y : -1 ; case GLUT_INIT_DISPLAY_MODE: return fgState.DisplayMode ; case GLUT_INIT_MAJOR_VERSION: return fgState.MajorVersion ; case GLUT_INIT_MINOR_VERSION: return fgState.MinorVersion ; case GLUT_INIT_FLAGS: return fgState.ContextFlags ; case GLUT_INIT_PROFILE: return fgState.ContextProfile ; #if TARGET_HOST_POSIX_X11 /* * The window/context specific queries are handled mostly by * fghGetConfig(). */ case GLUT_WINDOW_NUM_SAMPLES: #ifdef GLX_VERSION_1_3 glGetIntegerv(GL_SAMPLES, &nsamples); #endif return nsamples; /* * 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 ); GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA ); GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER ); GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE ); GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE ); GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE ); GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE ); GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE ); GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE ); GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE ); GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO ); # undef GLX_QUERY /* Colormap size is handled in a bit different way than all the rest */ case GLUT_WINDOW_COLORMAP_SIZE: if( (fghGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) ) { /* * We've got a RGBA visual, so there is no colormap at all. * The other possibility is that we have no current window set. */ return 0; } else { const GLXFBConfig * fbconfig = fgStructure.CurrentWindow->Window.FBConfig; XVisualInfo * visualInfo = glXGetVisualFromFBConfig( fgDisplay.Display, *fbconfig ); const int result = visualInfo->visual->map_entries; XFree(visualInfo); return result; } /* * Those calls are somewhat similiar, as they use XGetWindowAttributes() * function */ case GLUT_WINDOW_X: case GLUT_WINDOW_Y: case GLUT_WINDOW_BORDER_WIDTH: case GLUT_WINDOW_HEADER_HEIGHT: { int x, y; Window w; if( fgStructure.CurrentWindow == NULL ) return 0; XTranslateCoordinates( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, fgDisplay.RootWindow, 0, 0, &x, &y, &w); switch ( eWhat ) { case GLUT_WINDOW_X: return x; case GLUT_WINDOW_Y: return y; } if ( w == 0 ) return 0; XTranslateCoordinates( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, w, 0, 0, &x, &y, &w); switch ( eWhat ) { case GLUT_WINDOW_BORDER_WIDTH: return x; case GLUT_WINDOW_HEADER_HEIGHT: return y; } } case GLUT_WINDOW_WIDTH: case GLUT_WINDOW_HEIGHT: { XWindowAttributes winAttributes; if( fgStructure.CurrentWindow == NULL ) return 0; XGetWindowAttributes( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, &winAttributes ); switch ( eWhat ) { case GLUT_WINDOW_WIDTH: return winAttributes.width ; case GLUT_WINDOW_HEIGHT: return winAttributes.height ; } } /* I do not know yet if there will be a fgChooseVisual() function for Win32 */ case GLUT_DISPLAY_MODE_POSSIBLE: { /* We should not have to call fgChooseFBConfig again here. */ GLXFBConfig * fbconfig; int isPossible; fbconfig = fgChooseFBConfig(NULL); if (fbconfig == NULL) { isPossible = 0; } else { isPossible = 1; XFree(fbconfig); } return isPossible; } /* This is system-dependant */ case GLUT_WINDOW_FORMAT_ID: if( fgStructure.CurrentWindow == NULL ) return 0; return fghGetConfig( GLX_VISUAL_ID ); #elif TARGET_HOST_MS_WINDOWS case GLUT_WINDOW_NUM_SAMPLES: glGetIntegerv(WGL_SAMPLES_ARB, &nsamples); return nsamples; /* Handle the OpenGL inquiries */ case GLUT_WINDOW_RGBA: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_RGBA_MODE, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_DOUBLEBUFFER: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_STEREO: #if defined(_WIN32_WCE) boolValue = (GLboolean)0; /* WinCE doesn't support this feature */ #else glGetBooleanv ( GL_STEREO, &boolValue ); returnValue = boolValue ? 1 : 0; #endif return returnValue; case GLUT_WINDOW_RED_SIZE: glGetIntegerv ( GL_RED_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_GREEN_SIZE: glGetIntegerv ( GL_GREEN_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_BLUE_SIZE: glGetIntegerv ( GL_BLUE_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_ALPHA_SIZE: glGetIntegerv ( GL_ALPHA_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_ACCUM_RED_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_GREEN_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_BLUE_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_ACCUM_ALPHA_SIZE: #if defined(_WIN32_WCE) returnValue = 0; /* WinCE doesn't support this feature */ #else glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ); #endif return returnValue; case GLUT_WINDOW_DEPTH_SIZE: glGetIntegerv ( GL_DEPTH_BITS, &returnValue ); return returnValue; case GLUT_WINDOW_BUFFER_SIZE: returnValue = 1 ; /* ????? */ return returnValue; case GLUT_WINDOW_STENCIL_SIZE: returnValue = 0 ; /* ????? */ return returnValue; 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 UNIX/X11; since * platform independence is a virtue for "freeglut", we * decided to break with GLUT's behaviour. * * Under UNIX/X11, 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 UNIX/X11: * - 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; freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 ); #if defined(_WIN32_WCE) GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect ); #else fghGetClientArea(&winRect,fgStructure.CurrentWindow, FALSE); if (fgStructure.CurrentWindow->Parent && (eWhat==GLUT_WINDOW_X || eWhat==GLUT_WINDOW_Y)) { /* For child window, we should return relative to upper-left * of parent's client area. */ POINT topleft; topleft.x = winRect.left; topleft.y = winRect.top; ScreenToClient(fgStructure.CurrentWindow->Parent->Window.Handle,&topleft); winRect.left = topleft.x; winRect.top = topleft.y; } #endif /* defined(_WIN32_WCE) */ switch( eWhat ) { case GLUT_WINDOW_X: return winRect.left ; case GLUT_WINDOW_Y: return winRect.top ; case GLUT_WINDOW_WIDTH: return winRect.right - winRect.left; case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top; } } break; case GLUT_WINDOW_BORDER_WIDTH : case GLUT_WINDOW_BORDER_HEIGHT : #if defined(_WIN32_WCE) return 0; #else { /* We can't get the border width or header height in the simple way * with some calls to GetSystemMetrics. We'd then have to assume which * elements are present for a given decoration, and such calculations * wouldn't be valid for every version of Windows. The below should be * robust. */ int borderWidth, captionHeight; DWORD windowStyle, windowExStyle; RECT clientRect, winRect; /* Get style of window, or default style */ fghGetStyleFromWindow( fgStructure.CurrentWindow, &windowStyle, &windowExStyle ); /* Get client area if any window */ if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle) fghGetClientArea(&clientRect,fgStructure.CurrentWindow,FALSE); else SetRect(&clientRect,0,0,200,200); /* Compute window rect (including non-client area) */ CopyRect(&winRect,&clientRect); fghComputeWindowRectFromClientArea_UseStyle(&winRect,windowStyle,windowExStyle,FALSE); /* Calculate border width by taking width of whole window minus width of client area and divide by two * NB: we assume horizontal and vertical borders have the same size, which should always be the case * unless the user bypassed FreeGLUT and messed with the windowstyle himself. * Once borderwidth is known, account for it when comparing height of window to height of client area. * all other extra pixels are assumed to be atop the window, forming the caption. */ borderWidth = ((winRect.right-winRect.left)-(clientRect.right-clientRect.left))/2; captionHeight = (winRect.bottom-winRect.top)-(clientRect.bottom-clientRect.top)-borderWidth*2; switch( eWhat ) { case GLUT_WINDOW_BORDER_WIDTH: return borderWidth; case GLUT_WINDOW_BORDER_HEIGHT: return captionHeight; } } #endif /* defined(_WIN32_WCE) */ case GLUT_DISPLAY_MODE_POSSIBLE: #if defined(_WIN32_WCE) return 0; #else return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE, PFD_MAIN_PLANE ); #endif /* defined(_WIN32_WCE) */ case GLUT_WINDOW_FORMAT_ID: #if !defined(_WIN32_WCE) if( fgStructure.CurrentWindow != NULL ) return GetPixelFormat( fgStructure.CurrentWindow->Window.Device ); #endif /* defined(_WIN32_WCE) */ return 0; #endif /* The window structure queries */ case GLUT_WINDOW_PARENT: if( fgStructure.CurrentWindow == NULL ) return 0; if( fgStructure.CurrentWindow->Parent == NULL ) return 0; return fgStructure.CurrentWindow->Parent->ID; case GLUT_WINDOW_NUM_CHILDREN: if( fgStructure.CurrentWindow == NULL ) return 0; return fgListLength( &fgStructure.CurrentWindow->Children ); case GLUT_WINDOW_CURSOR: if( fgStructure.CurrentWindow == NULL ) return 0; return fgStructure.CurrentWindow->State.Cursor; case GLUT_MENU_NUM_ITEMS: if( fgStructure.CurrentMenu == NULL ) return 0; return fgListLength( &fgStructure.CurrentMenu->Entries ); case GLUT_ACTION_ON_WINDOW_CLOSE: return fgState.ActionOnWindowClose; case GLUT_VERSION : return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH; case GLUT_RENDERING_CONTEXT: return fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT : GLUT_CREATE_NEW_CONTEXT; case GLUT_DIRECT_RENDERING: return fgState.DirectContext; case GLUT_FULL_SCREEN: return fgStructure.CurrentWindow->State.IsFullscreen; case GLUT_AUX: return fgState.AuxiliaryBufferNumber; case GLUT_MULTISAMPLE: return fgState.SampleNumber; case GLUT_SKIP_STALE_MOTION_EVENTS: return fgState.SkipStaleMotion; default: fgWarning( "glutGet(): missing enum handle %d", eWhat ); break; } return -1; }