/* * 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; }
/* * 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; }
/* * General settings query method */ int FGAPIENTRY glutGet( GLenum eWhat ) { switch (eWhat) { case GLUT_INIT_STATE: return fgState.Initialised; /* Although internally the time store is 64bits wide, the return value * here still wraps every 49.7 days. Integer overflows cancel however * when subtracting an initial start time, unless the total time exceeds * 32-bit, so you can still work with this. * XXX: a glutGet64 to return the time might be an idea... */ case GLUT_ELAPSED_TIME: return (int) fgElapsedTime(); } FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGet" ); 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 ; /* 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; case GLUT_GEOMETRY_VISUALIZE_NORMALS: if( fgStructure.CurrentWindow == NULL ) return GL_FALSE; return fgStructure.CurrentWindow->State.VisualizeNormals; case GLUT_STROKE_FONT_DRAW_JOIN_DOTS: return fgState.StrokeFontDrawJoinDots; default: return fgPlatformGlutGet ( eWhat ); break; } }
/* * General settings query method */ int FGAPIENTRY glutGet( GLenum eWhat ) { switch (eWhat) { case GLUT_INIT_STATE: return fgState.Initialised; case GLUT_ELAPSED_TIME: return (int) 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 ; /* 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; default: return fgPlatformGlutGet ( eWhat ); break; } return -1; }