// File: tomfunkhouser[P]gaps/pkgs/fglut/freeglut_window.c
// Function: fgChooseFBConfig
GLXFBConfig* fgChooseFBConfig( void )
{
  GLboolean wantIndexedMode = GL_FALSE;
  int attributes[ 100 ];
  int where = 0, numAuxBuffers;

  /* First we have to process the display mode settings... */
  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_VAL( GLX_RED_SIZE,   1 );
    ATTRIB_VAL( GLX_GREEN_SIZE, 1 );
    ATTRIB_VAL( GLX_BLUE_SIZE,  1 );
    if( fgState.DisplayMode & GLUT_ALPHA ) {
      ATTRIB_VAL( GLX_ALPHA_SIZE, 1 );
    }
  }

  if( fgState.DisplayMode & GLUT_DOUBLE ) {
    ATTRIB_VAL( GLX_DOUBLEBUFFER, True );
  }

  if( fgState.DisplayMode & GLUT_STEREO ) {
    ATTRIB_VAL( GLX_STEREO, True );
  }

  if( fgState.DisplayMode & GLUT_DEPTH ) {
    ATTRIB_VAL( GLX_DEPTH_SIZE, 1 );
  }

  if( fgState.DisplayMode & GLUT_STENCIL ) {
    ATTRIB_VAL( GLX_STENCIL_SIZE, 1 );
  }

  if( fgState.DisplayMode & GLUT_ACCUM ) {
    ATTRIB_VAL( GLX_ACCUM_RED_SIZE, 1 );
    ATTRIB_VAL( GLX_ACCUM_GREEN_SIZE, 1 );
    ATTRIB_VAL( GLX_ACCUM_BLUE_SIZE, 1 );
    if( fgState.DisplayMode & GLUT_ALPHA ) {
      ATTRIB_VAL( GLX_ACCUM_ALPHA_SIZE, 1 );
    }
  }

  numAuxBuffers = fghNumberOfAuxBuffersRequested();
  if ( numAuxBuffers > 0 ) {
    ATTRIB_VAL( GLX_AUX_BUFFERS, numAuxBuffers );
  }

  if( fgState.DisplayMode & GLUT_SRGB ) {
    ATTRIB_VAL( GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True );
  }

  if (fgState.DisplayMode & GLUT_MULTISAMPLE) {
    ATTRIB_VAL(GLX_SAMPLE_BUFFERS, 1);
    ATTRIB_VAL(GLX_SAMPLES, fgState.SampleNumber);
  }

  /* Push a terminator at the end of the list */
  ATTRIB( None );

    {
        GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
        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)
        {
            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.  */
                glXGetFBConfigAttrib( fgDisplay.Display,
                                        fbconfigArray[0],
                                        GLX_BUFFER_SIZE,
                                        &bufferSizeMin );
                /*  Get bufferSizeMax.  */
                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;
        }
        else
        {
           fbconfig = NULL;
        }

        return fbconfig;
    }
}

// Assembly:
subq $0x1c8, %rsp            # imm = 0x1C8
movb $0x0, 0x1c7(%rsp)
movl $0x0, 0x2c(%rsp)
leaq 0x770c2(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x183342
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x2, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x8, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x8011, 0x30(%rsp,%rax,4) # imm = 0x8011
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x2, 0x30(%rsp,%rax,4)
movb $0x1, 0x1c7(%rsp)
jmp 0x18340e
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x8, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x9, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0xa, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
leaq 0x76fbd(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x18340c
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0xb, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
jmp 0x18340e
leaq 0x76f7b(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x18344e
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x5, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
leaq 0x76f3b(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x183490
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x6, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
leaq 0x76ef9(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x1834d0
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0xc, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
leaq 0x76eb9(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x183510
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0xd, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
leaq 0x76e79(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x1835f2
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0xe, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0xf, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x10, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
leaq 0x76dd9(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x1835f0
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x11, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
jmp 0x1835f2
callq 0x183850
movl %eax, 0x28(%rsp)
cmpl $0x0, 0x28(%rsp)
jle 0x183630
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x7, 0x30(%rsp,%rax,4)
movl 0x28(%rsp), %ecx
movl 0x2c(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x2c(%rsp)
cltq
movl %ecx, 0x30(%rsp,%rax,4)
leaq 0x76d59(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x1000, %eax           # imm = 0x1000
cmpl $0x0, %eax
je 0x183672
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x20b2, 0x30(%rsp,%rax,4) # imm = 0x20B2
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
leaq 0x76d17(%rip), %rax     # 0x1fa390
movl 0x18(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x1836eb
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x186a0, 0x30(%rsp,%rax,4) # imm = 0x186A0
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x1, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x186a1, 0x30(%rsp,%rax,4) # imm = 0x186A1
leaq 0x76cbe(%rip), %rax     # 0x1fa390
movl 0xb8(%rax), %ecx
movl 0x2c(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x2c(%rsp)
cltq
movl %ecx, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x0, 0x30(%rsp,%rax,4)
leaq 0x7c727(%rip), %rax     # 0x1ffe30
movq (%rax), %rdi
leaq 0x7c71d(%rip), %rax     # 0x1ffe30
movl 0x8(%rax), %esi
leaq 0x30(%rsp), %rdx
leaq 0x14(%rsp), %rcx
callq 0x22e60
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x20(%rsp)
je 0x18382f
cmpb $0x0, 0x1c7(%rsp)
je 0x183823
leaq 0x7c6e5(%rip), %rax     # 0x1ffe30
movq (%rax), %rdi
movq 0x20(%rsp), %rax
movq (%rax), %rsi
movl $0x2, %edx
leaq 0x10(%rsp), %rcx
callq 0x222b0
leaq 0x7c6c4(%rip), %rax     # 0x1ffe30
movq (%rax), %rdi
movq 0x20(%rsp), %rax
movl 0x14(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
movl $0x2, %edx
leaq 0xc(%rsp), %rcx
callq 0x222b0
movl 0xc(%rsp), %eax
cmpl 0x10(%rsp), %eax
jle 0x183821
movq 0x20(%rsp), %rdi
callq 0x22d60
movl 0x2c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x2, 0x30(%rsp,%rax,4)
movl 0xc(%rsp), %ecx
movl 0x2c(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x2c(%rsp)
cltq
movl %ecx, 0x30(%rsp,%rax,4)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rsp)
cltq
movl $0x0, 0x30(%rsp,%rax,4)
leaq 0x7c630(%rip), %rax     # 0x1ffe30
movq (%rax), %rdi
leaq 0x7c626(%rip), %rax     # 0x1ffe30
movl 0x8(%rax), %esi
leaq 0x30(%rsp), %rdx
leaq 0x14(%rsp), %rcx
callq 0x22e60
movq %rax, 0x20(%rsp)
jmp 0x183823
movq 0x20(%rsp), %rax
movq %rax, 0x18(%rsp)
jmp 0x183838
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
addq $0x1c8, %rsp            # imm = 0x1C8
retq
nopw %cs:(%rax,%rax)