// File: /workspace/github_c_makefile_star2_O3/tkln[P]mcwm/mcwm.c
// Function: main
int main(int argc, char **argv)
{
    uint32_t mask = 0;
    uint32_t values[2];
    int ch;                    /* Option character */
    xcb_void_cookie_t cookie;
    xcb_generic_error_t *error;
    xcb_drawable_t root;
    char *focuscol;
    char *unfocuscol;
    char *fixedcol;    
    int scrno;
    xcb_screen_iterator_t iter;
    
    /* Install signal handlers. */

    /* We ignore child exists. Don't create zombies. */
    if (SIG_ERR == signal(SIGCHLD, SIG_IGN))
    {
        perror("mcwm: signal");
        exit(1);
    }

    if (SIG_ERR == signal(SIGINT, sigcatch))
    {
        perror("mcwm: signal");
        exit(1);
    }

    if (SIG_ERR == signal(SIGTERM, sigcatch))
    {
        perror("mcwm: signal");
        exit(1);
    }
    
    /* Set up defaults. */
    
    conf.borderwidth = BORDERWIDTH;
    conf.snapmargin = SNAPMARGIN;
    conf.terminal = TERMINAL;
    conf.runcmd = RUNCMD;
    conf.allowicons = ALLOWICONS;
    focuscol = FOCUSCOL;
    unfocuscol = UNFOCUSCOL;
    fixedcol = FIXEDCOL;
    
    while (1)
    {
        ch = getopt(argc, argv, "b:s:it:f:u:x:");
        if (-1 == ch)
        {
                
            /* No more options, break out of while loop. */
            break;
        }
        
        switch (ch)
        {
        case 'b':
            /* Border width */
            conf.borderwidth = atoi(optarg);            
            break;

        case 's':
            /* Snap margin */
            conf.snapmargin = atoi(optarg);
            break;

        case 'i':
            conf.allowicons = true;
            break;
            
        case 't':
            conf.terminal = optarg;
            break;

        case 'f':
            focuscol = optarg;
            break;

        case 'u':
            unfocuscol = optarg;
            break;

        case 'x':
            fixedcol = optarg;
            break;
            
        default:
            printhelp();
            exit(0);
        } /* switch */
    }

    /*
     * Use $DISPLAY. After connecting scrno will contain the value of
     * the display's screen.
     */
    conn = xcb_connect(NULL, &scrno);
    if (xcb_connection_has_error(conn))
    {
        perror("xcb_connect");
        exit(1);
    }

    /* Find our screen. */
    iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
    for (int i = 0; i < scrno; ++ i)
    {
        xcb_screen_next(&iter);
    }

    screen = iter.data;
    if (!screen)
    {
        fprintf (stderr, "mcwm: Can't get the current screen. Exiting.\n");
        xcb_disconnect(conn);
        exit(1);
    }

    root = screen->root;
    
    PDEBUG("Screen size: %dx%d\nRoot window: %d\n", screen->width_in_pixels,
           screen->height_in_pixels, screen->root);
    
    /* Get some colours. */
    conf.focuscol = getcolor(focuscol);
    conf.unfocuscol = getcolor(unfocuscol);
    conf.fixedcol = getcolor(fixedcol);
    
    /* Get some atoms. */
    atom_desktop = getatom("_NET_WM_DESKTOP");
    wm_delete_window = getatom("WM_DELETE_WINDOW");
    wm_change_state = getatom("WM_CHANGE_STATE");
    wm_state = getatom("WM_STATE");
    wm_protocols = getatom("WM_PROTOCOLS");
    
    /* Check for RANDR extension and configure. */
    randrbase = setuprandr();

    /* Loop over all clients and set up stuff. */
    if (0 != setupscreen())
    {
        fprintf(stderr, "mcwm: Failed to initialize windows. Exiting.\n");
        xcb_disconnect(conn);
        exit(1);
    }

    /* Set up key bindings. */
    if (0 != setupkeys())
    {
        fprintf(stderr, "mcwm: Couldn't set up keycodes. Exiting.");
        xcb_disconnect(conn);
        exit(1);
    }

    /* Grab mouse buttons. */

    xcb_grab_button(conn, 0, root, XCB_EVENT_MASK_BUTTON_PRESS
                    | XCB_EVENT_MASK_BUTTON_RELEASE,
                    XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
                    1 /* left mouse button */,
                    MOUSEMODKEY);
    
    xcb_grab_button(conn, 0, root, XCB_EVENT_MASK_BUTTON_PRESS
                    | XCB_EVENT_MASK_BUTTON_RELEASE,
                    XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
                    2 /* middle mouse button */,
                    MOUSEMODKEY);

    xcb_grab_button(conn, 0, root, XCB_EVENT_MASK_BUTTON_PRESS
                    | XCB_EVENT_MASK_BUTTON_RELEASE,
                    XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
                    3 /* right mouse button */,
                    MOUSEMODKEY);

    /* Subscribe to events. */
    mask = XCB_CW_EVENT_MASK;

    values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
        | XCB_EVENT_MASK_STRUCTURE_NOTIFY
        | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;

    cookie =
        xcb_change_window_attributes_checked(conn, root, mask, values);
    error = xcb_request_check(conn, cookie);

    xcb_flush(conn);
    
    if (NULL != error)
    {
        fprintf(stderr, "mcwm: Can't get SUBSTRUCTURE REDIRECT. "
                "Error code: %d\n"
                "Another window manager running? Exiting.\n",
                error->error_code);

        xcb_disconnect(conn);
        
        exit(1);
    }

    /* Loop over events. */
    events();

    /* Die gracefully. */
    cleanup(sigcode);

    exit(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r12
movl %edi, %ebp
movl $0x1, %esi
movl $0x11, %edi
callq 0x32a0
cmpq $-0x1, %rax
je 0x4c32
leaq 0x3c8(%rip), %rsi       # 0x4c3e
movl $0x2, %edi
callq 0x32a0
cmpq $-0x1, %rax
je 0x4c32
leaq 0x3ad(%rip), %rsi       # 0x4c3e
movl $0xf, %edi
callq 0x32a0
cmpq $-0x1, %rax
je 0x4c32
movq $0x1, 0x60a0(%rip) # 0xa950
leaq 0x2849(%rip), %rax      # 0x7100
movq %rax, 0x609a(%rip)      # 0xa958
leaq 0x2842(%rip), %rax      # 0x7107
movq %rax, 0x6094(%rip)      # 0xa960
movb $0x0, 0x60a1(%rip)      # 0xa974
leaq 0x2844(%rip), %r15      # 0x711e
leaq 0x2848(%rip), %rax      # 0x7129
movq %rax, 0x10(%rsp)
leaq 0x2843(%rip), %rax      # 0x7130
movq %rax, 0x18(%rsp)
leaq 0x283e(%rip), %r13      # 0x7137
movq 0x56d0(%rip), %rbx      # 0x9fd0
leaq 0x2725(%rip), %r14      # 0x702c
movl %ebp, %edi
movq %r12, %rsi
movq %r13, %rdx
callq 0x3480
cmpl $0x68, %eax
jle 0x493a
leal -0x73(%rax), %ecx
cmpl $0x5, %ecx
ja 0x494f
movslq (%r14,%rcx,4), %rax
addq %r14, %rax
jmpq *%rax
movq (%rbx), %rdi
callq 0x34c0
movl %eax, 0x601c(%rip)      # 0xa954
jmp 0x4907
cmpl $0x62, %eax
jne 0x496d
movq (%rbx), %rdi
callq 0x34c0
movl %eax, 0x6003(%rip)      # 0xa950
jmp 0x4907
cmpl $0x69, %eax
jne 0x4a19
movb $0x1, 0x6015(%rip)      # 0xa974
jmp 0x4907
movq (%rbx), %rax
movq %rax, 0x5fed(%rip)      # 0xa958
jmp 0x4907
cmpl $0x66, %eax
jne 0x498e
movq (%rbx), %r15
jmp 0x4907
movq (%rbx), %rax
movq %rax, 0x10(%rsp)
jmp 0x4907
movq (%rbx), %rax
movq %rax, 0x18(%rsp)
jmp 0x4907
cmpl $-0x1, %eax
jne 0x4a19
leaq 0xc(%rsp), %rsi
xorl %edi, %edi
callq 0x3120
movq %rax, 0x5fce(%rip)      # 0xa978
movq %rax, %rdi
callq 0x3440
testl %eax, %eax
jne 0x4a25
movq 0x5fbb(%rip), %rdi      # 0xa978
callq 0x3490
movq %rax, %rdi
callq 0x3270
movq %rax, 0x20(%rsp)
movq %rdx, 0x28(%rsp)
cmpl $0x0, 0xc(%rsp)
jle 0x49f7
xorl %ebx, %ebx
leaq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x31f0
incl %ebx
cmpl 0xc(%rsp), %ebx
jl 0x49e2
movq 0x20(%rsp), %rax
movq %rax, 0x5f4a(%rip)      # 0xa948
testq %rax, %rax
jne 0x4a36
movq 0x55ee(%rip), %rax      # 0x9ff8
movq (%rax), %rcx
leaq 0x273d(%rip), %rdi      # 0x7151
jmp 0x4bd7
callq 0x4c45
xorl %edi, %edi
callq 0x3500
leaq 0x2719(%rip), %rdi      # 0x7145
callq 0x3470
jmp 0x4bf2
movl (%rax), %r12d
movq %r15, %rdi
callq 0x4c9b
movl %eax, 0x5f21(%rip)      # 0xa968
movq 0x10(%rsp), %rdi
callq 0x4c9b
movl %eax, 0x5f15(%rip)      # 0xa96c
movq 0x18(%rsp), %rdi
callq 0x4c9b
movl %eax, 0x5f09(%rip)      # 0xa970
leaq 0x2711(%rip), %rdi      # 0x717f
callq 0x4cfc
movl %eax, 0x5f07(%rip)      # 0xa980
leaq 0x270f(%rip), %rdi      # 0x718f
callq 0x4cfc
movl %eax, 0x5ef9(%rip)      # 0xa984
leaq 0x270e(%rip), %rdi      # 0x71a0
callq 0x4cfc
movl %eax, 0x5eeb(%rip)      # 0xa988
leaq 0x270c(%rip), %rdi      # 0x71b0
callq 0x4cfc
movl %eax, 0x5edd(%rip)      # 0xa98c
leaq 0x2703(%rip), %rdi      # 0x71b9
callq 0x4cfc
movl %eax, 0x5ecf(%rip)      # 0xa990
callq 0x4d4a
movl %eax, 0x5ec8(%rip)      # 0xa994
callq 0x4da1
testl %eax, %eax
jne 0x4bc6
callq 0x5024
testl %eax, %eax
jne 0x4bfc
movq 0x5e8b(%rip), %rdi      # 0xa978
movl $0x40, %r14d
xorl %ebx, %ebx
xorl %esi, %esi
movl %r12d, %edx
movl $0xc, %ecx
movl $0x1, %r8d
movl $0x1, %r9d
pushq %r14
pushq $0x1
pushq %rbx
pushq %r12
callq 0x3280
addq $0x20, %rsp
movq 0x5e56(%rip), %rdi      # 0xa978
xorl %esi, %esi
movl %r12d, %edx
movl $0xc, %ecx
movl $0x1, %r8d
movl $0x1, %r9d
pushq %r14
pushq $0x2
pushq %rbx
pushq %r12
callq 0x3280
addq $0x20, %rsp
movq 0x5e29(%rip), %rdi      # 0xa978
xorl %esi, %esi
movl %r12d, %edx
movl $0xc, %ecx
movl $0x1, %r8d
movl $0x1, %r9d
pushq %r14
pushq $0x3
pushq %rbx
pushq %r12
callq 0x3280
addq $0x20, %rsp
leaq 0x30(%rsp), %rcx
movl $0x1a0000, (%rcx)       # imm = 0x1A0000
movq 0x5df1(%rip), %rdi      # 0xa978
movl %r12d, %esi
movl $0x800, %edx            # imm = 0x800
callq 0x33c0
movq 0x5ddd(%rip), %rdi      # 0xa978
movl %eax, %esi
callq 0x3380
movq %rax, %rbx
movq 0x5dcc(%rip), %rdi      # 0xa978
callq 0x3150
testq %rbx, %rbx
jne 0x4c14
callq 0x524a
movl 0x5dd7(%rip), %edi      # 0xa998
callq 0x5f53
movq 0x542b(%rip), %rax      # 0x9ff8
movq (%rax), %rcx
leaq 0x25ef(%rip), %rdi      # 0x71c6
movl $0x2d, %esi
movl $0x1, %edx
callq 0x3510
movq 0x5d8b(%rip), %rdi      # 0xa978
callq 0x3430
movl $0x1, %edi
callq 0x3500
movq 0x53f5(%rip), %rax      # 0x9ff8
movq (%rax), %rcx
leaq 0x25e7(%rip), %rdi      # 0x71f4
movl $0x28, %esi
jmp 0x4bdc
movq 0x53dd(%rip), %rax      # 0x9ff8
movq (%rax), %rdi
movzbl 0x1(%rbx), %edx
leaq 0x25f4(%rip), %rsi      # 0x721d
xorl %eax, %eax
callq 0x32d0
jmp 0x4be6
leaq 0x24d8(%rip), %rdi      # 0x7111
jmp 0x4a2c