Metropoli BBS
VIEWER: slw32tty.c MODE: TEXT (ASCII)
/* Copyright (c) 1992, 1995 John E. Davis
 * All rights reserved.
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Perl Artistic License.
 */

#include "config.h"
#include "sl-feat.h"

#include <stdio.h>

#include <windows.h>
#include <winbase.h>

#include "slang.h"
#include "_slang.h"

#ifdef __cplusplus
# define _DOTS_ ...
#else
# define _DOTS_ void
#endif

/*----------------------------------------------------------------------*\
 *  Function:	static void set_ctrl_break (int state);
 *
 * set the control-break setting
\*----------------------------------------------------------------------*/
static void set_ctrl_break (int state)
{
}

/*----------------------------------------------------------------------*\
 *  Function:	int SLang_init_tty (int abort_char, int no_flow_control,
 *				    int opost);
 *
 * initialize the keyboard interface and attempt to set-up the interrupt 9
 * handler if ABORT_CHAR is non-zero.
 * NO_FLOW_CONTROL and OPOST are only for compatiblity and are ignored.
\*----------------------------------------------------------------------*/

HANDLE hStdout, hStdin;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

int SLang_init_tty (int abort_char, int no_flow_control, int opost)
{
   SMALL_RECT windowRect;
   COORD newPosition;
   DWORD flags;

  /* first off, create a new console so the old one can be restored on exit */
   HANDLE console = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
					      FILE_SHARE_READ |FILE_SHARE_WRITE,
					      0,
					      CONSOLE_TEXTMODE_BUFFER,
					      0);
   if (SetConsoleActiveScreenBuffer(console) == FALSE)
     {
	return -1;
     }

  /* start things off at the origin */
   newPosition.X = 0;
   newPosition.Y = 0;

  /* still read in characters from stdin, but output to the new console */
  /* this way, on program exit, the original screen is restored */
   hStdin = GetStdHandle(STD_INPUT_HANDLE);
/*   hStdout = GetStdHandle(STD_OUTPUT_HANDLE); */

/*   hStdin = console; */
   hStdout = console;

   if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE)
     {
	return -1; /* failure */
     }

   if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
     {
	return -1; /* failure */
     }
   // if

   windowRect.Left = 0;
   windowRect.Top = 0;
   windowRect.Right = csbiInfo.dwSize.X - 1;
   windowRect.Bottom = csbiInfo.dwSize.Y - 1;
   if (!SetConsoleWindowInfo(hStdout, TRUE, &windowRect))
     {
	return -1;
     }

   if (SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT) == FALSE)
     {
	return -1; /* failure */
     }

   if (SetConsoleMode(hStdout, 0) == FALSE)
     {
	return -1; /* failure */
     }

   if (GetConsoleMode(hStdin, &flags))
     {
	if (flags & ENABLE_PROCESSED_INPUT)
	  {
	     return -1;
	  }
     }

   (void) SetConsoleCursorPosition(hStdout, newPosition);

  /* success */
   return 0;
}
/* SLang_init_tty */

/*----------------------------------------------------------------------*\
 *  Function:	void SLang_reset_tty (void);
 *
 * reset the tty before exiting
\*----------------------------------------------------------------------*/
void SLang_reset_tty (void)
{
   set_ctrl_break (1);
}


/* Return TRUE if the Shift, Ctrl, Alt, Caps Lock, or Num Lock key was pressed.
 */
static int is_shift_key (INPUT_RECORD *pRecord)
{
   unsigned k = (pRecord->Event.KeyEvent.uChar.AsciiChar |
		 (pRecord->Event.KeyEvent.wVirtualScanCode << 8));
   return ((k == 0x1d00)
	   || (k == 0x2a00)
	   || (k == 0x3600)
	   || (k == 0x3800)
	   || (k == 0x3a00)
	   || (k == 0x4500));
}


/*----------------------------------------------------------------------*\
 *  Function:	int _SLsys_input_pending (int tsecs);
 *
 *  sleep for *tsecs tenths of a sec waiting for input
\*----------------------------------------------------------------------*/
int _SLsys_input_pending (int tsecs)
{
   INPUT_RECORD record;
   DWORD events_read;

   while (1)
     {
	if (0 == PeekConsoleInput(hStdin, &record, 1, &events_read))
	  /* function failed */
	  return 0;
	  
	if (events_read != 1)
	  return 0;

	if ((record.EventType == KEY_EVENT)
	    && record.Event.KeyEvent.bKeyDown
	    && (0 == is_shift_key (&record)))
	  /* ok, there is a keypress here */
	  return 1;
	     
	/* something else is here, so read it and try again */
	(void) ReadConsoleInput(hStdin, &record, 1, &events_read);
     }
}

/*----------------------------------------------------------------------*\
 *  Function:	unsigned int _SLsys_getkey (void);
 *
 * wait for and get the next available keystroke.
 * Also re-maps some useful keystrokes.
 *
 *	Backspace (^H)	=>	Del (127)
 *	Ctrl-Space	=>	^@	(^@^3 - a pc NUL char)
 *	extended keys are prefixed by a null character
\*----------------------------------------------------------------------*/
unsigned int _SLsys_getkey (void)
{
   unsigned int ch;
   DWORD events_read;
   INPUT_RECORD record;

   while (1)
     {
	if (!ReadConsoleInput(hStdin, &record, 1, &events_read))
	  return 0;

	if ((record.EventType == KEY_EVENT)
	    && record.Event.KeyEvent.bKeyDown
	    && !is_shift_key (&record))
	  {
#ifdef CYGWIN32
	     ch = record.Event.KeyEvent.AsciiChar;
#else
	     ch = record.Event.KeyEvent.uChar.AsciiChar;
#endif
	     if (ch == 0 || ch == 0xE0)
	       {
		  SLang_ungetkey(record.Event.KeyEvent.wVirtualScanCode);
	       }
	     return ch;
	  }
     }
/*   ReadFile(hStdin, &key, 1, &events_read, NULL); */

/*   return key; */
}

/*----------------------------------------------------------------------*\
 *  Function:	int SLang_set_abort_signal (void (*handler)(int));
\*----------------------------------------------------------------------*/
int SLang_set_abort_signal (void (*handler)(int))
{
   return 0;
}
[ RETURN TO DIRECTORY ]