// File: /workspace/github_c_makefile_star2_O1/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 0x4c00
leaq 0x3c8(%rip), %rsi       # 0x4c0c
movl $0x2, %edi
callq 0x32a0
cmpq $-0x1, %rax
je 0x4c00
leaq 0x3ad(%rip), %rsi       # 0x4c0c
movl $0xf, %edi
callq 0x32a0
cmpq $-0x1, %rax
je 0x4c00
movq $0x1, 0x60d2(%rip) # 0xa950
leaq 0x2843(%rip), %rax      # 0x70c8
movq %rax, 0x60cc(%rip)      # 0xa958
leaq 0x283c(%rip), %rax      # 0x70cf
movq %rax, 0x60c6(%rip)      # 0xa960
movb $0x0, 0x60d3(%rip)      # 0xa974
leaq 0x283e(%rip), %r15      # 0x70e6
leaq 0x2842(%rip), %rax      # 0x70f1
movq %rax, 0x10(%rsp)
leaq 0x283d(%rip), %rax      # 0x70f8
movq %rax, 0x18(%rsp)
leaq 0x2838(%rip), %r13      # 0x70ff
movq 0x5702(%rip), %rbx      # 0x9fd0
leaq 0x2757(%rip), %r14      # 0x702c
movl %ebp, %edi
movq %r12, %rsi
movq %r13, %rdx
callq 0x3480
cmpl $0x68, %eax
jle 0x4908
leal -0x73(%rax), %ecx
cmpl $0x5, %ecx
ja 0x491d
movslq (%r14,%rcx,4), %rax
addq %r14, %rax
jmpq *%rax
movq (%rbx), %rdi
callq 0x34c0
movl %eax, 0x604e(%rip)      # 0xa954
jmp 0x48d5
cmpl $0x62, %eax
jne 0x493b
movq (%rbx), %rdi
callq 0x34c0
movl %eax, 0x6035(%rip)      # 0xa950
jmp 0x48d5
cmpl $0x69, %eax
jne 0x49e7
movb $0x1, 0x6047(%rip)      # 0xa974
jmp 0x48d5
movq (%rbx), %rax
movq %rax, 0x601f(%rip)      # 0xa958
jmp 0x48d5
cmpl $0x66, %eax
jne 0x495c
movq (%rbx), %r15
jmp 0x48d5
movq (%rbx), %rax
movq %rax, 0x10(%rsp)
jmp 0x48d5
movq (%rbx), %rax
movq %rax, 0x18(%rsp)
jmp 0x48d5
cmpl $-0x1, %eax
jne 0x49e7
leaq 0xc(%rsp), %rsi
xorl %edi, %edi
callq 0x3120
movq %rax, 0x6000(%rip)      # 0xa978
movq %rax, %rdi
callq 0x3440
testl %eax, %eax
jne 0x49f3
movq 0x5fed(%rip), %rdi      # 0xa978
callq 0x3490
movq %rax, %rdi
callq 0x3270
movq %rax, 0x20(%rsp)
movq %rdx, 0x28(%rsp)
cmpl $0x0, 0xc(%rsp)
jle 0x49c0
xorl %ebx, %ebx
leaq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x31f0
incl %ebx
cmpl 0xc(%rsp), %ebx
jl 0x49b0
movq 0x20(%rsp), %rax
movq %rax, 0x5f7c(%rip)      # 0xa948
testq %rax, %rax
jne 0x4a04
movq 0x5620(%rip), %rax      # 0x9ff8
movq (%rax), %rcx
leaq 0x2737(%rip), %rdi      # 0x7119
jmp 0x4ba5
callq 0x4c13
xorl %edi, %edi
callq 0x3500
leaq 0x2713(%rip), %rdi      # 0x710d
callq 0x3470
jmp 0x4bc0
movl (%rax), %r12d
movq %r15, %rdi
callq 0x4c69
movl %eax, 0x5f53(%rip)      # 0xa968
movq 0x10(%rsp), %rdi
callq 0x4c69
movl %eax, 0x5f47(%rip)      # 0xa96c
movq 0x18(%rsp), %rdi
callq 0x4c69
movl %eax, 0x5f3b(%rip)      # 0xa970
leaq 0x270b(%rip), %rdi      # 0x7147
callq 0x4cca
movl %eax, 0x5f39(%rip)      # 0xa980
leaq 0x2709(%rip), %rdi      # 0x7157
callq 0x4cca
movl %eax, 0x5f2b(%rip)      # 0xa984
leaq 0x2708(%rip), %rdi      # 0x7168
callq 0x4cca
movl %eax, 0x5f1d(%rip)      # 0xa988
leaq 0x2706(%rip), %rdi      # 0x7178
callq 0x4cca
movl %eax, 0x5f0f(%rip)      # 0xa98c
leaq 0x26fd(%rip), %rdi      # 0x7181
callq 0x4cca
movl %eax, 0x5f01(%rip)      # 0xa990
callq 0x4d18
movl %eax, 0x5efa(%rip)      # 0xa994
callq 0x4d6f
testl %eax, %eax
jne 0x4b94
callq 0x4ffc
testl %eax, %eax
jne 0x4bca
movq 0x5ebd(%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 0x5e88(%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 0x5e5b(%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 0x5e23(%rip), %rdi      # 0xa978
movl %r12d, %esi
movl $0x800, %edx            # imm = 0x800
callq 0x33c0
movq 0x5e0f(%rip), %rdi      # 0xa978
movl %eax, %esi
callq 0x3380
movq %rax, %rbx
movq 0x5dfe(%rip), %rdi      # 0xa978
callq 0x3150
testq %rbx, %rbx
jne 0x4be2
callq 0x522b
movl 0x5e09(%rip), %edi      # 0xa998
callq 0x5f08
movq 0x545d(%rip), %rax      # 0x9ff8
movq (%rax), %rcx
leaq 0x25e9(%rip), %rdi      # 0x718e
movl $0x2d, %esi
movl $0x1, %edx
callq 0x3510
movq 0x5dbd(%rip), %rdi      # 0xa978
callq 0x3430
movl $0x1, %edi
callq 0x3500
movq 0x5427(%rip), %rax      # 0x9ff8
movq (%rax), %rcx
leaq 0x25e1(%rip), %rdi      # 0x71bc
movl $0x28, %esi
jmp 0x4baa
movq 0x540f(%rip), %rax      # 0x9ff8
movq (%rax), %rdi
movzbl 0x1(%rbx), %edx
leaq 0x25ee(%rip), %rsi      # 0x71e5
xorl %eax, %eax
callq 0x32d0
jmp 0x4bb4
leaq 0x24d2(%rip), %rdi      # 0x70d9
jmp 0x49fa