// File: /workspace/github_c_makefile_star2_O2/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 0x4b4d
movq %r14, %r13
shrq $0x20, %r13
movl 0x28(%rbx), %eax
cmpl $-0x1, %eax
je 0x4aec
cmpl %r14d, 0x2c(%rbx)
setl %cl
cmpl %r13d, %eax
setg %al
orb %cl, %al
jne 0x4ae4
cmpl %r15d, 0x34(%rbx)
jl 0x4ae4
movq %r15, %rax
shrq $0x20, %rax
cmpl %eax, 0x30(%rbx)
jle 0x4aec
movq %rbx, %rdi
callq 0x2040
movl 0x38(%rbx), %eax
cmpl $-0x1, %eax
je 0x4ba6
cmpl %r14d, %eax
jne 0x4b9e
cmpl %r15d, 0x40(%rbx)
jne 0x4b9e
cmpl %r13d, 0x3c(%rbx)
jne 0x4b9e
movq %r15, %rax
shrq $0x20, %rax
cmpl %eax, 0x44(%rbx)
jne 0x4b9e
movl 0x48(%rbx), %ecx
movl 0x4c(%rbx), %eax
movl %ecx, %edx
orl %ebp, %edx
sete %dl
movl %eax, %esi
orl %r12d, %esi
sete %sil
orb %dl, %sil
cmpb $0x1, %sil
jne 0x4b9e
addl %ebp, %ecx
movl %ecx, 0x48(%rbx)
addl %r12d, %eax
movl %eax, 0x4c(%rbx)
jmp 0x4bb5
movq %rbx, (%rsp)
leaq 0x6fb(%rip), %r8        # 0x5253
leaq 0x7a6(%rip), %r9        # 0x5305
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x2160
movq %rbx, %rdi
callq 0x2040
movq %rbx, (%rsp)
leaq -0x648(%rip), %r8       # 0x453a
leaq -0x5de(%rip), %r9       # 0x45ab
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x2160
jmp 0x4c5d
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 0x693(%rip), %r8        # 0x5253
leaq 0x73e(%rip), %r9        # 0x5305
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x2160
movl 0x28(%rbx), %eax
cmpl $-0x1, %eax
je 0x4c5d
cmpl %r14d, %eax
jl 0x4c55
movl 0x30(%rbx), %ecx
cmpl %r15d, %ecx
jl 0x4c58
movl 0x2c(%rbx), %esi
cmpl %r13d, %esi
jg 0x4c58
movl 0x34(%rbx), %edx
movq %r15, %rdi
shrq $0x20, %rdi
cmpl %edi, %edx
jg 0x4c58
subl %ebp, %eax
movl %eax, 0x28(%rbx)
subl %ebp, %esi
movl %esi, 0x2c(%rbx)
subl %r12d, %ecx
movl %ecx, 0x30(%rbx)
subl %r12d, %edx
movl %edx, 0x34(%rbx)
cmpl %r14d, %eax
jge 0x4c24
movl %r14d, 0x28(%rbx)
movl %r14d, %eax
cmpl %r15d, %ecx
jge 0x4c30
movl %r15d, 0x30(%rbx)
movl %r15d, %ecx
cmpl %r13d, %esi
jle 0x4c3c
movl %r13d, 0x2c(%rbx)
movl %r13d, %esi
cmpl %edi, %edx
jle 0x4c45
movl %edi, 0x34(%rbx)
movl %edi, %edx
cmpl %eax, %esi
jge 0x4c4c
movl %eax, 0x2c(%rbx)
cmpl %ecx, %edx
jge 0x4c5d
movl %ecx, 0x34(%rbx)
jmp 0x4c5d
movl 0x30(%rbx), %ecx
cmpl %r15d, %ecx
jge 0x4c6f
pushq $0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testl %r12d, %r12d
jne 0x4c5d
shrq $0x20, %r15
cmpl %r15d, 0x34(%rbx)
jg 0x4c5d
cmpl %r14d, %eax
setge %cl
cmpl %r13d, %eax
setl %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x4ca4
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 0x4c5d
subl %ebp, %eax
cmpl %r14d, %eax
cmovlel %r14d, %eax
cmpl %r13d, %eax
cmovgel %r13d, %eax
movl %eax, 0x2c(%rbx)
jmp 0x4c5d