// File: tomfunkhouser[P]gaps/pkgs/fglut/freeglut_menu.c
// Function: fgCheckActiveMenu
GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
                              int mouse_x, int mouse_y )
{
    /*
     * Near as I can tell, this is the menu behaviour:
     *  - Down-click the menu button, menu not active:  activate
     *    the menu with its upper left-hand corner at the mouse
     *    location.
     *  - Down-click any button outside the menu, menu active:
     *    deactivate the menu
     *  - Down-click any button inside the menu, menu active:
     *    select the menu entry and deactivate the menu
     *  - Up-click the menu button, menu not active:  nothing happens
     *  - Up-click the menu button outside the menu, menu active:
     *    nothing happens
     *  - Up-click the menu button inside the menu, menu active:
     *    select the menu entry and deactivate the menu
     * Since menus can have submenus, we need to check this recursively.
     */
    if( window->ActiveMenu )
    {
        if( window == window->ActiveMenu->ParentWindow )
        {
            window->ActiveMenu->Window->State.MouseX =
                                       mouse_x - window->ActiveMenu->X;
            window->ActiveMenu->Window->State.MouseY =
                                       mouse_y - window->ActiveMenu->Y;
        }

        /* In the menu, invoke the callback and deactivate the menu */
        if( fghCheckMenuStatus( window->ActiveMenu ) )
        {
            /*
             * Save the current window and menu and set the current
             * window to the window whose menu this is
             */
            SFG_Window *save_window = fgStructure.CurrentWindow;
            SFG_Menu *save_menu = fgStructure.CurrentMenu;
            SFG_Window *parent_window = window->ActiveMenu->ParentWindow;
            fgSetWindow( parent_window );
            fgStructure.CurrentMenu = window->ActiveMenu;

            /* Execute the menu callback */
            fghExecuteMenuCallback( window->ActiveMenu );
            fgDeactivateMenu( parent_window );

            /* Restore the current window and menu */
            fgSetWindow( save_window );
            fgStructure.CurrentMenu = save_menu;
        }
        else if( pressed )
            /*
             * Outside the menu, deactivate if it's a downclick
             *
             * XXX This isn't enough.  A downclick outside of
             * XXX the interior of our freeglut windows should also
             * XXX deactivate the menu.  This is more complicated.
             */
            fgDeactivateMenu( window->ActiveMenu->ParentWindow );

        /*
         * XXX Why does an active menu require a redisplay at
         * XXX this point?  If this can come out cleanly, then
         * XXX it probably should do so; if not, a comment should
         * XXX explain it.
         */
        if( ! window->IsMenu )
            window->State.Redisplay = GL_TRUE;

        return GL_TRUE;
    }

    /* No active menu, let's check whether we need to activate one. */
    if( ( 0 <= button ) &&
        ( FREEGLUT_MAX_MENUS > button ) &&
        ( window->Menu[ button ] ) &&
        pressed )
    {
        /* XXX Posting a requisite Redisplay seems bogus. */
        window->State.Redisplay = GL_TRUE;
        fghActivateMenu( window, button );
        return GL_TRUE;
    }

    return GL_FALSE;
}

// Assembly:
subq $0x38, %rsp
movb %dl, %al
movq %rdi, 0x28(%rsp)
movl %esi, 0x24(%rsp)
movb %al, 0x23(%rsp)
movl %ecx, 0x1c(%rsp)
movl %r8d, 0x18(%rsp)
movq 0x28(%rsp), %rax
cmpq $0x0, 0x150(%rax)
je 0x1803b1
movq 0x28(%rsp), %rax
movq 0x28(%rsp), %rcx
movq 0x150(%rcx), %rcx
cmpq 0x68(%rcx), %rax
jne 0x1802d2
movl 0x1c(%rsp), %ecx
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rax
subl 0x4c(%rax), %ecx
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rax
movq 0x60(%rax), %rax
movl %ecx, 0x60(%rax)
movl 0x18(%rsp), %ecx
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rax
subl 0x50(%rax), %ecx
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rax
movq 0x60(%rax), %rax
movl %ecx, 0x64(%rax)
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rdi
callq 0x17fd20
cmpb $0x0, %al
je 0x180375
leaq 0x7fbee(%rip), %rax     # 0x1ffee0
movq 0x30(%rax), %rax
movq %rax, 0x10(%rsp)
leaq 0x7fbde(%rip), %rax     # 0x1ffee0
movq 0x38(%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rax
movq 0x68(%rax), %rax
movq %rax, (%rsp)
movq (%rsp), %rdi
callq 0x1838e0
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rcx
leaq 0x7fba5(%rip), %rax     # 0x1ffee0
movq %rcx, 0x38(%rax)
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rdi
callq 0x180410
movq (%rsp), %rdi
callq 0x1804d0
movq 0x10(%rsp), %rdi
callq 0x1838e0
movq 0x8(%rsp), %rcx
leaq 0x7fb71(%rip), %rax     # 0x1ffee0
movq %rcx, 0x38(%rax)
jmp 0x180393
cmpb $0x0, 0x23(%rsp)
je 0x180391
movq 0x28(%rsp), %rax
movq 0x150(%rax), %rax
movq 0x68(%rax), %rdi
callq 0x1804d0
jmp 0x180393
movq 0x28(%rsp), %rax
cmpb $0x0, 0x170(%rax)
jne 0x1803aa
movq 0x28(%rsp), %rax
movb $0x1, 0x48(%rax)
movb $0x1, 0x37(%rsp)
jmp 0x180406
xorl %eax, %eax
cmpl 0x24(%rsp), %eax
jg 0x180401
movl $0x3, %eax
cmpl 0x24(%rsp), %eax
jle 0x180401
movq 0x28(%rsp), %rax
movslq 0x24(%rsp), %rcx
cmpq $0x0, 0x138(%rax,%rcx,8)
je 0x180401
movzbl 0x23(%rsp), %eax
cmpl $0x0, %eax
je 0x180401
movq 0x28(%rsp), %rax
movb $0x1, 0x48(%rax)
movq 0x28(%rsp), %rdi
movl 0x24(%rsp), %esi
callq 0x1805e0
movb $0x1, 0x37(%rsp)
jmp 0x180406
movb $0x0, 0x37(%rsp)
movb 0x37(%rsp), %al
addq $0x38, %rsp
retq
nop