// File: rfotino[P]consolite-emulator/src/window.cpp
// Function: EmuWindow::EmuWindow(EmuVideoMemory*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
EmuWindow::EmuWindow(EmuVideoMemory *vid_mem,
                     const std::string& keymap_filename)
                    : _vidMem(vid_mem),
                      _error(false),
                      _width(DEFAULT_WINDOW_WIDTH),
                      _height(DEFAULT_WINDOW_HEIGHT) {
  // Read key mapping into memory
  _loadKeyMap(keymap_filename);

  // Open a connection to the X server.
  _display = XOpenDisplay(nullptr);
  if (nullptr == _display) {
    std::cerr << "Error: Cannot open connection to the X server."
              << std::endl;
    _error = true;
    return;
  }

  // Create a window on the default screen.
  int screen_num = DefaultScreen(_display);
  Window window = XCreateSimpleWindow(
      _display,                         // Connection to the X server
      DefaultRootWindow(_display),      // Parent window
      0,                                // X position
      0,                                // Y position
      _width,                           // Width
      _height,                          // Height
      0,                                // Border width
      BlackPixel(_display, screen_num), // Border color
      BlackPixel(_display, screen_num)  // Background color
  );

  // Create the cairo surface we will use for drawing to the window
  Visual *visual = DefaultVisual(_display, screen_num);
  _surface = cairo_xlib_surface_create(
      _display,     // Connection to the X server
      window,       // A Drawable, the window in this case
      visual,       // A Visual, the screen in this case
      _width,       // The surface width
      _height       // The surface height
  );
  if (nullptr == _surface) {
    _error = true;
    std::cerr << "Error: Cannot get cairo Xlib surface." << std::endl;
    return;
  }

  // Create the cairo object from the window surface
  _cairo = cairo_create(_surface);
  
  // Intercept the WM_DELETE_WINDOW message from the window
  // manager so that we can close the window when the user hits
  // the exit button.
  _wmDeleteMessage = XInternAtom(_display, "WM_DELETE_WINDOW", false);
  XSetWMProtocols(_display, window, &_wmDeleteMessage, 1);
  // Select the kind of window events we want to intercept.
  // StructureNotifyMask lets us intercept window resize events.
  XSelectInput(_display, window, ExposureMask | StructureNotifyMask |
                                 KeyPressMask | KeyReleaseMask);
  // "Map" (show) the window.
  XMapWindow(_display, window);
  // Suppress auto-repeating KeyRelease events
  XkbSetDetectableAutoRepeat(_display, 1, 0);
  // Flush any buffered commands to the X server
  XFlush(_display);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq %rax, 0x20(%rdi)
movb $0x0, 0x28(%rdi)
movl $0x300, 0x2c(%rdi)      # imm = 0x300
movl $0x240, 0x30(%rdi)      # imm = 0x240
addq $0x38, %rdi
movq %rdi, -0x50(%rbp)
callq 0x5a70
movq -0x40(%rbp), %rdi
addq $0x68, %rdi
movq %rdi, -0x48(%rbp)
callq 0x5a90
movq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5080
jmp 0x4e46
xorl %eax, %eax
movl %eax, %edi
callq 0x33e0
movq %rax, -0x58(%rbp)
jmp 0x4e55
movq -0x40(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rax, 0x10(%rcx)
xorl %eax, %eax
cmpq 0x10(%rcx), %rax
jne 0x4ec4
movq 0xa180(%rip), %rdi      # 0xeff0
leaq 0x5301(%rip), %rsi      # 0xa178
callq 0x32c0
movq %rax, -0x60(%rbp)
jmp 0x4e82
movq -0x60(%rbp), %rdi
movq 0xa133(%rip), %rsi      # 0xefc0
callq 0x3300
jmp 0x4e94
movq -0x40(%rbp), %rax
movb $0x1, 0x28(%rax)
jmp 0x506a
movq -0x48(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x5ab0
movq -0x50(%rbp), %rdi
callq 0x5ad0
jmp 0x5073
movq -0x40(%rbp), %rcx
movq 0x10(%rcx), %rax
movl 0xe0(%rax), %eax
movl %eax, -0x28(%rbp)
movq 0x10(%rcx), %rdi
movq 0xe8(%rdi), %rax
movslq 0xe0(%rdi), %rdx
shlq $0x7, %rdx
movq 0x10(%rax,%rdx), %rsi
movl 0x2c(%rcx), %r8d
movl 0x30(%rcx), %r9d
movslq -0x28(%rbp), %rcx
shlq $0x7, %rcx
movq 0x60(%rax,%rcx), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movq %rcx, 0x8(%rax)
movl $0x0, (%rax)
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x30a0
movq %rax, -0x68(%rbp)
jmp 0x4f25
movq -0x40(%rbp), %rax
movq -0x68(%rbp), %rcx
movq %rcx, -0x30(%rbp)
movq 0x10(%rax), %rcx
movq 0xe8(%rcx), %rcx
movslq -0x28(%rbp), %rdx
shlq $0x7, %rdx
movq 0x40(%rcx,%rdx), %rcx
movq %rcx, -0x38(%rbp)
movq 0x10(%rax), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
movl 0x2c(%rax), %ecx
movl 0x30(%rax), %r8d
callq 0x31f0
movq %rax, -0x70(%rbp)
jmp 0x4f6b
movq -0x40(%rbp), %rcx
movq -0x70(%rbp), %rax
movq %rax, (%rcx)
xorl %eax, %eax
cmpq (%rcx), %rax
jne 0x4fb5
movq -0x40(%rbp), %rax
movb $0x1, 0x28(%rax)
movq 0xa064(%rip), %rdi      # 0xeff0
leaq 0x5214(%rip), %rsi      # 0xa1a7
callq 0x32c0
movq %rax, -0x78(%rbp)
jmp 0x4f9e
movq -0x78(%rbp), %rdi
movq 0xa017(%rip), %rsi      # 0xefc0
callq 0x3300
jmp 0x4fb0
jmp 0x506a
movq -0x40(%rbp), %rax
movq (%rax), %rdi
callq 0x30b0
movq %rax, -0x80(%rbp)
jmp 0x4fc7
movq -0x40(%rbp), %rax
movq -0x80(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq 0x10(%rax), %rdi
leaq 0x51ef(%rip), %rsi      # 0xa1cd
xorl %edx, %edx
callq 0x3210
movq %rax, -0x88(%rbp)
jmp 0x4fee
movq -0x40(%rbp), %rax
movq -0x88(%rbp), %rcx
movq %rax, %rdx
addq $0x18, %rdx
movq %rcx, 0x18(%rax)
movq 0x10(%rax), %rdi
movq -0x30(%rbp), %rsi
movl $0x1, %ecx
callq 0x3160
jmp 0x5018
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x30(%rbp), %rsi
movl $0x28003, %edx          # imm = 0x28003
callq 0x31a0
jmp 0x5030
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x30(%rbp), %rsi
callq 0x3360
jmp 0x5043
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
xorl %eax, %eax
movl %eax, %edx
movl $0x1, %esi
callq 0x3540
jmp 0x505b
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x3470
jmp 0x506a
addq $0xa0, %rsp
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x3520
nopl (%rax)