xref: /freebsd/contrib/less/ttyin.c (revision 6dcb072b3021f88118ab758d851d01be270f36b2)
1a5f0fb15SPaul Saab /*
26dcb072bSXin LI  * Copyright (C) 1984-2004  Mark Nudelman
3a5f0fb15SPaul Saab  *
4a5f0fb15SPaul Saab  * You may distribute under the terms of either the GNU General Public
5a5f0fb15SPaul Saab  * License or the Less License, as specified in the README file.
6a5f0fb15SPaul Saab  *
7a5f0fb15SPaul Saab  * For more information about less, or for information on how to
8a5f0fb15SPaul Saab  * contact the author, see the README file.
9a5f0fb15SPaul Saab  */
10a5f0fb15SPaul Saab 
11a5f0fb15SPaul Saab 
12a5f0fb15SPaul Saab /*
13a5f0fb15SPaul Saab  * Routines dealing with getting input from the keyboard (i.e. from the user).
14a5f0fb15SPaul Saab  */
15a5f0fb15SPaul Saab 
16a5f0fb15SPaul Saab #include "less.h"
17c9346414SPaul Saab #if OS2
18c9346414SPaul Saab #include "cmd.h"
19c9346414SPaul Saab #include "pckeys.h"
20c9346414SPaul Saab #endif
21a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
22a5f0fb15SPaul Saab #include "windows.h"
23a5f0fb15SPaul Saab extern char WIN32getch();
24a5f0fb15SPaul Saab static DWORD console_mode;
25a5f0fb15SPaul Saab #endif
26a5f0fb15SPaul Saab 
27000ba3e8STim J. Robbins public int tty;
28a5f0fb15SPaul Saab extern int sigs;
296dcb072bSXin LI extern int utf_mode;
30a5f0fb15SPaul Saab 
31a5f0fb15SPaul Saab /*
32a5f0fb15SPaul Saab  * Open keyboard for input.
33a5f0fb15SPaul Saab  */
34a5f0fb15SPaul Saab 	public void
35a5f0fb15SPaul Saab open_getchr()
36a5f0fb15SPaul Saab {
37a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
38a5f0fb15SPaul Saab 	/* Need this to let child processes inherit our console handle */
39a5f0fb15SPaul Saab 	SECURITY_ATTRIBUTES sa;
40a5f0fb15SPaul Saab 	memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
41a5f0fb15SPaul Saab 	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
42a5f0fb15SPaul Saab 	sa.bInheritHandle = TRUE;
43a5f0fb15SPaul Saab 	tty = (int) CreateFile("CONIN$", GENERIC_READ,
44a5f0fb15SPaul Saab 			FILE_SHARE_READ, &sa,
45a5f0fb15SPaul Saab 			OPEN_EXISTING, 0L, NULL);
46a5f0fb15SPaul Saab 	GetConsoleMode((HANDLE)tty, &console_mode);
47a5f0fb15SPaul Saab 	/* Make sure we get Ctrl+C events. */
48a5f0fb15SPaul Saab 	SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT);
49a5f0fb15SPaul Saab #else
50c9346414SPaul Saab #if MSDOS_COMPILER
51a5f0fb15SPaul Saab 	extern int fd0;
52a5f0fb15SPaul Saab 	/*
53a5f0fb15SPaul Saab 	 * Open a new handle to CON: in binary mode
54a5f0fb15SPaul Saab 	 * for unbuffered keyboard read.
55a5f0fb15SPaul Saab 	 */
56a5f0fb15SPaul Saab 	 fd0 = dup(0);
57a5f0fb15SPaul Saab 	 close(0);
58a5f0fb15SPaul Saab 	 tty = open("CON", OPEN_READ);
59a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC
60a5f0fb15SPaul Saab 	/*
61a5f0fb15SPaul Saab 	 * Setting stdin to binary causes Ctrl-C to not
62a5f0fb15SPaul Saab 	 * raise SIGINT.  We must undo that side-effect.
63a5f0fb15SPaul Saab 	 */
64a5f0fb15SPaul Saab 	(void) __djgpp_set_ctrl_c(1);
65a5f0fb15SPaul Saab #endif
66a5f0fb15SPaul Saab #else
67a5f0fb15SPaul Saab 	/*
68a5f0fb15SPaul Saab 	 * Try /dev/tty.
69a5f0fb15SPaul Saab 	 * If that doesn't work, use file descriptor 2,
70a5f0fb15SPaul Saab 	 * which in Unix is usually attached to the screen,
71a5f0fb15SPaul Saab 	 * but also usually lets you read from the keyboard.
72a5f0fb15SPaul Saab 	 */
73c9346414SPaul Saab #if OS2
74c9346414SPaul Saab 	/* The __open() system call translates "/dev/tty" to "con". */
75c9346414SPaul Saab 	tty = __open("/dev/tty", OPEN_READ);
76c9346414SPaul Saab #else
77a5f0fb15SPaul Saab 	tty = open("/dev/tty", OPEN_READ);
78c9346414SPaul Saab #endif
79a5f0fb15SPaul Saab 	if (tty < 0)
80a5f0fb15SPaul Saab 		tty = 2;
81a5f0fb15SPaul Saab #endif
82a5f0fb15SPaul Saab #endif
83a5f0fb15SPaul Saab }
84a5f0fb15SPaul Saab 
85a5f0fb15SPaul Saab /*
86a5f0fb15SPaul Saab  * Close the keyboard.
87a5f0fb15SPaul Saab  */
88a5f0fb15SPaul Saab 	public void
89a5f0fb15SPaul Saab close_getchr()
90a5f0fb15SPaul Saab {
91a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
92a5f0fb15SPaul Saab 	SetConsoleMode((HANDLE)tty, console_mode);
93a5f0fb15SPaul Saab 	CloseHandle((HANDLE)tty);
94a5f0fb15SPaul Saab #endif
95a5f0fb15SPaul Saab }
96a5f0fb15SPaul Saab 
97a5f0fb15SPaul Saab /*
98a5f0fb15SPaul Saab  * Get a character from the keyboard.
99a5f0fb15SPaul Saab  */
100a5f0fb15SPaul Saab 	public int
101a5f0fb15SPaul Saab getchr()
102a5f0fb15SPaul Saab {
103a5f0fb15SPaul Saab 	char c;
104a5f0fb15SPaul Saab 	int result;
1056dcb072bSXin LI 	int hex_in = 0;
1066dcb072bSXin LI 	int hex_value = 0;
107a5f0fb15SPaul Saab 
108a5f0fb15SPaul Saab 	do
109a5f0fb15SPaul Saab 	{
110a5f0fb15SPaul Saab #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
111a5f0fb15SPaul Saab 		/*
112a5f0fb15SPaul Saab 		 * In raw read, we don't see ^C so look here for it.
113a5f0fb15SPaul Saab 		 */
114a5f0fb15SPaul Saab 		flush();
115a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
116a5f0fb15SPaul Saab 		if (ABORT_SIGS())
117a5f0fb15SPaul Saab 			return (READ_INTR);
118a5f0fb15SPaul Saab 		c = WIN32getch(tty);
119a5f0fb15SPaul Saab #else
120a5f0fb15SPaul Saab 		c = getch();
121a5f0fb15SPaul Saab #endif
122a5f0fb15SPaul Saab 		result = 1;
123a5f0fb15SPaul Saab 		if (c == '\003')
124a5f0fb15SPaul Saab 			return (READ_INTR);
125a5f0fb15SPaul Saab #else
126a5f0fb15SPaul Saab 		result = iread(tty, &c, sizeof(char));
127a5f0fb15SPaul Saab 		if (result == READ_INTR)
128a5f0fb15SPaul Saab 			return (READ_INTR);
129a5f0fb15SPaul Saab 		if (result < 0)
130a5f0fb15SPaul Saab 		{
131a5f0fb15SPaul Saab 			/*
132a5f0fb15SPaul Saab 			 * Don't call error() here,
133a5f0fb15SPaul Saab 			 * because error calls getchr!
134a5f0fb15SPaul Saab 			 */
135a5f0fb15SPaul Saab 			quit(QUIT_ERROR);
136a5f0fb15SPaul Saab 		}
137a5f0fb15SPaul Saab #endif
1386dcb072bSXin LI #if 0 /* allow entering arbitrary hex chars for testing */
1396dcb072bSXin LI 		/* ctrl-A followed by two hex chars makes a byte */
1406dcb072bSXin LI 		if (c == CONTROL('A'))
1416dcb072bSXin LI 		{
1426dcb072bSXin LI 			hex_in = 2;
1436dcb072bSXin LI 			result = 0;
1446dcb072bSXin LI 			continue;
1456dcb072bSXin LI 		}
1466dcb072bSXin LI 		if (hex_in > 0)
1476dcb072bSXin LI 		{
1486dcb072bSXin LI 			int v;
1496dcb072bSXin LI 			if (c >= '0' && c <= '9')
1506dcb072bSXin LI 				v = c - '0';
1516dcb072bSXin LI 			else if (c >= 'a' && c <= 'f')
1526dcb072bSXin LI 				v = c - 'a' + 10;
1536dcb072bSXin LI 			else if (c >= 'A' && c <= 'F')
1546dcb072bSXin LI 				v = c - 'A' + 10;
1556dcb072bSXin LI 			else
1566dcb072bSXin LI 				hex_in = 0;
1576dcb072bSXin LI 			hex_value = (hex_value << 4) | v;
1586dcb072bSXin LI 			if (--hex_in > 0)
1596dcb072bSXin LI 			{
1606dcb072bSXin LI 				result = 0;
1616dcb072bSXin LI 				continue;
1626dcb072bSXin LI 			}
1636dcb072bSXin LI 			c = hex_value;
1646dcb072bSXin LI 		}
1656dcb072bSXin LI #endif
166a5f0fb15SPaul Saab 		/*
167a5f0fb15SPaul Saab 		 * Various parts of the program cannot handle
168a5f0fb15SPaul Saab 		 * an input character of '\0'.
169a5f0fb15SPaul Saab 		 * If a '\0' was actually typed, convert it to '\340' here.
170a5f0fb15SPaul Saab 		 */
171a5f0fb15SPaul Saab 		if (c == '\0')
172a5f0fb15SPaul Saab 			c = '\340';
173a5f0fb15SPaul Saab 	} while (result != 1);
174a5f0fb15SPaul Saab 
1756dcb072bSXin LI 	return (c & 0xFF);
176a5f0fb15SPaul Saab }
177