Use XParseGeometry for better geometry parsing.
Moved geometry parsing to after fgInitialize() so we can use the screen size to correctly calculate negative positions in the geometry string. Copied the code for XParseGeometry from the X11 sources for use in the Win32 version. freeglut now passes test1 of the glut test suite. git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@355 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
parent
d161195cb4
commit
d906368add
@ -299,6 +299,148 @@ void fgDeinitialize( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Everything inside the following #ifndef is copied from the X sources.
|
||||
*/
|
||||
|
||||
#ifndef TARGET_HOST_UNIX_X11
|
||||
|
||||
#define NoValue 0x0000
|
||||
#define XValue 0x0001
|
||||
#define YValue 0x0002
|
||||
#define WidthValue 0x0004
|
||||
#define HeightValue 0x0008
|
||||
#define AllValues 0x000F
|
||||
#define XNegative 0x0010
|
||||
#define YNegative 0x0020
|
||||
|
||||
/*
|
||||
* XParseGeometry parses strings of the form
|
||||
* "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
|
||||
* width, height, xoffset, and yoffset are unsigned integers.
|
||||
* Example: "=80x24+300-49"
|
||||
* The equal sign is optional.
|
||||
* It returns a bitmask that indicates which of the four values
|
||||
* were actually found in the string. For each value found,
|
||||
* the corresponding argument is updated; for each value
|
||||
* not found, the corresponding argument is left unchanged.
|
||||
*/
|
||||
|
||||
static int
|
||||
ReadInteger(char *string, char **NextString)
|
||||
{
|
||||
register int Result = 0;
|
||||
int Sign = 1;
|
||||
|
||||
if (*string == '+')
|
||||
string++;
|
||||
else if (*string == '-')
|
||||
{
|
||||
string++;
|
||||
Sign = -1;
|
||||
}
|
||||
for (; (*string >= '0') && (*string <= '9'); string++)
|
||||
{
|
||||
Result = (Result * 10) + (*string - '0');
|
||||
}
|
||||
*NextString = string;
|
||||
if (Sign >= 0)
|
||||
return (Result);
|
||||
else
|
||||
return (-Result);
|
||||
}
|
||||
|
||||
static int XParseGeometry (
|
||||
_Xconst char *string,
|
||||
int *x,
|
||||
int *y,
|
||||
unsigned int *width, /* RETURN */
|
||||
unsigned int *height) /* RETURN */
|
||||
{
|
||||
int mask = NoValue;
|
||||
register char *strind;
|
||||
unsigned int tempWidth = 0, tempHeight = 0;
|
||||
int tempX = 0, tempY = 0;
|
||||
char *nextCharacter;
|
||||
|
||||
if ( (string == NULL) || (*string == '\0')) return(mask);
|
||||
if (*string == '=')
|
||||
string++; /* ignore possible '=' at beg of geometry spec */
|
||||
|
||||
strind = (char *)string;
|
||||
if (*strind != '+' && *strind != '-' && *strind != 'x') {
|
||||
tempWidth = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= WidthValue;
|
||||
}
|
||||
|
||||
if (*strind == 'x' || *strind == 'X') {
|
||||
strind++;
|
||||
tempHeight = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= HeightValue;
|
||||
}
|
||||
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempX = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= XNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{ strind++;
|
||||
tempX = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= XValue;
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempY = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
mask |= YNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
strind++;
|
||||
tempY = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= YValue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If strind isn't at the end of the string the it's an invalid
|
||||
geometry specification. */
|
||||
|
||||
if (*strind != '\0') return (0);
|
||||
|
||||
if (mask & XValue)
|
||||
*x = tempX;
|
||||
if (mask & YValue)
|
||||
*y = tempY;
|
||||
if (mask & WidthValue)
|
||||
*width = tempWidth;
|
||||
if (mask & HeightValue)
|
||||
*height = tempHeight;
|
||||
return (mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
@ -309,6 +451,7 @@ void fgDeinitialize( void )
|
||||
void FGAPIENTRY glutInit( int* pargc, char** argv )
|
||||
{
|
||||
char* displayName = NULL;
|
||||
char* geometry = NULL;
|
||||
int i, j, argc = *pargc;
|
||||
|
||||
if (pargc && *pargc && argv && *argv && **argv)
|
||||
@ -336,14 +479,7 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_HOST_WIN32
|
||||
if( !getenv( "DISPLAY" ) )
|
||||
displayName = strdup( "" );
|
||||
else
|
||||
#endif
|
||||
displayName = strdup( getenv( "DISPLAY" ) );
|
||||
if( !displayName )
|
||||
fgError( "Could not allocate space for display name." );
|
||||
displayName = getenv( "DISPLAY");
|
||||
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
@ -352,12 +488,7 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
|
||||
if( ++i >= argc )
|
||||
fgError( "-display parameter must be followed by display name" );
|
||||
|
||||
if( displayName )
|
||||
free( displayName );
|
||||
displayName = strdup( argv[ i ] );
|
||||
if( !displayName )
|
||||
fgError( "Could not allocate space for display name (%s)",
|
||||
argv [ i ] );
|
||||
displayName = argv[ i ];
|
||||
|
||||
argv[ i - 1 ] = NULL;
|
||||
argv[ i ] = NULL;
|
||||
@ -365,36 +496,11 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
|
||||
}
|
||||
else if( strcmp( argv[ i ], "-geometry" ) == 0 )
|
||||
{
|
||||
int result, x, y;
|
||||
unsigned int w, h;
|
||||
|
||||
if( ++i >= argc )
|
||||
fgError( "-geometry parameter must be followed by window "
|
||||
"geometry settings" );
|
||||
result = sscanf( argv[ i ], "%dx%d+%d+%d", &x, &y, &w, &h );
|
||||
|
||||
if( result > 3 )
|
||||
fgState.Size.Y = h;
|
||||
if( result > 2 )
|
||||
fgState.Size.X = w;
|
||||
|
||||
if( result > 1 )
|
||||
{
|
||||
if( y < 0 )
|
||||
fgState.Position.Y =
|
||||
fgDisplay.ScreenHeight + y - fgState.Size.Y;
|
||||
else
|
||||
fgState.Position.Y = y;
|
||||
}
|
||||
|
||||
if( result > 0 )
|
||||
{
|
||||
if( x < 0 )
|
||||
fgState.Position.X =
|
||||
fgDisplay.ScreenWidth + x - fgState.Size.X;
|
||||
else
|
||||
fgState.Position.X = x;
|
||||
}
|
||||
geometry = argv[ i ];
|
||||
|
||||
argv[ i - 1 ] = NULL;
|
||||
argv[ i ] = NULL;
|
||||
@ -469,55 +575,57 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
|
||||
fgInitialize( displayName );
|
||||
|
||||
/*
|
||||
* Check for the minus one settings for both position and size...
|
||||
* Geometry parsing deffered until here because we may need the screen
|
||||
* size.
|
||||
*/
|
||||
if( fgState.Position.X < 0 || fgState.Position.Y < 0 )
|
||||
fgState.Position.Use = GL_FALSE;
|
||||
|
||||
if( fgState.Size.X < 0 || fgState.Size.Y < 0 )
|
||||
fgState.Size.Use = GL_FALSE;
|
||||
if (geometry )
|
||||
{
|
||||
int mask = XParseGeometry( geometry,
|
||||
&fgState.Position.X, &fgState.Position.Y,
|
||||
&fgState.Size.X, &fgState.Size.Y );
|
||||
|
||||
if( displayName )
|
||||
free( displayName );
|
||||
if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
|
||||
fgState.Size.Use = GL_TRUE;
|
||||
|
||||
if( mask & XNegative )
|
||||
fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
|
||||
|
||||
if( mask & YNegative )
|
||||
fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
|
||||
|
||||
if( (mask & (XValue|YValue)) == (XValue|YValue) )
|
||||
fgState.Position.Use = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the default initial window position for new windows
|
||||
*/
|
||||
void FGAPIENTRY glutInitWindowPosition( int x, int y )
|
||||
{
|
||||
if( ( x >= 0 ) && ( y >= 0 ) )
|
||||
{
|
||||
fgState.Position.X = x;
|
||||
fgState.Position.Y = y;
|
||||
|
||||
if( ( x >= 0 ) && ( y >= 0 ) )
|
||||
fgState.Position.Use = GL_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgState.Position.X = -1;
|
||||
fgState.Position.Y = -1;
|
||||
fgState.Position.Use = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the default initial window size for new windows
|
||||
*/
|
||||
void FGAPIENTRY glutInitWindowSize( int width, int height )
|
||||
{
|
||||
if( ( width > 0 ) && ( height > 0 ) )
|
||||
{
|
||||
fgState.Size.X = width;
|
||||
fgState.Size.Y = height;
|
||||
|
||||
if( ( width > 0 ) && ( height > 0 ) )
|
||||
fgState.Size.Use = GL_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgState.Size.X = -1;
|
||||
fgState.Size.Y = -1;
|
||||
fgState.Size.Use = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the default display mode for all new windows
|
||||
|
Reference in New Issue
Block a user