1ea316270f
compiler-time type checking, and also causes problems for targets where multiple incompatible calling conventions may be selected based on argument types. This change switches less(1) to ANSI prototypes. While there, we also remove use of "register", and attempt to use "const" a bit better now that the compiler can check argument types. Reviewed by: cem, emaste MFC after: 3 weeks Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D10152
178 lines
3.4 KiB
C
178 lines
3.4 KiB
C
/*
|
|
* Copyright (C) 1984-2015 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, 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(void)
|
|
{
|
|
#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(void)
|
|
{
|
|
#if MSDOS_COMPILER==WIN32C
|
|
SetConsoleMode((HANDLE)tty, console_mode);
|
|
CloseHandle((HANDLE)tty);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Get a character from the keyboard.
|
|
*/
|
|
public int
|
|
getchr(void)
|
|
{
|
|
char c;
|
|
int result;
|
|
|
|
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 */
|
|
{
|
|
int hex_in = 0;
|
|
int hex_value = 0;
|
|
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);
|
|
}
|