
#ifdef __cplusplus
extern "C" {
#endif

#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <proto/exec.h>
#include <proto/dos.h>

#ifdef __cplusplus
}
#endif

extern LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);

/* Agetch() reads one raw keystroke -- uses sendpkt() */

static int char_waiting = 0;

static int Agetch(void)
{
  UBYTE c = (UBYTE)char_waiting;
  char_waiting = 0;

  if ( c == 0)
    {
    LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
    struct Task *me = FindTask(NULL);
    struct CommandLineInterface *cli = BADDR(((struct Process *) me)->pr_CLI);
    BPTR fh = cli->cli_StandardInput;   /* this is immune to < redirection */
    void *conp = ((struct FileHandle *) BADDR(fh))->fh_Type;
    char longspace[8];
    long *flag = (long *) ((ULONG) &longspace[4] & ~3); /* LONGWORD ALIGNED! */
  
    *flag = 1;
    sendpkt(conp, ACTION_SCREEN_MODE, flag, 1);         /* assume success */
    Read(fh, &c, 1);
    *flag = 0;
    sendpkt(conp, ACTION_SCREEN_MODE, flag, 1);
    if (c == 3)                                         /* ^C in input */
      Signal(me, SIGBREAKF_CTRL_C);
    }
  return c;
}

static int Akbhit(void)
{
  if (char_waiting == 0)
    char_waiting = Agetch();
  return (char_waiting != 0);
}

/* =================================================================== */

#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
}
#endif


int kbhit(void) /* check if char waiting on stdin, do not block */
{
  if (isatty(fileno(stdin))
    return Akbhit();
  return (!feof(stdin));
}  


int getch(void) /* get a char from stdin, do not echo, block if none waiting */
{
  int c = 0;
  while ((SetSignal(0L,0L) & SIGBREAKF_CTRL_C) == 0)
    {
    if (kbhit())
      {
      if (isatty(fileno(stdin)))
        return Agetch();
      return getc(stdin);
      }
    Delay((250000*TICKS_PER_SECOND)/1000000);
    }
  return 3;
}

