// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/apps/sflview/sflview.cpp
// Function: GLUTKeyboard(unsigned char, int, int)
void GLUTKeyboard(unsigned char key, int x, int y)
{
  // Invert y coordinate
  y = GLUTwindow_height - y;

  // Determine modifiers
  int modifiers = glutGetModifiers();
  int shift = (modifiers & GLUT_ACTIVE_SHIFT);
  int ctrl = (modifiers & GLUT_ACTIVE_CTRL);
  int alt = (modifiers & GLUT_ACTIVE_ALT);

  // Convert control keys 
  int translated_key = key;
  if ((key >= 1) && (key <= 26)) {
    if (shift) translated_key += 64;
    else translated_key += 96;
    ctrl = GLUT_ACTIVE_CTRL;
  }

  // Process keyboard event
  if (alt) {
    if (translated_key == 'M') {
      show_model_names = !show_model_names;
      glutPostRedisplay();
    }
    else if (translated_key == 'm') {
      show_model = !show_model;
      glutPostRedisplay();
    }
  }
  else if (!ctrl) {
    switch (translated_key) {
    case 27: // ESC
      exit(0);
      break;

    case 32: { // SPACE
      const R3Camera& camera = viewer->Camera();
      printf("#camera  %g %g %g  %g %g %g  %g %g %g\n",
        camera.Origin().X(), camera.Origin().Y(), camera.Origin().Z(),
        camera.Towards().X(), camera.Towards().Y(), camera.Towards().Z(),
        camera.Up().X(), camera.Up().Y(), camera.Up().Z());
      break; }
    }
  }

  // Send keyboard event to viewer
  if (viewer->Keyboard(x, y, translated_key, shift, ctrl, alt)) {
    glutPostRedisplay();
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movl %edx, 0x8(%rsp)
movl %esi, 0xc(%rsp)
movl %edi, %r14d
movl 0x17cb0e(%rip), %ebp    # 0x1a7a04
callq 0x111bae
movl %eax, %r15d
andl $0x2, %eax
leal -0x1(%r14), %ecx
xorl %edx, %edx
movl %r15d, %r12d
andl $0x1, %r12d
sete %dl
shll $0x5, %edx
orl $0x40, %edx
xorl %ebx, %ebx
cmpb $0x1a, %cl
pushq $0x2
popq %r13
cmovael %eax, %r13d
cmovbl %edx, %ebx
orl %r14d, %ebx
andl $0x4, %r15d
jne 0x2af4e
testl %r13d, %r13d
jne 0x2b069
cmpl $0x20, %ebx
je 0x2af8c
cmpl $0x1b, %ebx
jne 0x2b069
xorl %edi, %edi
callq 0x27b50
cmpl $0x6d, %ebx
je 0x2af70
cmpl $0x4d, %ebx
jne 0x2b069
xorl %eax, %eax
cmpl $0x0, 0x181a4b(%rip)    # 0x1ac9b0
sete %al
movl %eax, 0x181a42(%rip)    # 0x1ac9b0
jmp 0x2af82
xorl %eax, %eax
cmpl $0x0, 0x17ca8f(%rip)    # 0x1a7a08
sete %al
movl %eax, 0x17ca86(%rip)    # 0x1a7a08
callq 0x10d110
jmp 0x2b069
movq 0x181a0d(%rip), %r14    # 0x1ac9a0
movsd 0x80(%r14), %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x88(%r14), %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x90(%r14), %xmm0
movsd %xmm0, 0x28(%rsp)
leaq 0xc8(%r14), %rsi
movq %rsi, 0x10(%rsp)
leaq 0x70(%rsp), %rdi
callq 0xb3446
leaq 0x70(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
leaq 0x58(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0xb3446
leaq 0x58(%rsp), %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x40(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0xb3446
leaq 0x40(%rsp), %rax
movsd 0x10(%rax), %xmm5
movsd 0xb0(%r14), %xmm6
movsd 0xb8(%r14), %xmm7
movsd 0xc0(%r14), %xmm0
movsd %xmm0, (%rsp)
leaq 0xef054(%rip), %rdi     # 0x11a098
movsd 0x38(%rsp), %xmm0
movsd 0x30(%rsp), %xmm1
movsd 0x28(%rsp), %xmm2
movsd 0x20(%rsp), %xmm3
movsd 0x18(%rsp), %xmm4
movb $0x8, %al
callq 0x27080
subl 0x8(%rsp), %ebp
movq 0x18192c(%rip), %rdi    # 0x1ac9a0
movq (%rdi), %rax
movl %r15d, (%rsp)
movl 0xc(%rsp), %esi
movl %ebp, %edx
movl %ebx, %ecx
movl %r12d, %r8d
movl %r13d, %r9d
callq *0x40(%rax)
testl %eax, %eax
je 0x2b095
callq 0x10d110
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq