// File: 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:
subq $0xc8, %rsp
movb %dil, %al
movb %al, 0xc7(%rsp)
movl %esi, 0xc0(%rsp)
movl %edx, 0xbc(%rsp)
movl 0x2962af(%rip), %eax    # 0x2c3ae4
subl 0xbc(%rsp), %eax
movl %eax, 0xbc(%rsp)
callq 0x2351c0
movl %eax, 0xb8(%rsp)
movl 0xb8(%rsp), %eax
andl $0x1, %eax
movl %eax, 0xb4(%rsp)
movl 0xb8(%rsp), %eax
andl $0x2, %eax
movl %eax, 0xb0(%rsp)
movl 0xb8(%rsp), %eax
andl $0x4, %eax
movl %eax, 0xac(%rsp)
movzbl 0xc7(%rsp), %eax
movl %eax, 0xa8(%rsp)
movzbl 0xc7(%rsp), %eax
cmpl $0x1, %eax
jl 0x2d8e4
movzbl 0xc7(%rsp), %eax
cmpl $0x1a, %eax
jg 0x2d8e4
cmpl $0x0, 0xb4(%rsp)
je 0x2d8c8
movl 0xa8(%rsp), %eax
addl $0x40, %eax
movl %eax, 0xa8(%rsp)
jmp 0x2d8d9
movl 0xa8(%rsp), %eax
addl $0x60, %eax
movl %eax, 0xa8(%rsp)
movl $0x2, 0xb0(%rsp)
cmpl $0x0, 0xac(%rsp)
je 0x2d943
cmpl $0x4d, 0xa8(%rsp)
jne 0x2d916
cmpl $0x0, 0x2a4bc1(%rip)    # 0x2d24c0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2a4bb1(%rip)    # 0x2d24c0
callq 0x22cf90
jmp 0x2d93e
cmpl $0x6d, 0xa8(%rsp)
jne 0x2d93c
cmpl $0x0, 0x2961c1(%rip)    # 0x2c3ae8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2961b1(%rip)    # 0x2c3ae8
callq 0x22cf90
jmp 0x2d93e
jmp 0x2dae0
cmpl $0x0, 0xb0(%rsp)
jne 0x2dade
movl 0xa8(%rsp), %eax
movl %eax, 0x54(%rsp)
subl $0x1b, %eax
je 0x2d971
jmp 0x2d963
movl 0x54(%rsp), %eax
subl $0x20, %eax
je 0x2d978
jmp 0x2dadc
xorl %edi, %edi
callq 0x28cb0
movq 0x2a4b31(%rip), %rdi    # 0x2d24b0
callq 0x2ee40
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x2ee60
movq %rax, %rdi
callq 0x2ee70
movsd %xmm0, 0x48(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x2ee60
movq %rax, %rdi
callq 0x2ee80
movsd %xmm0, 0x10(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x2ee60
movq %rax, %rdi
callq 0x2ee90
movsd %xmm0, 0x18(%rsp)
movq 0xa0(%rsp), %rsi
leaq 0x88(%rsp), %rdi
callq 0x2eea0
leaq 0x88(%rsp), %rdi
callq 0x2eef0
movsd %xmm0, 0x20(%rsp)
movq 0xa0(%rsp), %rsi
leaq 0x70(%rsp), %rdi
callq 0x2eea0
leaq 0x70(%rsp), %rdi
callq 0x2ef00
movsd %xmm0, 0x28(%rsp)
movq 0xa0(%rsp), %rsi
leaq 0x58(%rsp), %rdi
callq 0x2eea0
leaq 0x58(%rsp), %rdi
callq 0x2ef10
movsd %xmm0, 0x30(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x2ef20
movq %rax, %rdi
callq 0x2eef0
movsd %xmm0, 0x38(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x2ef20
movq %rax, %rdi
callq 0x2ef00
movsd %xmm0, 0x40(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x2ef20
movq %rax, %rdi
callq 0x2ef10
movsd 0x10(%rsp), %xmm1
movsd 0x18(%rsp), %xmm2
movsd 0x20(%rsp), %xmm3
movsd 0x28(%rsp), %xmm4
movsd 0x30(%rsp), %xmm5
movsd 0x38(%rsp), %xmm6
movsd 0x40(%rsp), %xmm7
movaps %xmm0, %xmm8
movsd 0x48(%rsp), %xmm0
leaq 0x213721(%rip), %rdi    # 0x2411f0
movsd %xmm8, (%rsp)
movb $0x8, %al
callq 0x28090
jmp 0x2dade
jmp 0x2dae0
movq 0x2a49c9(%rip), %rdi    # 0x2d24b0
movl 0xc0(%rsp), %esi
movl 0xbc(%rsp), %edx
movl 0xa8(%rsp), %ecx
movl 0xb4(%rsp), %r8d
movl 0xb0(%rsp), %r9d
movl 0xac(%rsp), %r10d
movq (%rdi), %rax
movl %r10d, (%rsp)
callq *0x40(%rax)
cmpl $0x0, %eax
je 0x2db28
callq 0x22cf90
addq $0xc8, %rsp
retq