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