/**   kbhit.c
 **
 **    This module is the equivalent of the Windows DOS "kbhit()" function
 ** for Linux.  This code is a byproduct of section "Detecting Keystrokes"
 ** from the "Beginning Linux Programming" manual by Neil Matthew & Richard 
 ** Stones.
 **
 **    This code does work with the SuSE 10.1 installation.
 **
 ** Original creation 12-11-08, by ted Schmitz
 **/
#if 0
#include <stdio.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <unistd.h>
#include <stdlib.h>
#else
#include <common.h>
#endif
/* storage for terminal settings */
static struct termios initial_settings, new_settings;
//static int peek_character = -1;

void init_keyboard();
void close_keyboard();
int kbhit();
int readch();

/*****************************************************************************
 **                            Check For Keystroke
 **
 **   This function checks to see if a key was pressed and returns the
 ** appropriate status to the calling code.
 **
 ** INPUT - Nothing
 **
 ** OUTPUT - Nothing
 **
 ** RETURN - A one will be returned to the calling code if a key
 **          was pressed.  Zero will be returned otherwise.
 **
 ****************************************************************************/
int kbhit()
{
  char ch;
  int nread;

  init_keyboard();

  new_settings.c_cc[VMIN] = 0; /* don't wait for a key if one is not avail */
  tcsetattr(0, TCSANOW, &new_settings);

  /* read last char in buffer & return number of new chars retrieved, if any */
  nread = read(0, &ch, 1);

  new_settings.c_cc[VMIN] = 1; /* go back to waiting for a key again */
  tcsetattr(0, TCSANOW, &new_settings);

  close_keyboard();

  /* if a new key was pressed save the char retrieved in module global var */
  if (nread == 1)
    {
    return 1;
    }

  return 0;
}

/*****************************************************************************
 **            Initialize Keyboard To Allow Checking For Keystrokes
 **
 ** INPUT - Nothing
 **
 ** OUTPUT - Keyboard driver will be modified to allow detection of any
 **          single keystroke.
 **
 ** RETURN - Nothing
 **
 ****************************************************************************/
void init_keyboard()
{
  tcgetattr(0,&initial_settings);
  new_settings = initial_settings;
  new_settings.c_lflag &= ~ICANON;
  new_settings.c_lflag &= ~ECHO;
  new_settings.c_lflag &= ~ISIG;
  new_settings.c_cc[VMIN] = 1;
  new_settings.c_cc[VTIME] = 0;
  tcsetattr(0, TCSANOW, &new_settings);

}

/*****************************************************************************
 **             Return Keyboard Back To Previous Configuration
 **
 **   This function returns the keyboard back to the configuration saved
 ** before we odified the driver to look for a single keystroke.
 **
 ** INPUT - Nothing
 **
 ** OUTPUT - Keyboard driver will be configured back to the state that was 
 **          saved before it was modified to detect keystrokes.
 **
 ** RETURN - Nothing
 **
 ****************************************************************************/
void close_keyboard()
{
  tcsetattr(0, TCSANOW, &initial_settings);
}

/*****************************************************************************
 **                  Read A Single Character From Keyboard
 **
 **   This function reads a single character from the keyboard input buffer.
 ** Some other function has determined that a key has been pressed before this
 ** function is called.
 **
 ** INPUT - Nothing
 **
 ** OUTPUT - Nothing
 **
 ** RETURN - The character read from the keyboard input buffer will be
 **          returned to the calling code.
 **
 **          NOTE: This function will wait for a key to be pressed if one is
 **                not available when this function is called.
 **
 ****************************************************************************/
int readch()
{
  char ch;

  read (0, &ch, 1);
  return ch;

}
