// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/fglut/freeglut_menu.c
// Function: fghCheckMenuStatus
static GLboolean fghCheckMenuStatus( SFG_Menu* menu )
{
    SFG_MenuEntry* menuEntry;
    int x, y;

    /* First of all check any of the active sub menus... */
    for( menuEntry = (SFG_MenuEntry *)menu->Entries.First;
         menuEntry;
         menuEntry = (SFG_MenuEntry *)menuEntry->Node.Next )
    {
        if( menuEntry->SubMenu && menuEntry->IsActive )
        {
            /*
             * OK, have the sub-menu checked, too. If it returns GL_TRUE, it
             * will mean that it caught the mouse cursor and we do not need
             * to regenerate the activity list, and so our parents do...
             */
            GLboolean return_status;

            menuEntry->SubMenu->Window->State.MouseX =
                menu->Window->State.MouseX + menu->X - menuEntry->SubMenu->X;
            menuEntry->SubMenu->Window->State.MouseY =
                menu->Window->State.MouseY + menu->Y - menuEntry->SubMenu->Y;
            return_status = fghCheckMenuStatus( menuEntry->SubMenu );

            if ( return_status )
                return GL_TRUE;
        }
    }

    /* That much about our sub menus, let's get to checking the current menu: */
    x = menu->Window->State.MouseX;
    y = menu->Window->State.MouseY;

    /* Check if the mouse cursor is contained within the current menu box */
    if( ( x >= FREEGLUT_MENU_BORDER ) &&
        ( x < menu->Width  - FREEGLUT_MENU_BORDER ) &&
        ( y >= FREEGLUT_MENU_BORDER ) &&
        ( y < menu->Height - FREEGLUT_MENU_BORDER )  )
    {
        int menuID = ( y - FREEGLUT_MENU_BORDER ) / FREEGLUT_MENU_HEIGHT;

        /* The mouse cursor is somewhere over our box, check it out. */
        menuEntry = fghFindMenuEntry( menu, menuID + 1 );
        FREEGLUT_INTERNAL_ERROR_EXIT( menuEntry, "Cannot find menu entry",
                                      "fghCheckMenuStatus" );

        menuEntry->IsActive = GL_TRUE;
        menuEntry->Ordinal = menuID;

        /*
         * If this is not the same as the last active menu entry, deactivate
         * the previous entry.  Specifically, if the previous active entry
         * was a submenu then deactivate it.
         */
        if( menu->ActiveEntry && ( menuEntry != menu->ActiveEntry ) )
            if( menu->ActiveEntry->SubMenu )
                fghDeactivateSubMenu( menu->ActiveEntry );

        if( menuEntry != menu->ActiveEntry )
        {
            menu->Window->State.Redisplay = GL_TRUE;
            if( menu->ActiveEntry )
                menu->ActiveEntry->IsActive = GL_FALSE;
        }

        menu->ActiveEntry = menuEntry;
        menu->IsActive = GL_TRUE;  /* XXX Do we need this? */

        /*
         * OKi, we have marked that entry as active, but it would be also
         * nice to have its contents updated, in case it's a sub menu.
         * Also, ignore the return value of the check function:
         */
        if( menuEntry->SubMenu )
        {
            if ( ! menuEntry->SubMenu->IsActive )
            {
                int max_x, max_y;
                SFG_Window *current_window = fgStructure.CurrentWindow;

                /* Set up the initial menu position now... */
                menuEntry->SubMenu->IsActive = GL_TRUE;

                /* Set up the initial submenu position now: */
                fghGetVMaxExtent(menu->ParentWindow, &max_x, &max_y);
                menuEntry->SubMenu->X = menu->X + menu->Width;
                menuEntry->SubMenu->Y = menu->Y +
                    menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT;

                if( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > max_x )
                    menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width;

                if( menuEntry->SubMenu->Y + menuEntry->SubMenu->Height > max_y )
                {
                    menuEntry->SubMenu->Y -= ( menuEntry->SubMenu->Height -
                                               FREEGLUT_MENU_HEIGHT -
                                               2 * FREEGLUT_MENU_BORDER );
                    if( menuEntry->SubMenu->Y < 0 )
                        menuEntry->SubMenu->Y = 0;
                }

                fgSetWindow( menuEntry->SubMenu->Window );
                glutPositionWindow( menuEntry->SubMenu->X,
                                    menuEntry->SubMenu->Y );
                glutReshapeWindow( menuEntry->SubMenu->Width,
                                   menuEntry->SubMenu->Height );
                glutPopWindow( );
                glutShowWindow( );
                menuEntry->SubMenu->Window->ActiveMenu = menuEntry->SubMenu;
                fgSetWindow( current_window );
                menuEntry->SubMenu->Window->State.MouseX =
                    x + menu->X - menuEntry->SubMenu->X;
                menuEntry->SubMenu->Window->State.MouseY =
                    y + menu->Y - menuEntry->SubMenu->Y;
                fghCheckMenuStatus( menuEntry->SubMenu );
            }

            /* Activate it because its parent entry is active */
            menuEntry->SubMenu->IsActive = GL_TRUE;  /* XXX Do we need this? */
        }

        /* Report back that we have caught the menu cursor */
        return GL_TRUE;
    }

    /* Looks like the menu cursor is somewhere else... */
    if( menu->ActiveEntry && menu->ActiveEntry->IsActive &&
        ( !menu->ActiveEntry->SubMenu ||
          !menu->ActiveEntry->SubMenu->IsActive ) )
    {
        menu->Window->State.Redisplay = GL_TRUE;
        menu->ActiveEntry->IsActive = GL_FALSE;
        menu->ActiveEntry = NULL;
    }

    return GL_FALSE;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
movq 0x20(%rdi), %r14
testq %r14, %r14
je 0xd109d
movq 0x20(%r14), %rdi
testq %rdi, %rdi
je 0xd1098
cmpb $0x0, 0x28(%r14)
je 0xd1098
movq 0x60(%rbx), %rax
movq 0x60(%rdi), %rcx
movq 0x60(%rax), %xmm0
movq 0x4c(%rbx), %xmm1
paddd %xmm0, %xmm1
movq 0x4c(%rdi), %xmm0
psubd %xmm0, %xmm1
movq %xmm1, 0x60(%rcx)
callq 0xd103d
testb %al, %al
jne 0xd1313
movq (%r14), %r14
jmp 0xd1052
movq 0x60(%rbx), %rax
movq 0x60(%rax), %rcx
cmpl $0x2, %ecx
jl 0xd12d2
movq %rcx, %xmm1
movl 0x44(%rbx), %edx
addl $-0x2, %edx
cmpl %edx, %ecx
setl %cl
pshufd $0x55, %xmm1, %xmm0     # xmm0 = xmm1[1,1,1,1]
movd %xmm0, %ebp
cmpl $0x2, %ebp
setge %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0xd12d2
movl 0x48(%rbx), %ecx
addl $-0x2, %ecx
cmpl %ecx, %ebp
jge 0xd12d2
movdqa %xmm1, 0x20(%rsp)
leaq 0x20(%rbx), %r12
addl $-0x2, %ebp
leaq 0x756be(%rip), %rdi     # 0x1467b8
callq 0xcda80
movl %eax, %ecx
addl $0x2, %ecx
movl %ebp, %eax
cltd
idivl %ecx
movl %eax, %ebp
movq (%r12), %r12
subl $0x1, %eax
setb %cl
testq %r12, %r12
je 0xd111e
testb %cl, %cl
je 0xd110b
testq %r12, %r12
jne 0xd113f
leaq 0x28e84(%rip), %rdi     # 0xf9fae
leaq 0x2964e(%rip), %rsi     # 0xfa77f
leaq 0x2965e(%rip), %rdx     # 0xfa796
xorl %eax, %eax
callq 0xcfe73
movb $0x1, 0x28(%r12)
movl %ebp, 0x14(%r12)
movq 0x58(%rbx), %rdi
testq %rdi, %rdi
sete %al
cmpq %rdi, %r12
sete %cl
orb %al, %cl
jne 0xd116e
cmpq $0x0, 0x20(%rdi)
je 0xd116e
callq 0xd1633
movq 0x58(%rbx), %rdi
cmpq %rdi, %r12
je 0xd1184
movq 0x60(%rbx), %rax
movb $0x1, 0x48(%rax)
testq %rdi, %rdi
je 0xd1184
movb $0x0, 0x28(%rdi)
movq %r12, 0x58(%rbx)
movb $0x1, 0x40(%rbx)
movq 0x20(%r12), %rax
movb $0x1, %bpl
testq %rax, %rax
je 0xd1302
cmpb $0x0, 0x40(%rax)
jne 0xd12cc
leaq 0x756c2(%rip), %rcx     # 0x146870
movq 0x30(%rcx), %rcx
movq %rcx, 0x10(%rsp)
movb $0x1, 0x40(%rax)
movq 0x68(%rbx), %rdi
leaq 0x1c(%rsp), %r15
leaq 0xc(%rsp), %rdx
movq %r15, %rsi
callq 0xd1c4e
movl 0x44(%rbx), %eax
addl 0x4c(%rbx), %eax
movq 0x20(%r12), %rcx
movl %eax, 0x4c(%rcx)
movl 0x50(%rbx), %r13d
movl 0x14(%r12), %r14d
leaq 0x755c9(%rip), %rdi     # 0x1467b8
callq 0xcda80
addl $0x2, %eax
imull %r14d, %eax
addl %r13d, %eax
movq 0x20(%r12), %rcx
movl %eax, 0x50(%rcx)
movl 0x44(%rcx), %edx
movl 0x4c(%rcx), %esi
addl %edx, %esi
cmpl (%r15), %esi
jle 0xd121b
movl 0x4c(%rbx), %esi
subl %edx, %esi
movl %esi, 0x4c(%rcx)
movl 0x48(%rcx), %r15d
addl %r15d, %eax
cmpl 0xc(%rsp), %eax
jle 0xd1253
leaq 0x75589(%rip), %rdi     # 0x1467b8
callq 0xcda80
movq 0x20(%r12), %rcx
movl 0x50(%rcx), %edx
subl %r15d, %eax
addl %edx, %eax
addl $0x6, %eax
xorl %edx, %edx
testl %eax, %eax
cmovgl %eax, %edx
movl %edx, 0x50(%rcx)
movq 0x20(%r12), %rcx
movq 0x60(%rcx), %rdi
callq 0xd314d
movq 0x20(%r12), %rax
movl 0x4c(%rax), %edi
movl 0x50(%rax), %esi
callq 0xd3d61
movq 0x20(%r12), %rax
movl 0x44(%rax), %edi
movl 0x48(%rax), %esi
callq 0xd3c88
callq 0xd3e51
callq 0xd39a8
movq 0x20(%r12), %rax
movq 0x60(%rax), %rcx
movq %rax, 0x150(%rcx)
movq 0x10(%rsp), %rdi
callq 0xd314d
movq 0x20(%r12), %rdi
movq 0x60(%rdi), %rax
movq 0x4c(%rbx), %xmm0
paddd 0x20(%rsp), %xmm0
movq 0x4c(%rdi), %xmm1
psubd %xmm1, %xmm0
movq %xmm0, 0x60(%rax)
callq 0xd103d
movq 0x20(%r12), %rax
movb $0x1, 0x40(%rax)
jmp 0xd1302
movq 0x58(%rbx), %rcx
testq %rcx, %rcx
je 0xd1300
cmpb $0x0, 0x28(%rcx)
je 0xd1300
movq 0x20(%rcx), %rdx
testq %rdx, %rdx
je 0xd12f0
cmpb $0x0, 0x40(%rdx)
jne 0xd1300
movb $0x1, 0x48(%rax)
movb $0x0, 0x28(%rcx)
movq $0x0, 0x58(%rbx)
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x1, %bpl
jmp 0xd1302