// File: /workspace/github_c_makefile_star2_O2/mcaimi[P]st/x.c
// Function: go_fullscreen
void
go_fullscreen(const Arg *arg)
{
  int error;
  unsigned int has_fullscreen_set = 0;
  Atom actual_type_return, req_property_type = XInternAtom(xw.dpy, "ATOM", False);
  int actual_format_return;
  unsigned long nitems_return, bytes_after_return;
  long long_offset, long_length;
  unsigned char *data = NULL;

  // query Xlib for current window properties. we need to determine whether the _NET_WM_STATE_FULLSCREEN
  // atom is already set.
  // https://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html
  long_offset = 0; // retrieve from the beginning of property list
  long_length = GET_WINDOW_PROPERTY_SIZE;
  error = XGetWindowProperty(xw.dpy, xw.win,
                               xw.window_state,
                               long_offset,
                               long_length,
                               FALSE,
                               req_property_type,
                               &actual_type_return,
                               &actual_format_return,
                               &nitems_return,
                               &bytes_after_return,
                               &data);

  if (error != Success) {
    fprintf(stderr, "%s - %s [%d]\n", "Xst ERROR", "go_fullscreen(): XGetWindowProperty() failed.", error );
    return;
  }

  // check if the _NET_WM_STATE_FULLSCREEN property is set:
  if (data) {
    for (int i=0; i<nitems_return; i++) {
      has_fullscreen_set = (xw.window_fullscreen == ((unsigned long*)data)[i]) ? 1 : 0; // property is 32bit cast to unsigned long
      if (has_fullscreen_set) {
        break;
      }
    }
    XFree(data);
  }

  // see https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html, _NET_WM_STATE paragraph
  /*
    window  = the respective client window
    message_type = _NET_WM_STATE
    format = 32
    data.l[0] = the action, as listed below
    data.l[1] = first property to alter
    data.l[2] = second property to alter
    data.l[3] = source indication
    other data.l[] elements = 0

    _NET_WM_STATE_REMOVE 0
    _NET_WM_STATE_ADD 1
    _NET_WM_STATE_TOGGLE 2
  */

  // See Xlib.h, line 36
  XEvent xevent;
  bzero(&xevent, sizeof(xevent));
  // prepare client message
  // we are interested in the 'xclient' field of the Xevent union
  xevent.type = ClientMessage;
  xevent.xclient.window = xw.win;
  xevent.xclient.message_type = xw.window_state;
  xevent.xclient.format = 32;
  xevent.xclient.data.l[0] = (! has_fullscreen_set) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
  xevent.xclient.data.l[1] = xw.window_fullscreen;
  xevent.xclient.data.l[2] = 0;
  xevent.xclient.data.l[3] = 0;
  xevent.xclient.data.l[4] = 0;
  // Message must be sent to root win, see https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm140130317705584
  // for specific parameters (for XCB). For Xlib, as used in this program, the equivalent Root window flags are named:
  // X.h:#define SubstructureNotifyMask              (1L<<19)
  // X.h:#define SubstructureRedirectMask    (1L<<20)
  // as found by grepping through Xorg's header files
  XSendEvent(xw.dpy, DefaultRootWindow(xw.dpy), FALSE, SubstructureNotifyMask|SubstructureRedirectMask, &xevent);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0xf0, %rsp
movq 0x13dbb(%rip), %rdi     # 0x20bc8
leaq 0x9127(%rip), %rsi      # 0x15f3b
xorl %edx, %edx
callq 0x6800
leaq 0x8(%rsp), %r10
andq $0x0, (%r10)
movq 0x13d9d(%rip), %rdi     # 0x20bc8
movq 0x13da6(%rip), %rsi     # 0x20bd8
movq 0x13de7(%rip), %rdx     # 0x20c20
leaq 0x20(%rsp), %r11
leaq 0x10(%rsp), %rbx
leaq 0x1c(%rsp), %r14
leaq 0x28(%rsp), %r15
movl $0xffff, %r8d           # imm = 0xFFFF
xorl %ecx, %ecx
xorl %r9d, %r9d
pushq %r10
pushq %r11
pushq %rbx
pushq %r14
pushq %r15
pushq %rax
callq 0x61f0
addq $0x30, %rsp
testl %eax, %eax
jne 0xcf3e
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0xceae
movq 0x10(%rsp), %rax
movq 0x13d8f(%rip), %rcx     # 0x20c18
xorl %esi, %esi
movq %rsi, %rdx
cmpq %rsi, %rax
je 0xce9d
leaq 0x1(%rdx), %rsi
cmpq (%rdi,%rdx,8), %rcx
jne 0xce8b
xorl %r14d, %r14d
cmpq %rdx, %rax
setbe %r14b
callq 0x60a0
jmp 0xceb2
pushq $0x1
popq %r14
leaq 0x30(%rsp), %rbx
movl $0xc0, %edx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x60c0
movl $0x21, (%rbx)
movq 0x13d05(%rip), %rax     # 0x20bd8
movq %rax, 0x20(%rbx)
movq 0x13d42(%rip), %rax     # 0x20c20
movq %rax, 0x28(%rbx)
movl $0x20, 0x30(%rbx)
movq %r14, 0x38(%rbx)
movq 0x13d24(%rip), %rax     # 0x20c18
movq %rax, 0x40(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x48(%rbx)
andq $0x0, 0x58(%rbx)
movq 0x13cbd(%rip), %rdi     # 0x20bc8
movq 0xe8(%rdi), %rax
movslq 0xe0(%rdi), %rcx
shlq $0x7, %rcx
movq 0x10(%rax,%rcx), %rsi
movl $0x180000, %ecx         # imm = 0x180000
xorl %edx, %edx
movq %rbx, %r8
callq 0x66c0
addq $0xf0, %rsp
popq %rbx
popq %r14
popq %r15
retq
movq 0x100ab(%rip), %rcx     # 0x1cff0
movq (%rcx), %rdi
leaq 0x8ff1(%rip), %rsi      # 0x15f40
leaq 0x8ff8(%rip), %rdx      # 0x15f4e
leaq 0x8ffb(%rip), %rcx      # 0x15f58
movl %eax, %r8d
xorl %eax, %eax
callq 0x6970
jmp 0xcf31