// File: nishalkulkarni[P]fluid-wm/fluid_wm.cpp
// Function: WindowManager::Run()
void WindowManager::Run()
{
    wm_detected_ = false;
    XSetErrorHandler(&WindowManager::OnWMDetected);

    XSelectInput(
        display_,
        root_,
        SubstructureRedirectMask | SubstructureNotifyMask);
    XSync(display_, false);
    if (wm_detected_) {
        std::cout << "Detected another window manager on display "
                  << XDisplayString(display_) << std::endl;
        return;
    }
    XSetErrorHandler(&WindowManager::OnXError);

    XGrabServer(display_);
    Window returned_root, returned_parent;
    Window* top_level_windows;
    unsigned int num_top_level_windows;
    assert(XQueryTree(
        display_,
        root_,
        &returned_root,
        &returned_parent,
        &top_level_windows,
        &num_top_level_windows));
    assert(returned_root == root_);
    for (unsigned int i = 0; i < num_top_level_windows; ++i) {
        Frame(top_level_windows[i], true);
    }
    XFree(top_level_windows);
    XUngrabServer(display_);

    for (;;) {
        XEvent e;
        XNextEvent(display_, &e);
        std::cout << "Received event: " << ToString(e) << std::endl;

        switch (e.type) {
        case CreateNotify:
            OnCreateNotify(e.xcreatewindow);
            break;
        case DestroyNotify:
            OnDestroyNotify(e.xdestroywindow);
            break;
        case ReparentNotify:
            OnReparentNotify(e.xreparent);
            break;
        case MapNotify:
            OnMapNotify(e.xmap);
            break;
        case UnmapNotify:
            OnUnmapNotify(e.xunmap);
            break;
        case ConfigureNotify:
            OnConfigureNotify(e.xconfigure);
            break;
        case MapRequest:
            OnMapRequest(e.xmaprequest);
            break;
        case ConfigureRequest:
            OnConfigureRequest(e.xconfigurerequest);
            break;
        case ButtonPress:
            OnButtonPress(e.xbutton);
            break;
        case ButtonRelease:
            OnButtonRelease(e.xbutton);
            break;
        case MotionNotify:
            // Skip any already pending motion events.
            while (XCheckTypedWindowEvent(
                display_, e.xmotion.window, MotionNotify, &e)) { }
            OnMotionNotify(e.xmotion);
            break;
        case KeyPress:
            OnKeyPress(e.xkey);
            break;
        case KeyRelease:
            OnKeyRelease(e.xkey);
            break;
        default:
            std::cout << "Ignored event" << std::endl;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x120(%rbp)
movb $0x0, 0x1196c(%rip)     # 0x232cd
leaq 0x3e8(%rip), %rdi       # 0x11d50
callq 0x40a0
movq -0x120(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
movl $0x180000, %edx         # imm = 0x180000
callq 0x4160
movq -0x120(%rbp), %rax
movq (%rax), %rdi
xorl %esi, %esi
callq 0x4520
testb $0x1, 0x11930(%rip)     # 0x232cd
je 0x119f2
movq 0x1162a(%rip), %rdi     # 0x22fd0
leaq 0x61cb(%rip), %rsi      # 0x17b78
callq 0x4240
movq %rax, %rcx
movq -0x120(%rbp), %rax
movq %rcx, -0x128(%rbp)
movq (%rax), %rdi
callq 0x41a0
movq -0x128(%rbp), %rdi
movq %rax, %rsi
callq 0x4240
movq %rax, %rdi
movq 0x115dc(%rip), %rsi     # 0x22fc0
callq 0x4290
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
leaq 0x3a7(%rip), %rdi       # 0x11da0
callq 0x40a0
movq -0x120(%rbp), %rax
movq (%rax), %rdi
callq 0x4260
movq -0x120(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
leaq -0x10(%rbp), %rdx
leaq -0x18(%rbp), %rcx
leaq -0x20(%rbp), %r8
leaq -0x24(%rbp), %r9
callq 0x40c0
cmpl $0x0, %eax
je 0x11a37
jmp 0x11a56
leaq 0x6166(%rip), %rdi      # 0x17ba4
leaq 0x61ca(%rip), %rsi      # 0x17c0f
movl $0x42, %edx
leaq 0x61cb(%rip), %rcx      # 0x17c1c
callq 0x4170
movq -0x120(%rbp), %rcx
movq -0x10(%rbp), %rax
cmpq 0x8(%rcx), %rax
jne 0x11a69
jmp 0x11a88
leaq 0x61c6(%rip), %rdi      # 0x17c36
leaq 0x6198(%rip), %rsi      # 0x17c0f
movl $0x43, %edx
leaq 0x6199(%rip), %rcx      # 0x17c1c
callq 0x4170
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0x11abe
movq -0x120(%rbp), %rdi
movq -0x20(%rbp), %rax
movl -0x28(%rbp), %ecx
movq (%rax,%rcx,8), %rsi
movl $0x1, %edx
callq 0x11f90
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x11a8f
movq -0x20(%rbp), %rdi
callq 0x4350
movq -0x120(%rbp), %rax
movq (%rax), %rdi
callq 0x4120
movq -0x120(%rbp), %rax
movq (%rax), %rdi
leaq -0xe8(%rbp), %rsi
movq %rsi, -0x148(%rbp)
callq 0x43d0
movq 0x114d6(%rip), %rdi     # 0x22fd0
leaq 0x614c(%rip), %rsi      # 0x17c4d
callq 0x4240
movq -0x148(%rbp), %rsi
movq %rax, -0x140(%rbp)
leaq -0x108(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0x47a0
movq -0x140(%rbp), %rdi
movq -0x138(%rbp), %rsi
callq 0x4220
movq %rax, -0x130(%rbp)
jmp 0x11b43
movq -0x130(%rbp), %rdi
movq 0x1146f(%rip), %rsi     # 0x22fc0
callq 0x4290
jmp 0x11b58
leaq -0x108(%rbp), %rdi
callq 0x4150
movl -0xe8(%rbp), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0x150(%rbp)
subl $0x15, %eax
ja 0x11d13
movq -0x150(%rbp), %rax
leaq 0x5f4b(%rip), %rcx      # 0x17ad8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x110(%rbp)
movl %eax, -0x114(%rbp)
leaq -0x108(%rbp), %rdi
callq 0x4150
jmp 0x11d3a
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x126a0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x126b0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x126c0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x126d0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x126e0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x12790
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x127a0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x127f0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x12980
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x12ac0
jmp 0x11d35
jmp 0x11cab
movq -0x120(%rbp), %rax
movq (%rax), %rdi
movq -0xc8(%rbp), %rsi
movl $0x6, %edx
leaq -0xe8(%rbp), %rcx
callq 0x4380
cmpl $0x0, %eax
je 0x11cd4
jmp 0x11cab
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x12ad0
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x12c60
jmp 0x11d35
movq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x12fc0
jmp 0x11d35
movq 0x112b6(%rip), %rdi     # 0x22fd0
leaq 0x5f3d(%rip), %rsi      # 0x17c5e
callq 0x4240
movq %rax, %rdi
movq 0x11290(%rip), %rsi     # 0x22fc0
callq 0x4290
jmp 0x11ad6
movq -0x110(%rbp), %rdi
callq 0x44b0
nopw %cs:(%rax,%rax)