/* pc.c - terminal I/O calls for GNU info for OS/2
   and other PC support functions
   Kai Uwe Rommel, 1990-1993
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/kbdscan.h>

#ifndef __RSXNT__
#define INCL_VIO
#include <os2emx.h>
static VIOCURSORINFO vci;
#endif

#include "pc.h"

#ifdef __RSXNT__

char buffer[4096];
int idx;

static void pc_flush(void)
{
  if (idx > 0)
    _rsxnt_write_with_ansi (buffer, idx);

  idx = 0;
}

void pc_putc (int c)
{
  if (idx == sizeof(buffer))
    pc_flush();

  buffer[idx++] = (char) c;
}

void pc_puts (char *s)
{
  while (*s)
    pc_putc(*s++);
}

void pc_putx (char *s, int x)
{
  for (; x; x--)
    pc_putc(*s++);
}

#endif

void pc_init (void)
{
#ifdef __RSXNT__
  extern void (*terminal_put_text_hook)();
  extern void (*terminal_write_chars_hook)();
  terminal_put_text_hook = pc_puts;
  terminal_write_chars_hook = pc_putx;
#else
  VIOCURSORINFO vcin;
  VioGetCurType(&vci, 0);
  vcin = vci;
  vcin.yStart = 0;
  vcin.cEnd = -100;
  VioSetCurType(&vcin, 0);
#endif
}

void pc_exit (void)
{
#ifndef __RSXNT__
  VioSetCurType(&vci, 0);
#endif
}

int pc_getc (int wait)
{
  int c;
  static int next;

  if (next)
    return c = next, next = 0, c;

#ifdef __RSXNT__
  if (wait)
    pc_flush();
#endif

  if ((c = _read_kbd (0, wait, 0)) == -1)
    return -1;

  if (c == 26)
    return next = 'V', 27;
  if (c != 0x00 && c != 0xE0)
    return c;

  if ((c = _read_kbd (0, wait, 0)) == -1)
    return -1;

  switch (c)
  {
  case K_F1:
    return 'H' - 64;

  case K_HOME:
    return 'A' - 64;
  case K_END:
    return 'E' - 64;

  case K_CTRL_HOME:
    return next = '<', 27;
  case K_CTRL_END:
    return next = '>', 27;

  case K_RIGHT:
    return 'F' - 64;
  case K_LEFT:
    return 'B' - 64;
  case K_DOWN:
    return 'N' - 64;
  case K_UP:
    return 'P' - 64;

  case K_CTRL_LEFT:
    return next = 'B', 27;
  case K_CTRL_RIGHT:
    return next = 'F', 27;

  case K_DEL:
  case K_PAGEUP:
    return next = 'V', 27;
  case K_PAGEDOWN:
    return 'V' - 64;

  default:
    return ' ';
  }
}
