xref: /freebsd/contrib/less/ttyin.c (revision a5f0fb151d90effe79714de0fa059954725fe57f)
1a5f0fb15SPaul Saab /*
2a5f0fb15SPaul Saab  * Copyright (C) 1984-2000  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"
17a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
18a5f0fb15SPaul Saab #include "windows.h"
19a5f0fb15SPaul Saab extern char WIN32getch();
20a5f0fb15SPaul Saab static DWORD console_mode;
21a5f0fb15SPaul Saab #endif
22a5f0fb15SPaul Saab 
23a5f0fb15SPaul Saab static int tty;
24a5f0fb15SPaul Saab extern int sigs;
25a5f0fb15SPaul Saab 
26a5f0fb15SPaul Saab /*
27a5f0fb15SPaul Saab  * Open keyboard for input.
28a5f0fb15SPaul Saab  */
29a5f0fb15SPaul Saab 	public void
30a5f0fb15SPaul Saab open_getchr()
31a5f0fb15SPaul Saab {
32a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
33a5f0fb15SPaul Saab 	/* Need this to let child processes inherit our console handle */
34a5f0fb15SPaul Saab 	SECURITY_ATTRIBUTES sa;
35a5f0fb15SPaul Saab 	memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
36a5f0fb15SPaul Saab 	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
37a5f0fb15SPaul Saab 	sa.bInheritHandle = TRUE;
38a5f0fb15SPaul Saab 	tty = (int) CreateFile("CONIN$", GENERIC_READ,
39a5f0fb15SPaul Saab 			FILE_SHARE_READ, &sa,
40a5f0fb15SPaul Saab 			OPEN_EXISTING, 0L, NULL);
41a5f0fb15SPaul Saab 	GetConsoleMode((HANDLE)tty, &console_mode);
42a5f0fb15SPaul Saab 	/* Make sure we get Ctrl+C events. */
43a5f0fb15SPaul Saab 	SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT);
44a5f0fb15SPaul Saab #else
45a5f0fb15SPaul Saab #if MSDOS_COMPILER || OS2
46a5f0fb15SPaul Saab 	extern int fd0;
47a5f0fb15SPaul Saab 	/*
48a5f0fb15SPaul Saab 	 * Open a new handle to CON: in binary mode
49a5f0fb15SPaul Saab 	 * for unbuffered keyboard read.
50a5f0fb15SPaul Saab 	 */
51a5f0fb15SPaul Saab 	 fd0 = dup(0);
52a5f0fb15SPaul Saab 	 close(0);
53a5f0fb15SPaul Saab 	 tty = open("CON", OPEN_READ);
54a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC
55a5f0fb15SPaul Saab 	/*
56a5f0fb15SPaul Saab 	 * Setting stdin to binary causes Ctrl-C to not
57a5f0fb15SPaul Saab 	 * raise SIGINT.  We must undo that side-effect.
58a5f0fb15SPaul Saab 	 */
59a5f0fb15SPaul Saab 	(void) __djgpp_set_ctrl_c(1);
60a5f0fb15SPaul Saab #endif
61a5f0fb15SPaul Saab #else
62a5f0fb15SPaul Saab 	/*
63a5f0fb15SPaul Saab 	 * Try /dev/tty.
64a5f0fb15SPaul Saab 	 * If that doesn't work, use file descriptor 2,
65a5f0fb15SPaul Saab 	 * which in Unix is usually attached to the screen,
66a5f0fb15SPaul Saab 	 * but also usually lets you read from the keyboard.
67a5f0fb15SPaul Saab 	 */
68a5f0fb15SPaul Saab 	tty = open("/dev/tty", OPEN_READ);
69a5f0fb15SPaul Saab 	if (tty < 0)
70a5f0fb15SPaul Saab 		tty = 2;
71a5f0fb15SPaul Saab #endif
72a5f0fb15SPaul Saab #endif
73a5f0fb15SPaul Saab }
74a5f0fb15SPaul Saab 
75a5f0fb15SPaul Saab /*
76a5f0fb15SPaul Saab  * Close the keyboard.
77a5f0fb15SPaul Saab  */
78a5f0fb15SPaul Saab 	public void
79a5f0fb15SPaul Saab close_getchr()
80a5f0fb15SPaul Saab {
81a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
82a5f0fb15SPaul Saab 	SetConsoleMode((HANDLE)tty, console_mode);
83a5f0fb15SPaul Saab 	CloseHandle((HANDLE)tty);
84a5f0fb15SPaul Saab #endif
85a5f0fb15SPaul Saab }
86a5f0fb15SPaul Saab 
87a5f0fb15SPaul Saab /*
88a5f0fb15SPaul Saab  * Get a character from the keyboard.
89a5f0fb15SPaul Saab  */
90a5f0fb15SPaul Saab 	public int
91a5f0fb15SPaul Saab getchr()
92a5f0fb15SPaul Saab {
93a5f0fb15SPaul Saab 	char c;
94a5f0fb15SPaul Saab 	int result;
95a5f0fb15SPaul Saab 
96a5f0fb15SPaul Saab 	do
97a5f0fb15SPaul Saab 	{
98a5f0fb15SPaul Saab #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
99a5f0fb15SPaul Saab 		/*
100a5f0fb15SPaul Saab 		 * In raw read, we don't see ^C so look here for it.
101a5f0fb15SPaul Saab 		 */
102a5f0fb15SPaul Saab 		flush();
103a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C
104a5f0fb15SPaul Saab 		if (ABORT_SIGS())
105a5f0fb15SPaul Saab 			return (READ_INTR);
106a5f0fb15SPaul Saab 		c = WIN32getch(tty);
107a5f0fb15SPaul Saab #else
108a5f0fb15SPaul Saab 		c = getch();
109a5f0fb15SPaul Saab #endif
110a5f0fb15SPaul Saab 		result = 1;
111a5f0fb15SPaul Saab 		if (c == '\003')
112a5f0fb15SPaul Saab 			return (READ_INTR);
113a5f0fb15SPaul Saab #else
114a5f0fb15SPaul Saab #if OS2
115a5f0fb15SPaul Saab 	{
116a5f0fb15SPaul Saab 		static int scan = -1;
117a5f0fb15SPaul Saab 		flush();
118a5f0fb15SPaul Saab 		if (scan >= 0)
119a5f0fb15SPaul Saab 		{
120a5f0fb15SPaul Saab 			c = scan;
121a5f0fb15SPaul Saab 			scan = -1;
122a5f0fb15SPaul Saab 		} else
123a5f0fb15SPaul Saab 		{
124a5f0fb15SPaul Saab 			if ((c = _read_kbd(0, 1, 0)) == -1)
125a5f0fb15SPaul Saab 				return (READ_INTR);
126a5f0fb15SPaul Saab 			if (c == '\0')
127a5f0fb15SPaul Saab 			{
128a5f0fb15SPaul Saab 				/*
129a5f0fb15SPaul Saab 				 * Zero is usually followed by another byte,
130a5f0fb15SPaul Saab 				 * since certain keys send two bytes.
131a5f0fb15SPaul Saab 				 */
132a5f0fb15SPaul Saab 				scan = _read_kbd(0, 0, 0);
133a5f0fb15SPaul Saab 			}
134a5f0fb15SPaul Saab 		}
135a5f0fb15SPaul Saab 		result = 1;
136a5f0fb15SPaul Saab 	}
137a5f0fb15SPaul Saab #else
138a5f0fb15SPaul Saab 		result = iread(tty, &c, sizeof(char));
139a5f0fb15SPaul Saab 		if (result == READ_INTR)
140a5f0fb15SPaul Saab 			return (READ_INTR);
141a5f0fb15SPaul Saab 		if (result < 0)
142a5f0fb15SPaul Saab 		{
143a5f0fb15SPaul Saab 			/*
144a5f0fb15SPaul Saab 			 * Don't call error() here,
145a5f0fb15SPaul Saab 			 * because error calls getchr!
146a5f0fb15SPaul Saab 			 */
147a5f0fb15SPaul Saab 			quit(QUIT_ERROR);
148a5f0fb15SPaul Saab 		}
149a5f0fb15SPaul Saab #endif
150a5f0fb15SPaul Saab #endif
151a5f0fb15SPaul Saab 		/*
152a5f0fb15SPaul Saab 		 * Various parts of the program cannot handle
153a5f0fb15SPaul Saab 		 * an input character of '\0'.
154a5f0fb15SPaul Saab 		 * If a '\0' was actually typed, convert it to '\340' here.
155a5f0fb15SPaul Saab 		 */
156a5f0fb15SPaul Saab 		if (c == '\0')
157a5f0fb15SPaul Saab 			c = '\340';
158a5f0fb15SPaul Saab 	} while (result != 1);
159a5f0fb15SPaul Saab 
160a5f0fb15SPaul Saab 	return (c & 0377);
161a5f0fb15SPaul Saab }
162