Putting in Jocelyn Frechot's X11 visual context changes. THIS WILL BREAK THE BUILD as I am unable to test it on a Linux machine here. Somebody please test it for me.

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@726 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
fayjf 2007-09-22 02:55:37 +00:00
parent 74802d3f21
commit 5ffa7abdb6
4 changed files with 200 additions and 62 deletions

View File

@ -380,7 +380,7 @@ struct tagSFG_Context
SFG_WindowContextType Context; /* The window's OpenGL/WGL context */
#if TARGET_HOST_POSIX_X11
XVisualInfo* VisualInfo; /* The window's visual information */
GLXFBConfig* FBConfig; /* The window's FBConfig */
#elif TARGET_HOST_MS_WINDOWS
HDC Device; /* The window's device context */
#endif
@ -556,10 +556,6 @@ enum
typedef struct tagSFG_MenuContext SFG_MenuContext;
struct tagSFG_MenuContext
{
#if TARGET_HOST_POSIX_X11
XVisualInfo* MVisualInfo; /* The window's visual information */
#endif
SFG_WindowContextType MContext; /* The menu window's WGL context */
};
@ -786,7 +782,7 @@ void fgDestroyStructure( void );
/* A helper function to check if a display mode is possible to use */
#if TARGET_HOST_POSIX_X11
XVisualInfo* fgChooseVisual( void );
GLXFBConfig* fgChooseFBConfig( void );
#endif
/* The window procedure for Win32 events handling */

View File

@ -52,10 +52,13 @@
static int fghGetConfig( int attribute )
{
int returnValue = 0;
int result; /* Not checked */
if( fgStructure.CurrentWindow )
glXGetConfig( fgDisplay.Display, fgStructure.CurrentWindow->Window.VisualInfo,
attribute, &returnValue );
result = glXGetFBConfigAttrib( fgDisplay.Display,
*(fgStructure.CurrentWindow->Window.FBConfig),
attribute,
&returnValue );
return returnValue;
}
@ -213,7 +216,20 @@ int FGAPIENTRY glutGet( GLenum eWhat )
*/
return 0;
}
return fgStructure.CurrentWindow->Window.VisualInfo->visual->map_entries;
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()
@ -278,13 +294,23 @@ int FGAPIENTRY glutGet( GLenum eWhat )
/* I do not know yet if there will be a fgChooseVisual() function for Win32 */
case GLUT_DISPLAY_MODE_POSSIBLE:
{
XVisualInfo* visualInfo = fgChooseVisual();
if ( visualInfo == NULL ) {
return 0;
} else {
XFree( visualInfo );
return 1;
/* 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 */
@ -292,7 +318,7 @@ int FGAPIENTRY glutGet( GLenum eWhat )
if( fgStructure.CurrentWindow == NULL )
return 0;
return fgStructure.CurrentWindow->Window.VisualInfo->visualid;
return fghGetConfig( GLX_VISUAL_ID );
#elif TARGET_HOST_MS_WINDOWS

View File

@ -72,6 +72,9 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
/* Have the window object created */
SFG_Window *window = (SFG_Window *)calloc( sizeof(SFG_Window), 1 );
#if TARGET_HOST_UNIX_X11
window->Window.FBConfig = NULL;
#endif
fghClearCallBacks( window );
/* Initialize the object properties */
@ -216,6 +219,12 @@ void fgDestroyWindow( SFG_Window* window )
fghClearCallBacks( window );
fgCloseWindow( window );
#if TARGET_HOST_UNIX_X11
if (window->Window.FBConfig != NULL)
{
XFree( window->Window.FBConfig );
}
#endif
free( window );
if( fgStructure.CurrentWindow == window )
fgStructure.CurrentWindow = NULL;

View File

@ -49,7 +49,7 @@ static wchar_t* fghWstrFromStr(const char* str)
/*
* TODO BEFORE THE STABLE RELEASE:
*
* fgChooseVisual() -- OK, but what about glutInitDisplayString()?
* fgChooseFBConfig() -- OK, but what about glutInitDisplayString()?
* fgSetupPixelFormat -- ignores the display mode settings
* fgOpenWindow() -- check the Win32 version, -iconic handling!
* fgCloseWindow() -- check the Win32 version
@ -76,10 +76,8 @@ static wchar_t* fghWstrFromStr(const char* str)
*/
#if TARGET_HOST_POSIX_X11
XVisualInfo* fgChooseVisual( void )
GLXFBConfig* fgChooseFBConfig( void )
{
#define BUFFER_SIZES 6
int bufferSize[BUFFER_SIZES] = { 16, 12, 8, 4, 2, 1 };
GLboolean wantIndexedMode = GL_FALSE;
int attributes[ 32 ];
int where = 0;
@ -95,11 +93,13 @@ XVisualInfo* fgChooseVisual( void )
if( fgState.DisplayMode & GLUT_INDEX )
{
ATTRIB_VAL( GLX_BUFFER_SIZE, 8 );
/* Buffer size is selected later. */
ATTRIB_VAL( GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT );
wantIndexedMode = GL_TRUE;
}
else
{
ATTRIB( GLX_RGBA );
ATTRIB_VAL( GLX_RED_SIZE, 1 );
ATTRIB_VAL( GLX_GREEN_SIZE, 1 );
ATTRIB_VAL( GLX_BLUE_SIZE, 1 );
@ -108,10 +108,10 @@ XVisualInfo* fgChooseVisual( void )
}
if( fgState.DisplayMode & GLUT_DOUBLE )
ATTRIB( GLX_DOUBLEBUFFER );
ATTRIB_VAL( GLX_DOUBLEBUFFER, True );
if( fgState.DisplayMode & GLUT_STEREO )
ATTRIB( GLX_STEREO );
ATTRIB_VAL( GLX_STEREO, True );
if( fgState.DisplayMode & GLUT_DEPTH )
ATTRIB_VAL( GLX_DEPTH_SIZE, 1 );
@ -137,34 +137,116 @@ XVisualInfo* fgChooseVisual( void )
if( fgState.DisplayMode & GLUT_AUX4 )
ATTRIB_VAL( GLX_AUX_BUFFERS, 4 );
if ( fgState.DisplayMode & GLUT_MULTISAMPLE )
ATTRIB_VAL( GLX_SAMPLES_SGIS, 4 );
{
ATTRIB_VAL( GLX_SAMPLE_BUFFERS, 1 );
}
/* Push a null at the end of the list */
ATTRIB( None );
if( ! wantIndexedMode )
return glXChooseVisual( fgDisplay.Display, fgDisplay.Screen,
attributes );
else
{
XVisualInfo* visualInfo;
int i;
GLXFBConfig * fbconfigArray; /* Array of FBConfigs */
GLXFBConfig * fbconfig; /* The FBConfig we want */
int fbconfigArraySize; /* Number of FBConfigs in the array */
/*
* In indexed mode, we need to check how many bits of depth can we
* achieve. We do this by trying each possibility from the list
* given in the {bufferSize} array. If we match, we return to caller.
*/
for( i=0; i<BUFFER_SIZES; i++ )
/* Get all FBConfigs that match "attributes". */
fbconfigArray = glXChooseFBConfig( fgDisplay.Display,
fgDisplay.Screen,
attributes,
&fbconfigArraySize );
if (fbconfigArray != NULL)
{
attributes[ 1 ] = bufferSize[ i ];
visualInfo = glXChooseVisual( fgDisplay.Display, fgDisplay.Screen,
attributes );
if( visualInfo != NULL )
return visualInfo;
int result; /* Returned by glXGetFBConfigAttrib, not checked. */
if( wantIndexedMode )
{
/*
* In index mode, we want the largest buffer size, i.e. visual
* depth. Here, FBConfigs are sorted by increasing buffer size
* first, so FBConfigs with the largest size come last.
*/
int bufferSizeMin, bufferSizeMax;
/* Get bufferSizeMin. */
result =
glXGetFBConfigAttrib( fgDisplay.Display,
fbconfigArray[0],
GLX_BUFFER_SIZE,
&bufferSizeMin );
/* Get bufferSizeMax. */
result =
glXGetFBConfigAttrib( fgDisplay.Display,
fbconfigArray[fbconfigArraySize - 1],
GLX_BUFFER_SIZE,
&bufferSizeMax );
if (bufferSizeMax > bufferSizeMin)
{
/*
* Free and reallocate fbconfigArray, keeping only FBConfigs
* with the largest buffer size.
*/
XFree(fbconfigArray);
/* Add buffer size token at the end of the list. */
where--;
ATTRIB_VAL( GLX_BUFFER_SIZE, bufferSizeMax );
ATTRIB( None );
fbconfigArray = glXChooseFBConfig( fgDisplay.Display,
fgDisplay.Screen,
attributes,
&fbconfigArraySize );
}
}
/*
* We now have an array of FBConfigs, the first one being the "best"
* one. So we should return only this FBConfig:
*
* int fbconfigXID;
*
* - pick the XID of the FBConfig we want
* result = glXGetFBConfigAttrib( fgDisplay.Display,
* fbconfigArray[0],
* GLX_FBCONFIG_ID,
* &fbconfigXID );
*
* - free the array
* XFree(fbconfigArray);
*
* - reset "attributes" with the XID
* where = 0;
* ATTRIB_VAL( GLX_FBCONFIG_ID, fbconfigXID );
* ATTRIB( None );
*
* - get our FBConfig only
* fbconfig = glXChooseFBConfig( fgDisplay.Display,
* fgDisplay.Screen,
* attributes,
* &fbconfigArraySize );
*
* However, for some configurations (for instance multisampling with
* Mesa 6.5.2 and ATI drivers), this does not work:
* glXChooseFBConfig returns NULL, whereas fbconfigXID is a valid
* XID. Further investigation is needed.
*
* So, for now, we return the whole array of FBConfigs. This should
* not produce any side effects elsewhere.
*/
fbconfig = fbconfigArray;
}
return NULL;
else
{
fbconfig = NULL;
}
return fbconfig;
}
}
#endif
@ -372,9 +454,10 @@ void fgSetWindow ( SFG_Window *window )
{
#if TARGET_HOST_POSIX_X11
if ( window )
glXMakeCurrent(
glXMakeContextCurrent(
fgDisplay.Display,
window->Window.Handle,
window->Window.Handle,
window->Window.Context
);
#elif TARGET_HOST_MS_WINDOWS
@ -405,46 +488,52 @@ void fgOpenWindow( SFG_Window* window, const char* title,
GLboolean gameMode, GLboolean isSubWindow )
{
#if TARGET_HOST_POSIX_X11
XVisualInfo * visualInfo;
XSetWindowAttributes winAttr;
XTextProperty textProperty;
XSizeHints sizeHints;
XWMHints wmHints;
unsigned long mask;
int renderType; /* GLX_RGBA_TYPE or GLX_COLOR_INDEX_TYPE */
unsigned int current_DisplayMode = fgState.DisplayMode ;
/* Save the display mode if we are creating a menu window */
if( window->IsMenu && ( ! fgStructure.MenuContext ) )
fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;
window->Window.VisualInfo = fgChooseVisual( );
window->Window.FBConfig = fgChooseFBConfig( );
if( window->IsMenu && ( ! fgStructure.MenuContext ) )
fgState.DisplayMode = current_DisplayMode ;
if( ! window->Window.VisualInfo )
if( ! window->Window.FBConfig )
{
/*
* The "fgChooseVisual" returned a null meaning that the visual
* The "fgChooseFBConfig" returned a null meaning that the visual
* context is not available.
* Try a couple of variations to see if they will work.
*/
if( !( fgState.DisplayMode & GLUT_DOUBLE ) )
{
fgState.DisplayMode |= GLUT_DOUBLE ;
window->Window.VisualInfo = fgChooseVisual( );
window->Window.FBConfig = fgChooseFBConfig( );
fgState.DisplayMode &= ~GLUT_DOUBLE;
}
if( fgState.DisplayMode & GLUT_MULTISAMPLE )
{
fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
window->Window.VisualInfo = fgChooseVisual( );
window->Window.FBConfig = fgChooseFBConfig( );
fgState.DisplayMode |= GLUT_MULTISAMPLE;
}
}
FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL,
"Visual with necessary capabilities not found", "fgOpenWindow" );
FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.FBConfig != NULL,
"FBConfig with necessary capabilities not found", "fgOpenWindow" );
/* Get the X visual. */
visualInfo = glXGetVisualFromFBConfig( fgDisplay.Display,
*(window->Window.FBConfig) );
/*
* XXX HINT: the masks should be updated when adding/removing callbacks.
@ -467,7 +556,7 @@ void fgOpenWindow( SFG_Window* window, const char* title,
winAttr.colormap = XCreateColormap(
fgDisplay.Display, fgDisplay.RootWindow,
window->Window.VisualInfo->visual, AllocNone
visualInfo->visual, AllocNone
);
mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
@ -488,8 +577,8 @@ void fgOpenWindow( SFG_Window* window, const char* title,
window->Parent == NULL ? fgDisplay.RootWindow :
window->Parent->Window.Handle,
x, y, w, h, 0,
window->Window.VisualInfo->depth, InputOutput,
window->Window.VisualInfo->visual, mask,
visualInfo->depth, InputOutput,
visualInfo->visual, mask,
&winAttr
);
@ -497,6 +586,22 @@ void fgOpenWindow( SFG_Window* window, const char* title,
* The GLX context creation, possibly trying the direct context rendering
* or else use the current context if the user has so specified
*/
/* Set renderType. */
if( window->IsMenu && ( ! fgStructure.MenuContext ) )
{
/* Display mode has been set to GLUT_RGB. */
renderType = GLX_RGBA_TYPE;
}
else if (fgState.DisplayMode & GLUT_INDEX)
{
renderType = GLX_COLOR_INDEX_TYPE;
}
else
{
renderType = GLX_RGBA_TYPE;
}
if( window->IsMenu )
{
/*
@ -507,16 +612,15 @@ void fgOpenWindow( SFG_Window* window, const char* title,
{
fgStructure.MenuContext =
(SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
fgStructure.MenuContext->MVisualInfo = window->Window.VisualInfo;
fgStructure.MenuContext->MContext = glXCreateContext(
fgDisplay.Display, fgStructure.MenuContext->MVisualInfo,
fgStructure.MenuContext->Context = glXCreateNewContext(
fgDisplay.Display, *(window->Window.FBConfig), renderType,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
);
}
/* window->Window.Context = fgStructure.MenuContext->MContext; */
window->Window.Context = glXCreateContext(
fgDisplay.Display, window->Window.VisualInfo,
fgDisplay.Display, window->Window.FBConfig, renderType,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
);
}
@ -525,14 +629,14 @@ void fgOpenWindow( SFG_Window* window, const char* title,
window->Window.Context = glXGetCurrentContext( );
if( ! window->Window.Context )
window->Window.Context = glXCreateContext(
fgDisplay.Display, window->Window.VisualInfo,
window->Window.Context = glXCreateNewContext(
fgDisplay.Display, window->Window.FBConfig, renderType,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
);
}
else
window->Window.Context = glXCreateContext(
fgDisplay.Display, window->Window.VisualInfo,
window->Window.Context = glXCreateNewContext(
fgDisplay.Display, window->Window.FBConfig, renderType,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
);
@ -594,14 +698,17 @@ void fgOpenWindow( SFG_Window* window, const char* title,
XSetWMProtocols( fgDisplay.Display, window->Window.Handle,
&fgDisplay.DeleteWindow, 1 );
glXMakeCurrent(
glXMakeContextCurrent(
fgDisplay.Display,
window->Window.Handle,
window->Window.Handle,
window->Window.Context
);
XMapWindow( fgDisplay.Display, window->Window.Handle );
XFree(visualInfo);
#elif TARGET_HOST_MS_WINDOWS
WNDCLASS wc;