/* Computes position of corners of client area (drawable area) of a window * based on the provided window Rect (outer position including decorations) * and based on the style of the window in question. If the window pointer * or the window handle is NULL, a fully decorated window (caption and * border) is assumed. * Furthermore, 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, the size * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable * area. */ void fghComputeClientAreaFromWindowRect( const SFG_Window *window, RECT *windowRect, BOOL wantPosOutside ) { DWORD windowStyle = 0; int xBorderWidth = 0, yBorderWidth = 0; if (window && window->Window.Handle) windowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE); else windowStyle = WS_OVERLAPPEDWINDOW; /* If window has title bar, correct rect for it */ if (windowStyle & WS_MAXIMIZEBOX) /* 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... */ if (wantPosOutside) windowRect->bottom -= GetSystemMetrics( SM_CYCAPTION ); else windowRect->top += GetSystemMetrics( SM_CYCAPTION ); /* get width of window's borders (frame), correct rect for it. * Note, borders can be of zero width if style does not specify borders */ fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth); if (wantPosOutside) { windowRect->right -= xBorderWidth * 2; windowRect->bottom -= yBorderWidth * 2; } else { windowRect->left += xBorderWidth; windowRect->right -= xBorderWidth; windowRect->top += yBorderWidth; windowRect->bottom -= yBorderWidth; } }
/* Computes position of corners of window Rect (outer position including * decorations) based on the provided client rect and based on the style * of the window in question. * If posIsOutside is set to true, the input client Rect is taken to 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. */ void fghComputeWindowRectFromClientArea_UseStyle( const DWORD windowStyle, RECT *clientRect, BOOL posIsOutside ) { int xBorderWidth = 0, yBorderWidth = 0; /* If window has title bar, correct rect for it */ if (windowStyle & WS_MAXIMIZEBOX) /* 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... */ if (posIsOutside) clientRect->bottom += GetSystemMetrics( SM_CYCAPTION ); else clientRect->top -= GetSystemMetrics( SM_CYCAPTION ); /* get width of window's borders (frame), correct rect for it. * Note, borders can be of zero width if style does not specify borders */ fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth); if (posIsOutside) { clientRect->right += xBorderWidth * 2; clientRect->bottom += yBorderWidth * 2; } else { clientRect->left -= xBorderWidth; clientRect->right += xBorderWidth; clientRect->top -= yBorderWidth; clientRect->bottom += yBorderWidth; } }
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 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.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; default: fgWarning( "glutGet(): missing enum handle %d", eWhat ); break; } return -1; }