Logo Search packages:      
Sourcecode: less version File versions  Download package

ttyin.c

/*
 * Copyright (C) 1984-2004  Mark Nudelman
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Less License, as specified in the README file.
 *
 * For more information about less, or for information on how to 
 * contact the author, see the README file.
 */


/*
 * Routines dealing with getting input from the keyboard (i.e. from the user).
 */

#include "less.h"
#if OS2
#include "cmd.h"
#include "pckeys.h"
#endif
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
extern char WIN32getch();
static DWORD console_mode;
#endif

public int tty;
extern int sigs;
extern int utf_mode;

/*
 * Open keyboard for input.
 */
      public void
open_getchr()
{
#if MSDOS_COMPILER==WIN32C
      /* Need this to let child processes inherit our console handle */
      SECURITY_ATTRIBUTES sa;
      memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
      sa.nLength = sizeof(SECURITY_ATTRIBUTES);
      sa.bInheritHandle = TRUE;
      tty = (int) CreateFile("CONIN$", GENERIC_READ,
                  FILE_SHARE_READ, &sa, 
                  OPEN_EXISTING, 0L, NULL);
      GetConsoleMode((HANDLE)tty, &console_mode);
      /* Make sure we get Ctrl+C events. */
      SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT);
#else
#if MSDOS_COMPILER
      extern int fd0;
      /*
       * Open a new handle to CON: in binary mode 
       * for unbuffered keyboard read.
       */
       fd0 = dup(0);
       close(0);
       tty = open("CON", OPEN_READ);
#if MSDOS_COMPILER==DJGPPC
      /*
       * Setting stdin to binary causes Ctrl-C to not
       * raise SIGINT.  We must undo that side-effect.
       */
      (void) __djgpp_set_ctrl_c(1);
#endif
#else
      /*
       * Try /dev/tty.
       * If that doesn't work, use file descriptor 2,
       * which in Unix is usually attached to the screen,
       * but also usually lets you read from the keyboard.
       */
#if OS2
      /* The __open() system call translates "/dev/tty" to "con". */
      tty = __open("/dev/tty", OPEN_READ);
#else
      tty = open("/dev/tty", OPEN_READ);
#endif
      if (tty < 0)
            tty = 2;
#endif
#endif
}

/*
 * Close the keyboard.
 */
      public void
close_getchr()
{
#if MSDOS_COMPILER==WIN32C
      SetConsoleMode((HANDLE)tty, console_mode);
      CloseHandle((HANDLE)tty);
#endif
}

/*
 * Get a character from the keyboard.
 */
      public int
getchr()
{
      char c;
      int result;
      int hex_in = 0;
      int hex_value = 0;

      do
      {
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
            /*
             * In raw read, we don't see ^C so look here for it.
             */
            flush();
#if MSDOS_COMPILER==WIN32C
            if (ABORT_SIGS())
                  return (READ_INTR);
            c = WIN32getch(tty);
#else
            c = getch();
#endif
            result = 1;
            if (c == '\003')
                  return (READ_INTR);
#else
            result = iread(tty, &c, sizeof(char));
            if (result == READ_INTR)
                  return (READ_INTR);
            if (result < 0)
            {
                  /*
                   * Don't call error() here,
                   * because error calls getchr!
                   */
                  quit(QUIT_ERROR);
            }
#endif
#if 0 /* allow entering arbitrary hex chars for testing */
            /* ctrl-A followed by two hex chars makes a byte */
            if (c == CONTROL('A'))
            {
                  hex_in = 2;
                  result = 0;
                  continue;
            }
            if (hex_in > 0)
            {
                  int v;
                  if (c >= '0' && c <= '9')
                        v = c - '0';
                  else if (c >= 'a' && c <= 'f')
                        v = c - 'a' + 10;
                  else if (c >= 'A' && c <= 'F')
                        v = c - 'A' + 10;
                  else
                        hex_in = 0;
                  hex_value = (hex_value << 4) | v;
                  if (--hex_in > 0)
                  {
                        result = 0;
                        continue;
                  }
                  c = hex_value;
            }
#endif
            /*
             * Various parts of the program cannot handle
             * an input character of '\0'.
             * If a '\0' was actually typed, convert it to '\340' here.
             */
            if (c == '\0')
                  c = '\340';
      } while (result != 1);

      return (c & 0xFF);
}

Generated by  Doxygen 1.6.0   Back to index