/*==============================================*/
/*  Keyboard.c - How to work with the keyboard  */
/*                                              */
/*  Author:  Bary W Pollack                     */
/*  Updated: Feb. 27, 2004                      */
/*==============================================*/

#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

GLsizei ww = 500, wh = 500;
GLfloat fVSize = 60;

/*==============================================*/

/* normal ASCII keyboard keys, including Esc, Del,... */
void keyboard (unsigned char key, int x, int y)     /* echo each key */
{
    char sMods [32];
    int  nMods = glutGetModifiers ();

    *sMods = '\0';
    if (nMods & GLUT_ACTIVE_SHIFT)
        strcat (sMods, " Shift");
    if (nMods & GLUT_ACTIVE_CTRL)
        strcat (sMods, " Ctrl");
    if (nMods & GLUT_ACTIVE_ALT)
        strcat (sMods, " Alt");
    printf ("key=%3u (%c)  x=%4d y=%4d  %s\n", key, key, x, y, sMods);
}

/*==============================================*/

/* the "special" keys:  F1, F2,..., Home, PgUp, and the cursor arrow keys */
void special (int key, int x, int y)     /* echo each key */
{
    char sMods [32];
    int  nMods = glutGetModifiers ();

    *sMods = '\0';
    if (nMods & GLUT_ACTIVE_SHIFT)
        strcat (sMods, " Shift");
    if (nMods & GLUT_ACTIVE_CTRL)
        strcat (sMods, " Ctrl");
    if (nMods & GLUT_ACTIVE_ALT)
        strcat (sMods, " Alt");
    switch (key)
    {
      case GLUT_KEY_F1:      strcat (sMods, " F1");      break;
      case GLUT_KEY_F2:      strcat (sMods, " F2");      break;
      case GLUT_KEY_F3:      strcat (sMods, " F3");      break;
      case GLUT_KEY_F12:     strcat (sMods, " F12");     break;
      case GLUT_KEY_LEFT:    strcat (sMods, " Left");    break;
      case GLUT_KEY_UP:      strcat (sMods, " Up");      break;
      case GLUT_KEY_RIGHT:   strcat (sMods, " Right");   break;
      case GLUT_KEY_DOWN:    strcat (sMods, " Down");    break;
      case GLUT_KEY_HOME:    strcat (sMods, " Home");    break;
      case GLUT_KEY_PAGE_UP: strcat (sMods, " PageUp");  break;
      case GLUT_KEY_INSERT:  strcat (sMods, " Insert");  break;
    }
    printf ("key=%3u (%c)  x=%4d y=%4d  %s\n", key, key, x, y, sMods);
}

/*==============================================*/

void display (void)         /* the display callback */
{
    int  d = 0;
    int  size = 2;

    glClear (GL_COLOR_BUFFER_BIT);

    /* draw a rectangle */
    glLineWidth (2.0);
    glBegin (GL_LINE_LOOP);
        glColor3f (0.0, 0.0, 0.0);
        glVertex2i (10+d, 10+d);  glVertex2i (50-d, 10+d);
        glVertex2i (50-d, 50-d);  glVertex2i (10+d, 50-d);
    glEnd ();

    /* put points at the 4 vertices */
    glPointSize (4.0);
    glBegin (GL_POINTS);
        glColor3f (0.0, 0.0, 1.0);
        glVertex2i (10+d, 10+d);  glVertex2i (50-d, 10+d);
        glVertex2i (50-d, 50-d);  glVertex2i (10+d, 50-d);
    glEnd ( );

    glFlush ();
}

/*==============================================*/

void myinit ()      /* standard initialization for OpenGL and GLUT */
{
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluOrtho2D (-0.02, fVSize + 0.02, -0.02, fVSize + 0.02);
    glMatrixMode (GL_MODELVIEW);
    glClearColor  (0.6, 7.0, 0.9, 1.0);
}

/*==============================================*/

int main (int argc, char **argv)
{
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB );
    glutInitWindowSize (wh, ww);
    glutInitWindowPosition (25, 50);
    glutCreateWindow ("Keyboard");

    glutKeyboardFunc (keyboard);
    glutSpecialFunc (special);
    glutDisplayFunc (display);

    myinit ();

    glutMainLoop ();

    return 0;
}

/*==============================================*/

