// File: /workspace/github_c_makefile_star2_O0/tsoding[P]x11-double-buffering/main.c
// Function: main
int main(void)
{
    printf("Double Buffering Implementation: "DB_IMPL_NAME"\n");

    DB db = {0};

    Display *display = XOpenDisplay(NULL);
    if (display == NULL) {
        fprintf(stderr, "ERROR: could not open the default display\n");
        exit(1);
    }

    Window window = XCreateSimpleWindow(
                        display,
                        XDefaultRootWindow(display),
                        0, 0,
                        WIDTH, HEIGHT,
                        0,
                        0,
                        0);

    db_init(&db, display, window);

    XStoreName(display, window, "DB Implementation: "DB_IMPL_NAME);

    Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(display, window, &wm_delete_window, 1);

    XSelectInput(display, window, KeyPressMask);

    XMapWindow(display, window);

    int rect_x = 10;
    int rect_y = 10;

    int rect_dx = -1;
    int rect_dy = -1;

    int quit = 0;
    while (!quit) {
        while (XPending(display) > 0) {
            XEvent event = {0};
            XNextEvent(display, &event);
            switch (event.type) {
            case KeyPress: {
                switch (XLookupKeysym(&event.xkey, 0)) {
                case 'q':
                    quit = 1;
                    break;
                default:
                {}
                }
            } break;
            case ClientMessage: {
                if ((Atom) event.xclient.data.l[0] == wm_delete_window) {
                    quit = 1;
                }
            }
            break;
            }
        }

        db_clear(&db);
        db_fill_rect(&db, rect_x, rect_y, RECT_WIDTH, RECT_HEIGHT);
        db_swap_buffers(&db);

        int rect_nx = rect_x + rect_dx;
        if (rect_nx <= 0 || rect_nx + RECT_WIDTH >= WIDTH) {
            rect_dx *= -1;
        } else {
            rect_x = rect_nx;
        }

        int rect_ny = rect_y + rect_dy;
        if (rect_ny <= 0 || rect_ny + RECT_HEIGHT >= HEIGHT) {
            rect_dy *= -1;
        } else {
            rect_y = rect_ny;
        }

        usleep(1000*1000/FPS);
    }

    XCloseDisplay(display);
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movl $0x0, -0x4(%rbp)
leaq 0xbab(%rip), %rdi       # 0x2004
movb $0x0, %al
callq 0x1060
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x1070
xorl %eax, %eax
movl %eax, %edi
callq 0x1080
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x14a6
movq 0x2b6d(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xb98(%rip), %rsi       # 0x202d
movb $0x0, %al
callq 0x1090
movl $0x1, %edi
callq 0x1150
movq -0x30(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0x30(%rbp), %rdi
callq 0x1120
movq -0x130(%rbp), %rdi
movq %rax, %rsi
xorl %ecx, %ecx
movl $0x320, %r8d            # imm = 0x320
movl $0x258, %r9d            # imm = 0x258
xorl %eax, %eax
movl %ecx, %edx
movl $0x0, (%rsp)
movq $0x0, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
callq 0x1110
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq -0x28(%rbp), %rdi
callq 0x1290
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rsi
leaq 0xb40(%rip), %rdx       # 0x2058
callq 0x1030
movq -0x30(%rbp), %rdi
leaq 0xb4a(%rip), %rsi       # 0x2072
xorl %edx, %edx
callq 0x10d0
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rsi
leaq -0x40(%rbp), %rdx
movl $0x1, %ecx
callq 0x10a0
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl $0x1, %edx
callq 0x10f0
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x1140
movl $0xa, -0x44(%rbp)
movl $0xa, -0x48(%rbp)
movl $0xffffffff, -0x4c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x159d
jmp 0x1722
jmp 0x159f
movq -0x30(%rbp), %rdi
callq 0x1040
cmpl $0x0, %eax
jle 0x1677
xorps %xmm0, %xmm0
movaps %xmm0, -0x150(%rbp)
movaps %xmm0, -0x70(%rbp)
movaps %xmm0, -0x80(%rbp)
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0xa0(%rbp)
movaps %xmm0, -0xb0(%rbp)
movaps %xmm0, -0xc0(%rbp)
movaps %xmm0, -0xd0(%rbp)
movaps %xmm0, -0xe0(%rbp)
movaps %xmm0, -0xf0(%rbp)
movaps %xmm0, -0x100(%rbp)
movaps %xmm0, -0x110(%rbp)
movaps %xmm0, -0x120(%rbp)
movq -0x30(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x10c0
movl -0x120(%rbp), %eax
movl %eax, -0x134(%rbp)
subl $0x2, %eax
je 0x1639
jmp 0x162c
movl -0x134(%rbp), %eax
subl $0x21, %eax
je 0x165c
jmp 0x1672
leaq -0x120(%rbp), %rdi
xorl %esi, %esi
callq 0x10e0
subq $0x71, %rax
jne 0x1658
jmp 0x164f
movl $0x1, -0x54(%rbp)
jmp 0x165a
jmp 0x165a
jmp 0x1672
movq -0xe8(%rbp), %rax
cmpq -0x40(%rbp), %rax
jne 0x1670
movl $0x1, -0x54(%rbp)
jmp 0x1672
jmp 0x159f
leaq -0x28(%rbp), %rdi
callq 0x1310
movl -0x44(%rbp), %esi
movl -0x48(%rbp), %edx
leaq -0x28(%rbp), %rdi
movl $0x12c, %r8d            # imm = 0x12C
movl %r8d, %ecx
callq 0x1370
leaq -0x28(%rbp), %rdi
callq 0x13e0
movl -0x44(%rbp), %eax
addl -0x4c(%rbp), %eax
movl %eax, -0x124(%rbp)
cmpl $0x0, -0x124(%rbp)
jle 0x16c8
movl -0x124(%rbp), %eax
addl $0x12c, %eax            # imm = 0x12C
cmpl $0x320, %eax            # imm = 0x320
jl 0x16d1
imull $-0x1, -0x4c(%rbp), %eax
movl %eax, -0x4c(%rbp)
jmp 0x16da
movl -0x124(%rbp), %eax
movl %eax, -0x44(%rbp)
movl -0x48(%rbp), %eax
addl -0x50(%rbp), %eax
movl %eax, -0x128(%rbp)
cmpl $0x0, -0x128(%rbp)
jle 0x1701
movl -0x128(%rbp), %eax
addl $0x12c, %eax            # imm = 0x12C
cmpl $0x258, %eax            # imm = 0x258
jl 0x170a
imull $-0x1, -0x50(%rbp), %eax
movl %eax, -0x50(%rbp)
jmp 0x1713
movl -0x128(%rbp), %eax
movl %eax, -0x48(%rbp)
movl $0x208d, %edi           # imm = 0x208D
callq 0x1180
jmp 0x158b
movq -0x30(%rbp), %rdi
callq 0x1160
xorl %eax, %eax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq