1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-27 08:00:11 +00:00
freebsd/contrib/less/ttyin.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

252 lines
4.7 KiB
C
Raw Normal View History

2012-07-23 21:31:53 +00:00
/*
2023-05-01 08:22:19 +00:00
* Copyright (C) 1984-2023 Mark Nudelman
2012-07-23 21:31:53 +00:00
*
* 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"
2002-01-07 20:29:38 +00:00
#if OS2
#include "cmd.h"
#include "pckeys.h"
#endif
#if MSDOS_COMPILER==WIN32C
2019-06-29 04:39:01 +00:00
#define WIN32_LEAN_AND_MEAN
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x400
#endif
2019-06-29 04:39:01 +00:00
#include <windows.h>
2020-10-24 05:25:54 +00:00
public DWORD console_mode;
2019-06-29 04:39:01 +00:00
public HANDLE tty;
#else
2004-04-17 07:16:34 +00:00
public int tty;
2019-06-29 04:39:01 +00:00
#endif
2021-04-19 01:15:19 +00:00
#if LESSTEST
public char *ttyin_name = NULL;
#endif /*LESSTEST*/
extern int sigs;
2006-08-20 15:49:51 +00:00
extern int utf_mode;
2019-06-29 04:39:01 +00:00
extern int wheel_lines;
2021-04-19 01:15:19 +00:00
#if !MSDOS_COMPILER
2023-05-01 08:22:19 +00:00
static int open_tty_device(constant char* dev)
2021-04-19 01:15:19 +00:00
{
2022-09-05 23:57:47 +00:00
#if OS2
/* The __open() system call translates "/dev/tty" to "con". */
return __open(dev, OPEN_READ);
#else
return open(dev, OPEN_READ);
2021-04-19 01:15:19 +00:00
#endif
2022-09-05 23:57:47 +00:00
}
/*
* Open the tty device.
* Try ttyname(), then try /dev/tty, then use file descriptor 2.
* In Unix, file descriptor 2 is usually attached to the screen,
* but also usually lets you read from the keyboard.
*/
2023-05-01 08:22:19 +00:00
public int open_tty(void)
2022-09-05 23:57:47 +00:00
{
int fd = -1;
2021-04-19 01:15:19 +00:00
#if LESSTEST
if (ttyin_name != NULL)
2022-09-05 23:57:47 +00:00
fd = open_tty_device(ttyin_name);
2021-04-19 01:15:19 +00:00
#endif /*LESSTEST*/
2022-09-05 23:57:47 +00:00
#if HAVE_TTYNAME
if (fd < 0)
{
constant char *dev = ttyname(2);
if (dev != NULL)
fd = open_tty_device(dev);
}
#endif
if (fd < 0)
fd = open_tty_device("/dev/tty");
if (fd < 0)
fd = 2;
return fd;
2021-04-19 01:15:19 +00:00
}
#endif /* MSDOS_COMPILER */
/*
* Open keyboard for input.
*/
2023-05-01 08:22:19 +00:00
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;
2019-06-29 04:39:01 +00:00
tty = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, &sa,
OPEN_EXISTING, 0L, NULL);
2019-06-29 04:39:01 +00:00
GetConsoleMode(tty, &console_mode);
/* Make sure we get Ctrl+C events. */
2019-06-29 04:39:01 +00:00
SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
#else
2002-01-07 20:29:38 +00:00
#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
2022-09-05 23:57:47 +00:00
tty = open_tty();
#endif
#endif
}
/*
* Close the keyboard.
*/
2023-05-01 08:22:19 +00:00
public void close_getchr(void)
2019-06-29 04:39:01 +00:00
{
#if MSDOS_COMPILER==WIN32C
SetConsoleMode(tty, console_mode);
CloseHandle(tty);
#endif
}
#if MSDOS_COMPILER==WIN32C
/*
* Close the pipe, restoring the keyboard (CMD resets it, losing the mouse).
*/
2023-05-01 08:22:19 +00:00
public int pclose(FILE *f)
2019-06-29 04:39:01 +00:00
{
int result;
result = _pclose(f);
SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
return result;
}
#endif
/*
* Get the number of lines to scroll when mouse wheel is moved.
*/
2023-05-01 08:22:19 +00:00
public int default_wheel_lines(void)
{
2019-06-29 04:39:01 +00:00
int lines = 1;
#if MSDOS_COMPILER==WIN32C
2019-06-29 04:39:01 +00:00
if (SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0))
{
if (lines == WHEEL_PAGESCROLL)
lines = 3;
}
#endif
2019-06-29 04:39:01 +00:00
return lines;
}
/*
* Get a character from the keyboard.
*/
2023-05-01 08:22:19 +00:00
public int getchr(void)
{
char c;
int result;
do
{
2021-04-19 01:15:19 +00:00
flush();
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
* In raw read, we don't see ^C so look here for it.
*/
#if MSDOS_COMPILER==WIN32C
if (ABORT_SIGS())
return (READ_INTR);
2019-06-29 04:39:01 +00:00
c = WIN32getch();
#else
c = getch();
#endif
result = 1;
if (c == '\003')
return (READ_INTR);
#else
2017-04-29 06:30:21 +00:00
{
unsigned char uc;
result = iread(tty, &uc, sizeof(char));
c = (char) uc;
}
if (result == READ_INTR)
return (READ_INTR);
if (result < 0)
{
/*
* Don't call error() here,
* because error calls getchr!
*/
quit(QUIT_ERROR);
}
2006-08-20 15:49:51 +00:00
#endif
2023-05-01 08:22:19 +00:00
#if LESSTEST
if (c == LESS_DUMP_CHAR)
{
dump_screen();
result = 0;
continue;
}
#endif
2006-08-20 15:49:51 +00:00
#if 0 /* allow entering arbitrary hex chars for testing */
/* ctrl-A followed by two hex chars makes a byte */
2007-06-04 01:42:54 +00:00
{
2017-04-25 03:42:16 +00:00
static int hex_in = 0;
static int hex_value = 0;
2006-08-20 15:49:51 +00:00
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
2019-06-29 04:39:01 +00:00
v = 0;
2006-08-20 15:49:51 +00:00
hex_value = (hex_value << 4) | v;
if (--hex_in > 0)
{
result = 0;
continue;
}
c = hex_value;
}
2007-06-04 01:42:54 +00:00
}
#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);
2006-08-20 15:49:51 +00:00
return (c & 0xFF);
}