// File: tomfunkhouser[P]gaps/pkgs/fglut/freeglut_init.c
// Function: glutInit
void FGAPIENTRY glutInit( int* pargc, char** argv )
{
    char* displayName = NULL;
    char* geometry = NULL;
    int i, j, argc = *pargc;

    /* will return true for VC8 (VC2005) and higher */
#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
    size_t sLen;
#if HAVE_ERRNO
    errno_t err;
#endif
#endif

    if( fgState.Initialised )
        fgError( "illegal glutInit() reinitialization attempt" );

    if (pargc && *pargc && argv && *argv && **argv)
    {
        fgState.ProgramName = strdup (*argv);

        if( !fgState.ProgramName )
            fgError ("Could not allocate space for the program's name.");
    }

    fgCreateStructure( );

    /* Get start time */
    fgState.Time = fgSystemTime();

    /* check if GLUT_FPS env var is set */
#ifndef _WIN32_WCE
    {
    /* will return true for VC8 (VC2005) and higher */
#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) && HAVE_ERRNO
        char* fps = NULL;
        err = _dupenv_s( &fps, &sLen, "GLUT_FPS" );
        if (err)
            fgError("Error getting GLUT_FPS environment variable"); 
#else
        const char *fps = getenv( "GLUT_FPS" );
#endif
        if( fps )
        {
            int interval;
            sscanf( fps, "%d", &interval );

            if( interval <= 0 )
                fgState.FPSInterval = 5000;  /* 5000 millisecond default */
            else
                fgState.FPSInterval = interval;
        }
    /* will return true for VC8 (VC2005) and higher */
#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) && HAVE_ERRNO
        free ( fps );  fps = NULL;  /* dupenv_s allocates a string that we must free */
#endif
    }

    /* will return true for VC8 (VC2005) and higher */
#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) && HAVE_ERRNO
    err = _dupenv_s( &displayName, &sLen, "DISPLAY" );
    if (err)
        fgError("Error getting DISPLAY environment variable");
#else
    displayName = getenv( "DISPLAY" );
#endif

    for( i = 1; i < argc; i++ )
    {
        if( strcmp( argv[ i ], "-display" ) == 0 )
        {
            if( ++i >= argc )
                fgError( "-display parameter must be followed by display name" );

            displayName = argv[ i ];

            argv[ i - 1 ] = NULL;
            argv[ i     ] = NULL;
            ( *pargc ) -= 2;
        }
        else if( strcmp( argv[ i ], "-geometry" ) == 0 )
        {
            if( ++i >= argc )
                fgError( "-geometry parameter must be followed by window "
                         "geometry settings" );

            geometry = argv[ i ];

            argv[ i - 1 ] = NULL;
            argv[ i     ] = NULL;
            ( *pargc ) -= 2;
        }
        else if( strcmp( argv[ i ], "-direct" ) == 0)
        {
            if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )
                fgError( "parameters ambiguity, -direct and -indirect "
                    "cannot be both specified" );

            fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;
            argv[ i ] = NULL;
            ( *pargc )--;
        }
        else if( strcmp( argv[ i ], "-indirect" ) == 0 )
        {
            if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
                fgError( "parameters ambiguity, -direct and -indirect "
                    "cannot be both specified" );

            fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;
            argv[ i ] = NULL;
            (*pargc)--;
        }
        else if( strcmp( argv[ i ], "-iconic" ) == 0 )
        {
            fgState.ForceIconic = GL_TRUE;
            argv[ i ] = NULL;
            ( *pargc )--;
        }
        else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
        {
            fgState.GLDebugSwitch = GL_TRUE;
            argv[ i ] = NULL;
            ( *pargc )--;
        }
        else if( strcmp( argv[ i ], "-sync" ) == 0 )
        {
            fgState.XSyncSwitch = GL_TRUE;
            argv[ i ] = NULL;
            ( *pargc )--;
        }
    }

    /* Compact {argv}. */
    for( i = j = 1; i < *pargc; i++, j++ )
    {
        /* Guaranteed to end because there are "*pargc" arguments left */
        while ( argv[ j ] == NULL )
            j++;
        if ( i != j )
            argv[ i ] = argv[ j ];
    }

#endif /* _WIN32_WCE */

    /*
     * Have the display created now. If there wasn't a "-display"
     * in the program arguments, we will use the DISPLAY environment
     * variable for opening the X display (see code above):
     */
    fghInitialize( displayName );
    /* will return true for VC8 (VC2005) and higher */
#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) && HAVE_ERRNO
    free ( displayName );  displayName = NULL;  /* dupenv_s allocates a string that we must free */
#endif

    /*
     * Geometry parsing deffered until here because we may need the screen
     * size.
     */

    if (geometry )
    {
        unsigned int parsedWidth = 0, parsedHeight = 0;
        int mask = XParseGeometry( geometry,
                                   &fgState.Position.X, &fgState.Position.Y,
                                   &parsedWidth, &parsedHeight );
        /* TODO: Check for overflow? */
        fgState.Size.X = parsedWidth;
        fgState.Size.Y = parsedHeight;

        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;
    }
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq $0x0, 0x30(%rsp)
movq $0x0, 0x28(%rsp)
movq 0x40(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x1c(%rsp)
cmpb $0x0, 0x7f18a(%rip)     # 0x1fa3ac
je 0x17b232
leaq 0x32e82(%rip), %rdi     # 0x1ae0ad
movb $0x0, %al
callq 0x17de70
cmpq $0x0, 0x40(%rsp)
je 0x17b295
movq 0x40(%rsp), %rax
cmpl $0x0, (%rax)
je 0x17b295
cmpq $0x0, 0x38(%rsp)
je 0x17b295
movq 0x38(%rsp), %rax
cmpq $0x0, (%rax)
je 0x17b295
movq 0x38(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x17b295
movq 0x38(%rsp), %rax
movq (%rax), %rdi
callq 0x23340
movq %rax, 0x7f1bd(%rip)     # 0x1fa438
cmpq $0x0, 0x7f1b5(%rip)     # 0x1fa438
jne 0x17b293
leaq 0x32e4d(%rip), %rdi     # 0x1ae0d9
movb $0x0, %al
callq 0x17de70
jmp 0x17b295
callq 0x182e10
callq 0x17de10
movq %rax, 0x7f12a(%rip)     # 0x1fa3d0
leaq 0x32e5d(%rip), %rdi     # 0x1ae10a
callq 0x22c70
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x10(%rsp)
je 0x17b2f6
movq 0x10(%rsp), %rdi
leaq 0x19c4f(%rip), %rsi     # 0x194f1a
leaq 0xc(%rsp), %rdx
movb $0x0, %al
callq 0x229a0
cmpl $0x0, 0xc(%rsp)
jg 0x17b2ea
movl $0x1388, 0x7f0d8(%rip)  # imm = 0x1388
jmp 0x17b2f4
movl 0xc(%rsp), %eax
movl %eax, 0x7f0cc(%rip)     # 0x1fa3c0
jmp 0x17b2f6
leaq 0x32e16(%rip), %rdi     # 0x1ae113
callq 0x22c70
movq %rax, 0x30(%rsp)
movl $0x1, 0x24(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x1c(%rsp), %eax
jge 0x17b5ea
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x32de9(%rip), %rsi     # 0x1ae11b
callq 0x22ec0
cmpl $0x0, %eax
jne 0x17b3a8
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
cmpl 0x1c(%rsp), %eax
jl 0x17b35b
leaq 0x32dd0(%rip), %rdi     # 0x1ae124
movb $0x0, %al
callq 0x17de70
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x30(%rsp)
movq 0x38(%rsp), %rax
movl 0x24(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x40(%rsp), %rax
movl (%rax), %ecx
subl $0x2, %ecx
movl %ecx, (%rax)
jmp 0x17b5d8
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x32d9b(%rip), %rsi     # 0x1ae158
callq 0x22ec0
cmpl $0x0, %eax
jne 0x17b433
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
cmpl 0x1c(%rsp), %eax
jl 0x17b3e6
leaq 0x32d83(%rip), %rdi     # 0x1ae162
movb $0x0, %al
callq 0x17de70
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x28(%rsp)
movq 0x38(%rsp), %rax
movl 0x24(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x40(%rsp), %rax
movl (%rax), %ecx
subl $0x2, %ecx
movl %ecx, (%rax)
jmp 0x17b5d6
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x32d5b(%rip), %rsi     # 0x1ae1a3
callq 0x22ec0
cmpl $0x0, %eax
jne 0x17b496
cmpl $0x0, 0x7ef57(%rip)     # 0x1fa3b0
jne 0x17b469
leaq 0x32d49(%rip), %rdi     # 0x1ae1ab
movb $0x0, %al
callq 0x17de70
movl $0x3, 0x7ef3d(%rip)     # 0x1fa3b0
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x40(%rsp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x17b5d4
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x32d45(%rip), %rsi     # 0x1ae1f0
callq 0x22ec0
cmpl $0x0, %eax
jne 0x17b4f9
cmpl $0x3, 0x7eef4(%rip)     # 0x1fa3b0
jne 0x17b4cc
leaq 0x32ce6(%rip), %rdi     # 0x1ae1ab
movb $0x0, %al
callq 0x17de70
movl $0x0, 0x7eeda(%rip)     # 0x1fa3b0
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x40(%rsp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x17b5d2
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x32cec(%rip), %rsi     # 0x1ae1fa
callq 0x22ec0
cmpl $0x0, %eax
jne 0x17b542
movb $0x1, 0x7ee95(%rip)     # 0x1fa3b4
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x40(%rsp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x17b5d0
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x32cab(%rip), %rsi     # 0x1ae202
callq 0x22ec0
cmpl $0x0, %eax
jne 0x17b588
movb $0x1, 0x7ee4e(%rip)     # 0x1fa3b6
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x40(%rsp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x17b5ce
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x32c6e(%rip), %rsi     # 0x1ae20b
callq 0x22ec0
cmpl $0x0, %eax
jne 0x17b5cc
movb $0x1, 0x7ee09(%rip)     # 0x1fa3b7
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x40(%rsp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x17b5ce
jmp 0x17b5d0
jmp 0x17b5d2
jmp 0x17b5d4
jmp 0x17b5d6
jmp 0x17b5d8
jmp 0x17b5da
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x17b30f
movl $0x1, 0x20(%rsp)
movl $0x1, 0x24(%rsp)
movl 0x24(%rsp), %eax
movq 0x40(%rsp), %rcx
cmpl (%rcx), %eax
jge 0x17b667
jmp 0x17b609
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x17b627
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x17b609
movl 0x24(%rsp), %eax
cmpl 0x20(%rsp), %eax
je 0x17b64d
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0x17b64f
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x17b5fa
movq 0x30(%rsp), %rdi
callq 0x17b740
cmpq $0x0, 0x28(%rsp)
je 0x17b732
movl $0x0, 0x8(%rsp)
movl $0x0, 0x4(%rsp)
movq 0x28(%rsp), %rdi
leaq 0x7ecf7(%rip), %rsi     # 0x1fa390
movq %rsi, %rdx
addq $0x4, %rdx
leaq 0x8(%rsp), %rcx
leaq 0x4(%rsp), %r8
callq 0x22a10
movl %eax, (%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x7ece0(%rip)     # 0x1fa39c
movl 0x4(%rsp), %eax
movl %eax, 0x7ecda(%rip)     # 0x1fa3a0
movl (%rsp), %eax
andl $0xc, %eax
cmpl $0xc, %eax
jne 0x17b6d8
movb $0x1, 0x7eccc(%rip)     # 0x1fa3a4
movl (%rsp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x17b6fb
movl 0x8477f(%rip), %eax     # 0x1ffe68
subl 0x7ecad(%rip), %eax     # 0x1fa39c
addl 0x7ec9b(%rip), %eax     # 0x1fa390
movl %eax, 0x7ec95(%rip)     # 0x1fa390
movl (%rsp), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x17b71e
movl 0x84760(%rip), %eax     # 0x1ffe6c
subl 0x7ec8e(%rip), %eax     # 0x1fa3a0
addl 0x7ec7c(%rip), %eax     # 0x1fa394
movl %eax, 0x7ec76(%rip)     # 0x1fa394
movl (%rsp), %eax
andl $0x3, %eax
cmpl $0x3, %eax
jne 0x17b730
movb $0x1, 0x7ec68(%rip)     # 0x1fa398
jmp 0x17b732
addq $0x48, %rsp
retq
nopw (%rax,%rax)