// File: tomfunkhouser[P]gaps/apps/gapsview/gapsview.cpp
// Function: GLUTKeyboard(unsigned char, int, int)
static void
GLUTKeyboard(unsigned char key, int x, int y)
{
  // Initialize redraw
  RNBoolean redraw = TRUE;

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

  // Process keyboard button event
  if (ctrl) {
    // Control which data sources are drawn
    switch(key) {
    case 7: // ctrl-G
      show_grids = !show_grids;
      break;

    case 12: // ctrl-L
      show_gsvs = !show_gsvs;
      break;

    case 13: // ctrl-M
      show_meshes = !show_meshes;
      break;

    case 15: // ctrl-O
      show_scenes = !show_scenes;
      break;

    case 16: // ctrl-P
      show_pointsets = !show_pointsets;
      break;

    case 19: // ctrl-S
      show_sfls = !show_sfls;
      break;

    default:
      redraw = FALSE;
      break;
    }
  }
  else if (alt) {
    // Control how things are drawn
    switch (key) {
    case 'C':
    case 'c':
      color_scheme = RGB_COLOR_SCHEME;
      break;

    case 'E':
    case 'e':
      color_scheme = NULL_COLOR_SCHEME;
      break;

    case 'I':
    case 'i':
      color_scheme = INSTANCE_COLOR_SCHEME;
      break;

    case 'L':
    case 'l':
      color_scheme = CATEGORY_COLOR_SCHEME;
      break;

    case 'S':
    case 's':
      color_scheme = SHADING_COLOR_SCHEME;
      break;

    case 'X':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_X]++;
        if (grid_slice_coords[RN_X] >= grids[selected_model_index]->XResolution()) 
          grid_slice_coords[RN_X] = grids[selected_model_index]->XResolution() - 1;
      }
      break;

    case 'x':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_X]--;
        if (grid_slice_coords[RN_X] < 0)
          grid_slice_coords[RN_X] = 0;
      }
      break;

    case 'Y':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Y]++;
        if (grid_slice_coords[RN_Y] >= grids[selected_model_index]->YResolution()) 
          grid_slice_coords[RN_Y] = grids[selected_model_index]->YResolution() - 1;
      }
      break;

    case 'y':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Y]--;
        if (grid_slice_coords[RN_Y] < 0)
          grid_slice_coords[RN_Y] = 0;
      }
      break;

    case 'Z':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Z]++;
        if (grid_slice_coords[RN_Z] >= grids[selected_model_index]->ZResolution()) 
          grid_slice_coords[RN_Z] = grids[selected_model_index]->ZResolution() - 1;
      }
      break;

    case 'z':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Z]--;
        if (grid_slice_coords[RN_Z] < 0)
          grid_slice_coords[RN_Z] = 0;
      }
      break;

    default:
      redraw = FALSE;
      break;
    }
  }
  else {
    // Control which data elements are drawn
    switch (key) {
    case '1':
    case '2':
    case '3':
    case '4':
      selected_model_index = key - '1';
      if (selected_model_index > nmodels - 1) {
        selected_model_index = nmodels - 1;
      }
      break;

    case 'A':
    case 'a':
      show_axes = !show_axes;
      break;

    case 'B':
    case 'b':
      show_bbox = !show_bbox;
      break;

    case 'C':
    case 'c':
      show_cameras = !show_cameras;
      break;

    case 'D':
    case 'd':
      show_image_depths = !show_image_depths;
      break;
      
    case 'E':
    case 'e':
      show_edges = !show_edges;
      break;

    case 'F':
    case 'f':
      show_surfaces = !show_surfaces;
      break;

    case 'G':
    case 'g':
      show_slices = !show_slices;
      break;

    case 'I':
      show_image_billboards = !show_image_billboards;
      break;

    case 'i':
      show_image_insets = !show_image_insets;
      break;

    case 'L':
    case 'l':
      show_text_labels = !show_text_labels;
      break;

    case 'N':
    case 'n':
      show_normals = !show_normals;
      break;

    case 'P':
    case 'p':
      show_points = !show_points;
      break;

    case 'R':
    case 'r':
      show_image_rays = !show_image_rays;
      break;

    case 'T':
    case 't':
      show_grid_threshold = !show_grid_threshold;
      break;

    case ' ': {
      // Print camera
      const R3Camera& camera = viewer->Camera();
      printf("#camera  %g %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(),
             camera.YFOV());
      break; }
      
    case 27: // ESCAPE
      GLUTStop();
      break;

    default:
      redraw = FALSE;
      break;
    }
  }
  
  // Remember mouse position 
  GLUTmouse[0] = x;
  GLUTmouse[1] = GLUTwindow_height - y;

  // Remember modifiers 
  GLUTmodifiers = modifiers;

  // Redraw
  if (redraw) glutPostRedisplay();  
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movb %dil, %al
movb %al, 0x107(%rsp)
movl %esi, 0x100(%rsp)
movl %edx, 0xfc(%rsp)
movl $0x1, 0xf8(%rsp)
callq 0x1fc3c0
movl %eax, 0xf4(%rsp)
movl 0xf4(%rsp), %eax
andl $0x2, %eax
movl %eax, 0xf0(%rsp)
movl 0xf4(%rsp), %eax
andl $0x4, %eax
movl %eax, 0xec(%rsp)
cmpl $0x0, 0xf0(%rsp)
je 0x2fff5
movzbl 0x107(%rsp), %eax
addl $-0x7, %eax
movl %eax, %ecx
movq %rcx, 0x90(%rsp)
subl $0xc, %eax
ja 0x2ffe5
movq 0x90(%rsp), %rax
leaq 0x236429(%rip), %rcx    # 0x26636c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x0, 0x2bfc31(%rip)    # 0x2efb84
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bfc21(%rip)    # 0x2efb84
jmp 0x2fff0
cmpl $0x0, 0x2bfc31(%rip)    # 0x2efba0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bfc21(%rip)    # 0x2efba0
jmp 0x2fff0
cmpl $0x0, 0x2bfbf8(%rip)    # 0x2efb80
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bfbe8(%rip)    # 0x2efb80
jmp 0x2fff0
cmpl $0x0, 0x2bfbdb(%rip)    # 0x2efb7c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bfbcb(%rip)    # 0x2efb7c
jmp 0x2fff0
cmpl $0x0, 0x2bfbba(%rip)    # 0x2efb74
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bfbaa(%rip)    # 0x2efb74
jmp 0x2fff0
cmpl $0x0, 0x2bfbb5(%rip)    # 0x2efb88
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bfba5(%rip)    # 0x2efb88
jmp 0x2fff0
movl $0x0, 0xf8(%rsp)
jmp 0x306a3
cmpl $0x0, 0xec(%rsp)
je 0x3030a
movzbl 0x107(%rsp), %eax
addl $-0x43, %eax
movl %eax, %ecx
movq %rcx, 0x88(%rsp)
subl $0x37, %eax
ja 0x302fa
movq 0x88(%rsp), %rax
leaq 0x23625c(%rip), %rcx    # 0x26628c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x1, 0x2bfb2d(%rip)    # 0x2efb70
jmp 0x30305
movl $0x0, 0x2bfb1e(%rip)    # 0x2efb70
jmp 0x30305
movl $0x4, 0x2bfb0f(%rip)    # 0x2efb70
jmp 0x30305
movl $0x3, 0x2bfb00(%rip)    # 0x2efb70
jmp 0x30305
movl $0x2, 0x2bfaf1(%rip)    # 0x2efb70
jmp 0x30305
movl 0x2cec3a(%rip), %eax    # 0x2fecc4
movl %eax, 0x84(%rsp)
leaq 0x2ce770(%rip), %rdi    # 0x2fe808
callq 0x38730
movl %eax, %ecx
movl 0x84(%rsp), %eax
cmpl %ecx, %eax
jge 0x30112
movl 0x2cebf0(%rip), %eax    # 0x2feca0
addl $0x1, %eax
movl %eax, 0x2cebe7(%rip)    # 0x2feca0
movl 0x2cebe1(%rip), %eax    # 0x2feca0
movl %eax, 0x80(%rsp)
movl 0x2cebf8(%rip), %esi    # 0x2fecc4
leaq 0x2ce735(%rip), %rdi    # 0x2fe808
callq 0x38800
movq (%rax), %rdi
callq 0x38990
movl %eax, %ecx
movl 0x80(%rsp), %eax
cmpl %ecx, %eax
jl 0x30110
movl 0x2cebd1(%rip), %esi    # 0x2fecc4
leaq 0x2ce70e(%rip), %rdi    # 0x2fe808
callq 0x38800
movq (%rax), %rdi
callq 0x38990
subl $0x1, %eax
movl %eax, 0x2ceb90(%rip)    # 0x2feca0
jmp 0x30112
jmp 0x30305
movl 0x2ceba7(%rip), %eax    # 0x2fecc4
movl %eax, 0x7c(%rsp)
leaq 0x2ce6e0(%rip), %rdi    # 0x2fe808
callq 0x38730
movl %eax, %ecx
movl 0x7c(%rsp), %eax
cmpl %ecx, %eax
jge 0x3015b
movl 0x2ceb63(%rip), %eax    # 0x2feca0
addl $-0x1, %eax
movl %eax, 0x2ceb5a(%rip)    # 0x2feca0
cmpl $0x0, 0x2ceb53(%rip)    # 0x2feca0
jge 0x30159
movl $0x0, 0x2ceb47(%rip)    # 0x2feca0
jmp 0x3015b
jmp 0x30305
movl 0x2ceb5e(%rip), %eax    # 0x2fecc4
movl %eax, 0x78(%rsp)
leaq 0x2ce697(%rip), %rdi    # 0x2fe808
callq 0x38730
movl %eax, %ecx
movl 0x78(%rsp), %eax
cmpl %ecx, %eax
jge 0x301e2
movl 0x2ceb1e(%rip), %eax    # 0x2feca4
addl $0x1, %eax
movl %eax, 0x2ceb15(%rip)    # 0x2feca4
movl 0x2ceb0f(%rip), %eax    # 0x2feca4
movl %eax, 0x74(%rsp)
movl 0x2ceb25(%rip), %esi    # 0x2fecc4
leaq 0x2ce662(%rip), %rdi    # 0x2fe808
callq 0x38800
movq (%rax), %rdi
callq 0x389b0
movl %eax, %ecx
movl 0x74(%rsp), %eax
cmpl %ecx, %eax
jl 0x301e0
movl 0x2ceb01(%rip), %esi    # 0x2fecc4
leaq 0x2ce63e(%rip), %rdi    # 0x2fe808
callq 0x38800
movq (%rax), %rdi
callq 0x389b0
subl $0x1, %eax
movl %eax, 0x2ceac4(%rip)    # 0x2feca4
jmp 0x301e2
jmp 0x30305
movl 0x2cead7(%rip), %eax    # 0x2fecc4
movl %eax, 0x70(%rsp)
leaq 0x2ce610(%rip), %rdi    # 0x2fe808
callq 0x38730
movl %eax, %ecx
movl 0x70(%rsp), %eax
cmpl %ecx, %eax
jge 0x3022b
movl 0x2cea97(%rip), %eax    # 0x2feca4
addl $-0x1, %eax
movl %eax, 0x2cea8e(%rip)    # 0x2feca4
cmpl $0x0, 0x2cea87(%rip)    # 0x2feca4
jge 0x30229
movl $0x0, 0x2cea7b(%rip)    # 0x2feca4
jmp 0x3022b
jmp 0x30305
movl 0x2cea8e(%rip), %eax    # 0x2fecc4
movl %eax, 0x6c(%rsp)
leaq 0x2ce5c7(%rip), %rdi    # 0x2fe808
callq 0x38730
movl %eax, %ecx
movl 0x6c(%rsp), %eax
cmpl %ecx, %eax
jge 0x302b2
movl 0x2cea52(%rip), %eax    # 0x2feca8
addl $0x1, %eax
movl %eax, 0x2cea49(%rip)    # 0x2feca8
movl 0x2cea43(%rip), %eax    # 0x2feca8
movl %eax, 0x68(%rsp)
movl 0x2cea55(%rip), %esi    # 0x2fecc4
leaq 0x2ce592(%rip), %rdi    # 0x2fe808
callq 0x38800
movq (%rax), %rdi
callq 0x389d0
movl %eax, %ecx
movl 0x68(%rsp), %eax
cmpl %ecx, %eax
jl 0x302b0
movl 0x2cea31(%rip), %esi    # 0x2fecc4
leaq 0x2ce56e(%rip), %rdi    # 0x2fe808
callq 0x38800
movq (%rax), %rdi
callq 0x389d0
subl $0x1, %eax
movl %eax, 0x2ce9f8(%rip)    # 0x2feca8
jmp 0x302b2
jmp 0x30305
movl 0x2cea0a(%rip), %eax    # 0x2fecc4
movl %eax, 0x64(%rsp)
leaq 0x2ce543(%rip), %rdi    # 0x2fe808
callq 0x38730
movl %eax, %ecx
movl 0x64(%rsp), %eax
cmpl %ecx, %eax
jge 0x302f8
movl 0x2ce9ce(%rip), %eax    # 0x2feca8
addl $-0x1, %eax
movl %eax, 0x2ce9c5(%rip)    # 0x2feca8
cmpl $0x0, 0x2ce9be(%rip)    # 0x2feca8
jge 0x302f6
movl $0x0, 0x2ce9b2(%rip)    # 0x2feca8
jmp 0x302f8
jmp 0x30305
movl $0x0, 0xf8(%rsp)
jmp 0x306a1
movzbl 0x107(%rsp), %eax
addl $-0x1b, %eax
movl %eax, %ecx
movq %rcx, 0x58(%rsp)
subl $0x59, %eax
ja 0x30694
movq 0x58(%rsp), %rax
leaq 0x235df3(%rip), %rcx    # 0x266124
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl 0x107(%rsp), %eax
subl $0x31, %eax
movl %eax, 0x2ce979(%rip)    # 0x2fecc4
movl 0x2ce973(%rip), %eax    # 0x2fecc4
movl 0x2cebad(%rip), %ecx    # 0x2fef04
subl $0x1, %ecx
cmpl %ecx, %eax
jle 0x3036d
movl 0x2ceba0(%rip), %eax    # 0x2fef04
subl $0x1, %eax
movl %eax, 0x2ce957(%rip)    # 0x2fecc4
jmp 0x3069f
cmpl $0x0, 0x2ceb87(%rip)    # 0x2fef00
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ceb77(%rip)    # 0x2fef00
jmp 0x3069f
cmpl $0x0, 0x2ceb67(%rip)    # 0x2feefc
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ceb57(%rip)    # 0x2feefc
jmp 0x3069f
cmpl $0x0, 0x2bf7db(%rip)    # 0x2efb8c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bf7cb(%rip)    # 0x2efb8c
jmp 0x3069f
cmpl $0x0, 0x2ceb27(%rip)    # 0x2feef4
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ceb17(%rip)    # 0x2feef4
jmp 0x3069f
cmpl $0x0, 0x2ce8e7(%rip)    # 0x2fecd0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ce8d7(%rip)    # 0x2fecd0
jmp 0x3069f
cmpl $0x0, 0x2ce8c7(%rip)    # 0x2feccc
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ce8b7(%rip)    # 0x2feccc
jmp 0x3069f
cmpl $0x0, 0x2ceabf(%rip)    # 0x2feee0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ceaaf(%rip)    # 0x2feee0
jmp 0x3069f
cmpl $0x0, 0x2ceab3(%rip)    # 0x2feef0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ceaa3(%rip)    # 0x2feef0
jmp 0x3069f
cmpl $0x0, 0x2cea93(%rip)    # 0x2feeec
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2cea83(%rip)    # 0x2feeec
jmp 0x3069f
cmpl $0x0, 0x2cea6f(%rip)    # 0x2feee4
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2cea5f(%rip)    # 0x2feee4
jmp 0x3069f
cmpl $0x0, 0x2ce837(%rip)    # 0x2fecc8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ce827(%rip)    # 0x2fecc8
jmp 0x3069f
cmpl $0x0, 0x2bf6cb(%rip)    # 0x2efb78
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2bf6bb(%rip)    # 0x2efb78
jmp 0x3069f
cmpl $0x0, 0x2cea2f(%rip)    # 0x2feef8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2cea1f(%rip)    # 0x2feef8
jmp 0x3069f
cmpl $0x0, 0x2cea03(%rip)    # 0x2feee8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2ce9f3(%rip)    # 0x2feee8
jmp 0x3069f
movq 0x2ce7af(%rip), %rdi    # 0x2fecb0
callq 0x38d50
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x38c00
movq %rax, %rdi
callq 0x38bb0
movsd %xmm0, 0x50(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x38c00
movq %rax, %rdi
callq 0x38c10
movsd %xmm0, 0x10(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x38c00
movq %rax, %rdi
callq 0x38c20
movsd %xmm0, 0x18(%rsp)
movq 0xe0(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x38c30
leaq 0xc8(%rsp), %rdi
callq 0x38c80
movsd %xmm0, 0x20(%rsp)
movq 0xe0(%rsp), %rsi
leaq 0xb0(%rsp), %rdi
callq 0x38c30
leaq 0xb0(%rsp), %rdi
callq 0x38c90
movsd %xmm0, 0x28(%rsp)
movq 0xe0(%rsp), %rsi
leaq 0x98(%rsp), %rdi
callq 0x38c30
leaq 0x98(%rsp), %rdi
callq 0x38ca0
movsd %xmm0, 0x30(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x38cb0
movq %rax, %rdi
callq 0x38c80
movsd %xmm0, 0x38(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x38cb0
movq %rax, %rdi
callq 0x38c90
movsd %xmm0, 0x40(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x38cb0
movq %rax, %rdi
callq 0x38ca0
movsd %xmm0, 0x48(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x38ce0
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
movsd 0x48(%rsp), %xmm9
movaps %xmm0, %xmm8
movsd 0x50(%rsp), %xmm0
leaq 0x235ddd(%rip), %rdi    # 0x266454
movsd %xmm9, (%rsp)
movsd %xmm8, 0x8(%rsp)
movb $0x8, %al
callq 0x290f0
jmp 0x3069f
callq 0x364a0
jmp 0x3069f
movl $0x0, 0xf8(%rsp)
jmp 0x306a1
jmp 0x306a3
movl 0x100(%rsp), %eax
movl %eax, 0x2ce858(%rip)    # 0x2fef08
movl 0x2bf43e(%rip), %eax    # 0x2efaf4
subl 0xfc(%rsp), %eax
movl %eax, 0x2ce849(%rip)    # 0x2fef0c
movl 0xf4(%rsp), %eax
movl %eax, 0x2ce840(%rip)    # 0x2fef10
cmpl $0x0, 0xf8(%rsp)
je 0x306df
callq 0x1f4190
addq $0x108, %rsp            # imm = 0x108
retq
nopw (%rax,%rax)