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 */ SFG_WindowContextType Context; /* The window's OpenGL/WGL context */
#if TARGET_HOST_POSIX_X11 #if TARGET_HOST_POSIX_X11
XVisualInfo* VisualInfo; /* The window's visual information */ GLXFBConfig* FBConfig; /* The window's FBConfig */
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
HDC Device; /* The window's device context */ HDC Device; /* The window's device context */
#endif #endif
@ -556,10 +556,6 @@ enum
typedef struct tagSFG_MenuContext SFG_MenuContext; typedef struct tagSFG_MenuContext SFG_MenuContext;
struct tagSFG_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 */ 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 */ /* A helper function to check if a display mode is possible to use */
#if TARGET_HOST_POSIX_X11 #if TARGET_HOST_POSIX_X11
XVisualInfo* fgChooseVisual( void ); GLXFBConfig* fgChooseFBConfig( void );
#endif #endif
/* The window procedure for Win32 events handling */ /* The window procedure for Win32 events handling */

View File

@ -52,10 +52,13 @@
static int fghGetConfig( int attribute ) static int fghGetConfig( int attribute )
{ {
int returnValue = 0; int returnValue = 0;
int result; /* Not checked */
if( fgStructure.CurrentWindow ) if( fgStructure.CurrentWindow )
glXGetConfig( fgDisplay.Display, fgStructure.CurrentWindow->Window.VisualInfo, result = glXGetFBConfigAttrib( fgDisplay.Display,
attribute, &returnValue ); *(fgStructure.CurrentWindow->Window.FBConfig),
attribute,
&returnValue );
return returnValue; return returnValue;
} }
@ -213,7 +216,20 @@ int FGAPIENTRY glutGet( GLenum eWhat )
*/ */
return 0; 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() * 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 */ /* I do not know yet if there will be a fgChooseVisual() function for Win32 */
case GLUT_DISPLAY_MODE_POSSIBLE: case GLUT_DISPLAY_MODE_POSSIBLE:
{ {
XVisualInfo* visualInfo = fgChooseVisual(); /* We should not have to call fgChooseFBConfig again here. */
if ( visualInfo == NULL ) { GLXFBConfig * fbconfig;
return 0; int isPossible;
} else {
XFree( visualInfo ); fbconfig = fgChooseFBConfig();
return 1;
if (fbconfig == NULL)
{
isPossible = 0;
} }
else
{
isPossible = 1;
XFree(fbconfig);
}
return isPossible;
} }
/* This is system-dependant */ /* This is system-dependant */
@ -292,7 +318,7 @@ int FGAPIENTRY glutGet( GLenum eWhat )
if( fgStructure.CurrentWindow == NULL ) if( fgStructure.CurrentWindow == NULL )
return 0; return 0;
return fgStructure.CurrentWindow->Window.VisualInfo->visualid; return fghGetConfig( GLX_VISUAL_ID );
#elif TARGET_HOST_MS_WINDOWS #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 */ /* Have the window object created */
SFG_Window *window = (SFG_Window *)calloc( sizeof(SFG_Window), 1 ); SFG_Window *window = (SFG_Window *)calloc( sizeof(SFG_Window), 1 );
#if TARGET_HOST_UNIX_X11
window->Window.FBConfig = NULL;
#endif
fghClearCallBacks( window ); fghClearCallBacks( window );
/* Initialize the object properties */ /* Initialize the object properties */
@ -216,6 +219,12 @@ void fgDestroyWindow( SFG_Window* window )
fghClearCallBacks( window ); fghClearCallBacks( window );
fgCloseWindow( window ); fgCloseWindow( window );
#if TARGET_HOST_UNIX_X11
if (window->Window.FBConfig != NULL)
{
XFree( window->Window.FBConfig );
}
#endif
free( window ); free( window );
if( fgStructure.CurrentWindow == window ) if( fgStructure.CurrentWindow == window )
fgStructure.CurrentWindow = NULL; fgStructure.CurrentWindow = NULL;

View File

@ -49,7 +49,7 @@ static wchar_t* fghWstrFromStr(const char* str)
/* /*
* TODO BEFORE THE STABLE RELEASE: * TODO BEFORE THE STABLE RELEASE:
* *
* fgChooseVisual() -- OK, but what about glutInitDisplayString()? * fgChooseFBConfig() -- OK, but what about glutInitDisplayString()?
* fgSetupPixelFormat -- ignores the display mode settings * fgSetupPixelFormat -- ignores the display mode settings
* fgOpenWindow() -- check the Win32 version, -iconic handling! * fgOpenWindow() -- check the Win32 version, -iconic handling!
* fgCloseWindow() -- check the Win32 version * fgCloseWindow() -- check the Win32 version
@ -76,10 +76,8 @@ static wchar_t* fghWstrFromStr(const char* str)
*/ */
#if TARGET_HOST_POSIX_X11 #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; GLboolean wantIndexedMode = GL_FALSE;
int attributes[ 32 ]; int attributes[ 32 ];
int where = 0; int where = 0;
@ -95,11 +93,13 @@ XVisualInfo* fgChooseVisual( void )
if( fgState.DisplayMode & GLUT_INDEX ) if( fgState.DisplayMode & GLUT_INDEX )
{ {
ATTRIB_VAL( GLX_BUFFER_SIZE, 8 ); ATTRIB_VAL( GLX_BUFFER_SIZE, 8 );
/* Buffer size is selected later. */
ATTRIB_VAL( GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT );
wantIndexedMode = GL_TRUE; wantIndexedMode = GL_TRUE;
} }
else else
{ {
ATTRIB( GLX_RGBA );
ATTRIB_VAL( GLX_RED_SIZE, 1 ); ATTRIB_VAL( GLX_RED_SIZE, 1 );
ATTRIB_VAL( GLX_GREEN_SIZE, 1 ); ATTRIB_VAL( GLX_GREEN_SIZE, 1 );
ATTRIB_VAL( GLX_BLUE_SIZE, 1 ); ATTRIB_VAL( GLX_BLUE_SIZE, 1 );
@ -108,10 +108,10 @@ XVisualInfo* fgChooseVisual( void )
} }
if( fgState.DisplayMode & GLUT_DOUBLE ) if( fgState.DisplayMode & GLUT_DOUBLE )
ATTRIB( GLX_DOUBLEBUFFER ); ATTRIB_VAL( GLX_DOUBLEBUFFER, True );
if( fgState.DisplayMode & GLUT_STEREO ) if( fgState.DisplayMode & GLUT_STEREO )
ATTRIB( GLX_STEREO ); ATTRIB_VAL( GLX_STEREO, True );
if( fgState.DisplayMode & GLUT_DEPTH ) if( fgState.DisplayMode & GLUT_DEPTH )
ATTRIB_VAL( GLX_DEPTH_SIZE, 1 ); ATTRIB_VAL( GLX_DEPTH_SIZE, 1 );
@ -137,34 +137,116 @@ XVisualInfo* fgChooseVisual( void )
if( fgState.DisplayMode & GLUT_AUX4 ) if( fgState.DisplayMode & GLUT_AUX4 )
ATTRIB_VAL( GLX_AUX_BUFFERS, 4 ); ATTRIB_VAL( GLX_AUX_BUFFERS, 4 );
if ( fgState.DisplayMode & GLUT_MULTISAMPLE ) 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 */ /* Push a null at the end of the list */
ATTRIB( None ); ATTRIB( None );
if( ! wantIndexedMode )
return glXChooseVisual( fgDisplay.Display, fgDisplay.Screen,
attributes );
else
{ {
XVisualInfo* visualInfo; GLXFBConfig * fbconfigArray; /* Array of FBConfigs */
int i; GLXFBConfig * fbconfig; /* The FBConfig we want */
int fbconfigArraySize; /* Number of FBConfigs in the array */
/* Get all FBConfigs that match "attributes". */
fbconfigArray = glXChooseFBConfig( fgDisplay.Display,
fgDisplay.Screen,
attributes,
&fbconfigArraySize );
if (fbconfigArray != NULL)
{
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 );
}
}
/* /*
* In indexed mode, we need to check how many bits of depth can we * We now have an array of FBConfigs, the first one being the "best"
* achieve. We do this by trying each possibility from the list * one. So we should return only this FBConfig:
* given in the {bufferSize} array. If we match, we return to caller. *
* 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.
*/ */
for( i=0; i<BUFFER_SIZES; i++ ) fbconfig = fbconfigArray;
{
attributes[ 1 ] = bufferSize[ i ];
visualInfo = glXChooseVisual( fgDisplay.Display, fgDisplay.Screen,
attributes );
if( visualInfo != NULL )
return visualInfo;
} }
return NULL; else
{
fbconfig = NULL;
}
return fbconfig;
} }
} }
#endif #endif
@ -372,9 +454,10 @@ void fgSetWindow ( SFG_Window *window )
{ {
#if TARGET_HOST_POSIX_X11 #if TARGET_HOST_POSIX_X11
if ( window ) if ( window )
glXMakeCurrent( glXMakeContextCurrent(
fgDisplay.Display, fgDisplay.Display,
window->Window.Handle, window->Window.Handle,
window->Window.Handle,
window->Window.Context window->Window.Context
); );
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
@ -405,46 +488,52 @@ void fgOpenWindow( SFG_Window* window, const char* title,
GLboolean gameMode, GLboolean isSubWindow ) GLboolean gameMode, GLboolean isSubWindow )
{ {
#if TARGET_HOST_POSIX_X11 #if TARGET_HOST_POSIX_X11
XVisualInfo * visualInfo;
XSetWindowAttributes winAttr; XSetWindowAttributes winAttr;
XTextProperty textProperty; XTextProperty textProperty;
XSizeHints sizeHints; XSizeHints sizeHints;
XWMHints wmHints; XWMHints wmHints;
unsigned long mask; unsigned long mask;
int renderType; /* GLX_RGBA_TYPE or GLX_COLOR_INDEX_TYPE */
unsigned int current_DisplayMode = fgState.DisplayMode ; unsigned int current_DisplayMode = fgState.DisplayMode ;
/* Save the display mode if we are creating a menu window */ /* Save the display mode if we are creating a menu window */
if( window->IsMenu && ( ! fgStructure.MenuContext ) ) if( window->IsMenu && ( ! fgStructure.MenuContext ) )
fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ; fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;
window->Window.VisualInfo = fgChooseVisual( ); window->Window.FBConfig = fgChooseFBConfig( );
if( window->IsMenu && ( ! fgStructure.MenuContext ) ) if( window->IsMenu && ( ! fgStructure.MenuContext ) )
fgState.DisplayMode = current_DisplayMode ; 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. * context is not available.
* Try a couple of variations to see if they will work. * Try a couple of variations to see if they will work.
*/ */
if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) if( !( fgState.DisplayMode & GLUT_DOUBLE ) )
{ {
fgState.DisplayMode |= GLUT_DOUBLE ; fgState.DisplayMode |= GLUT_DOUBLE ;
window->Window.VisualInfo = fgChooseVisual( ); window->Window.FBConfig = fgChooseFBConfig( );
fgState.DisplayMode &= ~GLUT_DOUBLE; fgState.DisplayMode &= ~GLUT_DOUBLE;
} }
if( fgState.DisplayMode & GLUT_MULTISAMPLE ) if( fgState.DisplayMode & GLUT_MULTISAMPLE )
{ {
fgState.DisplayMode &= ~GLUT_MULTISAMPLE ; fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
window->Window.VisualInfo = fgChooseVisual( ); window->Window.FBConfig = fgChooseFBConfig( );
fgState.DisplayMode |= GLUT_MULTISAMPLE; fgState.DisplayMode |= GLUT_MULTISAMPLE;
} }
} }
FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL, FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.FBConfig != NULL,
"Visual with necessary capabilities not found", "fgOpenWindow" ); "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. * 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( winAttr.colormap = XCreateColormap(
fgDisplay.Display, fgDisplay.RootWindow, fgDisplay.Display, fgDisplay.RootWindow,
window->Window.VisualInfo->visual, AllocNone visualInfo->visual, AllocNone
); );
mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
@ -488,8 +577,8 @@ void fgOpenWindow( SFG_Window* window, const char* title,
window->Parent == NULL ? fgDisplay.RootWindow : window->Parent == NULL ? fgDisplay.RootWindow :
window->Parent->Window.Handle, window->Parent->Window.Handle,
x, y, w, h, 0, x, y, w, h, 0,
window->Window.VisualInfo->depth, InputOutput, visualInfo->depth, InputOutput,
window->Window.VisualInfo->visual, mask, visualInfo->visual, mask,
&winAttr &winAttr
); );
@ -497,6 +586,22 @@ void fgOpenWindow( SFG_Window* window, const char* title,
* The GLX context creation, possibly trying the direct context rendering * The GLX context creation, possibly trying the direct context rendering
* or else use the current context if the user has so specified * 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 ) if( window->IsMenu )
{ {
/* /*
@ -507,16 +612,15 @@ void fgOpenWindow( SFG_Window* window, const char* title,
{ {
fgStructure.MenuContext = fgStructure.MenuContext =
(SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
fgStructure.MenuContext->MVisualInfo = window->Window.VisualInfo; fgStructure.MenuContext->Context = glXCreateNewContext(
fgStructure.MenuContext->MContext = glXCreateContext( fgDisplay.Display, *(window->Window.FBConfig), renderType,
fgDisplay.Display, fgStructure.MenuContext->MVisualInfo,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
); );
} }
/* window->Window.Context = fgStructure.MenuContext->MContext; */ /* window->Window.Context = fgStructure.MenuContext->MContext; */
window->Window.Context = glXCreateContext( window->Window.Context = glXCreateContext(
fgDisplay.Display, window->Window.VisualInfo, fgDisplay.Display, window->Window.FBConfig, renderType,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
); );
} }
@ -525,14 +629,14 @@ void fgOpenWindow( SFG_Window* window, const char* title,
window->Window.Context = glXGetCurrentContext( ); window->Window.Context = glXGetCurrentContext( );
if( ! window->Window.Context ) if( ! window->Window.Context )
window->Window.Context = glXCreateContext( window->Window.Context = glXCreateNewContext(
fgDisplay.Display, window->Window.VisualInfo, fgDisplay.Display, window->Window.FBConfig, renderType,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
); );
} }
else else
window->Window.Context = glXCreateContext( window->Window.Context = glXCreateNewContext(
fgDisplay.Display, window->Window.VisualInfo, fgDisplay.Display, window->Window.FBConfig, renderType,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) 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, XSetWMProtocols( fgDisplay.Display, window->Window.Handle,
&fgDisplay.DeleteWindow, 1 ); &fgDisplay.DeleteWindow, 1 );
glXMakeCurrent( glXMakeContextCurrent(
fgDisplay.Display, fgDisplay.Display,
window->Window.Handle, window->Window.Handle,
window->Window.Handle,
window->Window.Context window->Window.Context
); );
XMapWindow( fgDisplay.Display, window->Window.Handle ); XMapWindow( fgDisplay.Display, window->Window.Handle );
XFree(visualInfo);
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
WNDCLASS wc; WNDCLASS wc;