// File: /workspace/github_c_makefile_star2_O1/neovim[P]libvterm/src/screen.c
// Function: scrollrect
static int scrollrect(VTermRect rect, int downward, int rightward, void *user)
{
  VTermScreen *screen = user;

  if(screen->damage_merge != VTERM_DAMAGE_SCROLL) {
    vterm_scroll_rect(rect, downward, rightward,
        moverect_internal, erase_internal, screen);

    vterm_screen_flush_damage(screen);

    vterm_scroll_rect(rect, downward, rightward,
        moverect_user, erase_user, screen);

    return 1;
  }

  if(screen->damaged.start_row != -1 &&
     !rect_intersects(&rect, &screen->damaged)) {
    vterm_screen_flush_damage(screen);
  }

  if(screen->pending_scrollrect.start_row == -1) {
    screen->pending_scrollrect = rect;
    screen->pending_scroll_downward  = downward;
    screen->pending_scroll_rightward = rightward;
  }
  else if(rect_equal(&screen->pending_scrollrect, &rect) &&
     ((screen->pending_scroll_downward  == 0 && downward  == 0) ||
      (screen->pending_scroll_rightward == 0 && rightward == 0))) {
    screen->pending_scroll_downward  += downward;
    screen->pending_scroll_rightward += rightward;
  }
  else {
    vterm_screen_flush_damage(screen);

    screen->pending_scrollrect = rect;
    screen->pending_scroll_downward  = downward;
    screen->pending_scroll_rightward = rightward;
  }

  vterm_scroll_rect(rect, downward, rightward,
      moverect_internal, erase_internal, screen);

  if(screen->damaged.start_row == -1)
    return 1;

  if(rect_contains(&rect, &screen->damaged)) {
    /* Scroll region entirely contains the damage; just move it */
    vterm_rect_move(&screen->damaged, -downward, -rightward);
    rect_clip(&screen->damaged, &rect);
  }
  /* There are a number of possible cases here, but lets restrict this to only
   * the common case where we might actually gain some performance by
   * optimising it. Namely, a vertical scroll that neatly cuts the damage
   * region in half.
   */
  else if(rect.start_col <= screen->damaged.start_col &&
          rect.end_col   >= screen->damaged.end_col &&
          rightward == 0) {
    if(screen->damaged.start_row >= rect.start_row &&
       screen->damaged.start_row  < rect.end_row) {
      screen->damaged.start_row -= downward;
      if(screen->damaged.start_row < rect.start_row)
        screen->damaged.start_row = rect.start_row;
      if(screen->damaged.start_row > rect.end_row)
        screen->damaged.start_row = rect.end_row;
    }
    if(screen->damaged.end_row >= rect.start_row &&
       screen->damaged.end_row  < rect.end_row) {
      screen->damaged.end_row -= downward;
      if(screen->damaged.end_row < rect.start_row)
        screen->damaged.end_row = rect.start_row;
      if(screen->damaged.end_row > rect.end_row)
        screen->damaged.end_row = rect.end_row;
    }
  }
  else {
    DEBUG_LOG("TODO: Just flush and redo damaged=" STRFrect " rect=" STRFrect "\n",
        ARGSrect(screen->damaged), ARGSrect(rect));
  }

  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %r8, %rbx
movl %ecx, %r12d
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %r14
cmpl $0x3, 0x24(%r8)
jne 0x53c2
movq %r14, %r13
shrq $0x20, %r13
movl 0x28(%rbx), %eax
cmpl $-0x1, %eax
je 0x52ac
cmpl %r14d, 0x2c(%rbx)
setl %cl
cmpl %r13d, %eax
setg %al
orb %cl, %al
jne 0x52a4
cmpl %r15d, 0x34(%rbx)
jl 0x52a4
movq %r15, %rax
shrq $0x20, %rax
cmpl %eax, 0x30(%rbx)
jle 0x52ac
movq %rbx, %rdi
callq 0x2040
movl 0x38(%rbx), %eax
cmpl $-0x1, %eax
je 0x52f2
cmpl %r14d, %eax
jne 0x52ea
cmpl %r15d, 0x40(%rbx)
jne 0x52ea
cmpl %r13d, 0x3c(%rbx)
jne 0x52ea
movq %r15, %rax
shrq $0x20, %rax
cmpl %eax, 0x44(%rbx)
jne 0x52ea
movl 0x48(%rbx), %eax
movl %eax, %ecx
orl %ebp, %ecx
je 0x547b
movl 0x4c(%rbx), %ecx
orl %r12d, %ecx
je 0x547b
movq %rbx, %rdi
callq 0x2040
movq %r14, 0x38(%rbx)
movq %r15, 0x40(%rbx)
movl %ebp, 0x48(%rbx)
movl %r12d, 0x4c(%rbx)
movq %rbx, (%rsp)
leaq 0x753(%rip), %r8        # 0x5a5f
leaq 0x875(%rip), %r9        # 0x5b88
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x2170
movl 0x28(%rbx), %eax
cmpl $-0x1, %eax
je 0x540e
cmpl %r14d, %eax
jl 0x5350
cmpl %r15d, 0x30(%rbx)
jl 0x5350
cmpl %r13d, 0x2c(%rbx)
jg 0x5350
movq %r15, %rcx
shrq $0x20, %rcx
cmpl %ecx, 0x34(%rbx)
jle 0x5422
cmpl %r15d, 0x30(%rbx)
jl 0x540e
testl %r12d, %r12d
jne 0x540e
shrq $0x20, %r15
cmpl %r15d, 0x34(%rbx)
jg 0x540e
cmpl %r14d, %eax
setge %cl
cmpl %r13d, %eax
setl %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x5397
subl %ebp, %eax
cmpl %r14d, %eax
cmovlel %r14d, %eax
cmpl %r13d, %eax
cmovgel %r13d, %eax
movl %eax, 0x28(%rbx)
movl 0x2c(%rbx), %eax
cmpl %r14d, %eax
setge %cl
cmpl %r13d, %eax
setl %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x540e
subl %ebp, %eax
cmpl %r14d, %eax
cmovlel %r14d, %eax
cmpl %r13d, %eax
cmovgel %r13d, %eax
movl %eax, 0x2c(%rbx)
jmp 0x540e
movq %rbx, (%rsp)
leaq 0x692(%rip), %r8        # 0x5a5f
leaq 0x7b4(%rip), %r9        # 0x5b88
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x2170
movq %rbx, %rdi
callq 0x2040
movq %rbx, (%rsp)
leaq -0x7fd(%rip), %r8       # 0x4bfa
leaq -0x796(%rip), %r9       # 0x4c68
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x2170
movl $0x1, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
subl %ebp, %eax
movl %eax, 0x28(%rbx)
movl 0x2c(%rbx), %edx
movl 0x30(%rbx), %edi
subl %ebp, %edx
movl %edx, 0x2c(%rbx)
subl %r12d, %edi
movl %edi, 0x30(%rbx)
movl 0x34(%rbx), %esi
subl %r12d, %esi
movl %esi, 0x34(%rbx)
cmpl %r14d, %eax
jge 0x544a
movl %r14d, 0x28(%rbx)
cmpl %r15d, %edi
jge 0x5453
movl %r15d, 0x30(%rbx)
cmpl %r13d, %edx
jle 0x545c
movl %r13d, 0x2c(%rbx)
cmpl %ecx, %esi
jle 0x5463
movl %ecx, 0x34(%rbx)
movl 0x28(%rbx), %eax
cmpl %eax, 0x2c(%rbx)
jge 0x546e
movl %eax, 0x2c(%rbx)
movl 0x30(%rbx), %eax
cmpl %eax, 0x34(%rbx)
jge 0x540e
movl %eax, 0x34(%rbx)
jmp 0x540e
addl %ebp, %eax
movl %eax, 0x48(%rbx)
addl %r12d, 0x4c(%rbx)
jmp 0x5301