// File: tomfunkhouser[P]gaps/apps/sflview/sflview.cpp
// Function: GLUTSpecial(int, int, int)
void GLUTSpecial(int 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);

  // Translate key
  int translated_key = key;
  switch (key) {
    case GLUT_KEY_PAGE_DOWN: translated_key = R3_SURFEL_VIEWER_PAGE_DOWN_KEY; break;
    case GLUT_KEY_PAGE_UP: translated_key = R3_SURFEL_VIEWER_PAGE_UP_KEY; break;
    case GLUT_KEY_DOWN: translated_key = R3_SURFEL_VIEWER_DOWN_KEY; break;
    case GLUT_KEY_UP: translated_key = R3_SURFEL_VIEWER_UP_KEY; break;
    case GLUT_KEY_LEFT: translated_key = R3_SURFEL_VIEWER_LEFT_KEY; break;
    case GLUT_KEY_RIGHT: translated_key = R3_SURFEL_VIEWER_RIGHT_KEY; break;
    case GLUT_KEY_HOME: translated_key = R3_SURFEL_VIEWER_HOME_KEY; break;
    case GLUT_KEY_END: translated_key = R3_SURFEL_VIEWER_END_KEY; break;
    case GLUT_KEY_INSERT: translated_key = R3_SURFEL_VIEWER_INSERT_KEY; break;
    case GLUT_KEY_F1: translated_key = R3_SURFEL_VIEWER_F1_KEY; break;
    case GLUT_KEY_F2: translated_key = R3_SURFEL_VIEWER_F2_KEY; break;
    case GLUT_KEY_F3: translated_key = R3_SURFEL_VIEWER_F3_KEY; break;
    case GLUT_KEY_F4: translated_key = R3_SURFEL_VIEWER_F4_KEY; break;
    case GLUT_KEY_F5: translated_key = R3_SURFEL_VIEWER_F5_KEY; break;
    case GLUT_KEY_F6: translated_key = R3_SURFEL_VIEWER_F6_KEY; break;
    case GLUT_KEY_F7: translated_key = R3_SURFEL_VIEWER_F7_KEY; break;
    case GLUT_KEY_F8: translated_key = R3_SURFEL_VIEWER_F8_KEY; break;
    case GLUT_KEY_F9: translated_key = R3_SURFEL_VIEWER_F9_KEY; break;
    case GLUT_KEY_F10: translated_key = R3_SURFEL_VIEWER_F10_KEY; break;
    case GLUT_KEY_F11: translated_key = R3_SURFEL_VIEWER_F11_KEY; break;
    case GLUT_KEY_F12: translated_key = R3_SURFEL_VIEWER_F12_KEY; break;
  }

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

// Assembly:
subq $0x38, %rsp
movl %edi, 0x34(%rsp)
movl %esi, 0x30(%rsp)
movl %edx, 0x2c(%rsp)
movl 0x29645e(%rip), %eax    # 0x2c3ae4
movl 0x2c(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x2c(%rsp)
callq 0x2351c0
movl %eax, 0x28(%rsp)
movl 0x28(%rsp), %eax
andl $0x1, %eax
movl %eax, 0x24(%rsp)
movl 0x28(%rsp), %eax
andl $0x2, %eax
movl %eax, 0x20(%rsp)
movl 0x28(%rsp), %eax
andl $0x4, %eax
movl %eax, 0x1c(%rsp)
movl 0x34(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x34(%rsp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, 0x10(%rsp)
subl $0x6b, %eax
ja 0x2d7d5
movq 0x10(%rsp), %rax
leaq 0x21395c(%rip), %rcx    # 0x241040
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x407, 0x18(%rsp)      # imm = 0x407
jmp 0x2d7d5
movl $0x408, 0x18(%rsp)      # imm = 0x408
jmp 0x2d7d5
movl $0x402, 0x18(%rsp)      # imm = 0x402
jmp 0x2d7d5
movl $0x403, 0x18(%rsp)      # imm = 0x403
jmp 0x2d7d5
movl $0x400, 0x18(%rsp)      # imm = 0x400
jmp 0x2d7d5
movl $0x401, 0x18(%rsp)      # imm = 0x401
jmp 0x2d7d5
movl $0x404, 0x18(%rsp)      # imm = 0x404
jmp 0x2d7d5
movl $0x405, 0x18(%rsp)      # imm = 0x405
jmp 0x2d7d5
movl $0x406, 0x18(%rsp)      # imm = 0x406
jmp 0x2d7d5
movl $0x428, 0x18(%rsp)      # imm = 0x428
jmp 0x2d7d5
movl $0x429, 0x18(%rsp)      # imm = 0x429
jmp 0x2d7d5
movl $0x42a, 0x18(%rsp)      # imm = 0x42A
jmp 0x2d7d5
movl $0x42b, 0x18(%rsp)      # imm = 0x42B
jmp 0x2d7d5
movl $0x42c, 0x18(%rsp)      # imm = 0x42C
jmp 0x2d7d5
movl $0x42d, 0x18(%rsp)      # imm = 0x42D
jmp 0x2d7d5
movl $0x42e, 0x18(%rsp)      # imm = 0x42E
jmp 0x2d7d5
movl $0x42f, 0x18(%rsp)      # imm = 0x42F
jmp 0x2d7d5
movl $0x430, 0x18(%rsp)      # imm = 0x430
jmp 0x2d7d5
movl $0x431, 0x18(%rsp)      # imm = 0x431
jmp 0x2d7d5
movl $0x432, 0x18(%rsp)      # imm = 0x432
jmp 0x2d7d5
movl $0x433, 0x18(%rsp)      # imm = 0x433
movq 0x2a4cd4(%rip), %rdi    # 0x2d24b0
movl 0x30(%rsp), %esi
movl 0x2c(%rsp), %edx
movl 0x18(%rsp), %ecx
movl 0x24(%rsp), %r8d
movl 0x20(%rsp), %r9d
movl 0x1c(%rsp), %r10d
movq (%rdi), %rax
movl %r10d, (%rsp)
callq *0x40(%rax)
cmpl $0x0, %eax
je 0x2d80b
callq 0x22cf90
addq $0x38, %rsp
retq