rc.conf: Add and document the missing root_rw_mount=YES
[dragonfly.git] / contrib / less / ttyin.c
blob96486f53769b97bbe736c88456062bf5b611d5ef
1 /*
2 * Copyright (C) 1984-2023 Mark Nudelman
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Less License, as specified in the README file.
7 * For more information, see the README file.
8 */
12 * Routines dealing with getting input from the keyboard (i.e. from the user).
15 #include "less.h"
16 #if OS2
17 #include "cmd.h"
18 #include "pckeys.h"
19 #endif
20 #if MSDOS_COMPILER==WIN32C
21 #define WIN32_LEAN_AND_MEAN
22 #ifndef _WIN32_WINNT
23 #define _WIN32_WINNT 0x400
24 #endif
25 #include <windows.h>
26 public DWORD console_mode;
27 public HANDLE tty;
28 #else
29 public int tty;
30 #endif
31 #if LESSTEST
32 public char *ttyin_name = NULL;
33 #endif /*LESSTEST*/
34 extern int sigs;
35 extern int utf_mode;
36 extern int wheel_lines;
38 #if !MSDOS_COMPILER
39 static int open_tty_device(constant char* dev)
41 #if OS2
42 /* The __open() system call translates "/dev/tty" to "con". */
43 return __open(dev, OPEN_READ);
44 #else
45 return open(dev, OPEN_READ);
46 #endif
50 * Open the tty device.
51 * Try ttyname(), then try /dev/tty, then use file descriptor 2.
52 * In Unix, file descriptor 2 is usually attached to the screen,
53 * but also usually lets you read from the keyboard.
55 public int open_tty(void)
57 int fd = -1;
58 #if LESSTEST
59 if (ttyin_name != NULL)
60 fd = open_tty_device(ttyin_name);
61 #endif /*LESSTEST*/
62 #if HAVE_TTYNAME
63 if (fd < 0)
65 constant char *dev = ttyname(2);
66 if (dev != NULL)
67 fd = open_tty_device(dev);
69 #endif
70 if (fd < 0)
71 fd = open_tty_device("/dev/tty");
72 if (fd < 0)
73 fd = 2;
74 return fd;
76 #endif /* MSDOS_COMPILER */
79 * Open keyboard for input.
81 public void open_getchr(void)
83 #if MSDOS_COMPILER==WIN32C
84 /* Need this to let child processes inherit our console handle */
85 SECURITY_ATTRIBUTES sa;
86 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
87 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
88 sa.bInheritHandle = TRUE;
89 tty = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
90 FILE_SHARE_READ, &sa,
91 OPEN_EXISTING, 0L, NULL);
92 GetConsoleMode(tty, &console_mode);
93 /* Make sure we get Ctrl+C events. */
94 SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
95 #else
96 #if MSDOS_COMPILER
97 extern int fd0;
99 * Open a new handle to CON: in binary mode
100 * for unbuffered keyboard read.
102 fd0 = dup(0);
103 close(0);
104 tty = open("CON", OPEN_READ);
105 #if MSDOS_COMPILER==DJGPPC
107 * Setting stdin to binary causes Ctrl-C to not
108 * raise SIGINT. We must undo that side-effect.
110 (void) __djgpp_set_ctrl_c(1);
111 #endif
112 #else
113 tty = open_tty();
114 #endif
115 #endif
119 * Close the keyboard.
121 public void close_getchr(void)
123 #if MSDOS_COMPILER==WIN32C
124 SetConsoleMode(tty, console_mode);
125 CloseHandle(tty);
126 #endif
129 #if MSDOS_COMPILER==WIN32C
131 * Close the pipe, restoring the keyboard (CMD resets it, losing the mouse).
133 public int pclose(FILE *f)
135 int result;
137 result = _pclose(f);
138 SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
139 return result;
141 #endif
144 * Get the number of lines to scroll when mouse wheel is moved.
146 public int default_wheel_lines(void)
148 int lines = 1;
149 #if MSDOS_COMPILER==WIN32C
150 if (SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0))
152 if (lines == WHEEL_PAGESCROLL)
153 lines = 3;
155 #endif
156 return lines;
160 * Get a character from the keyboard.
162 public int getchr(void)
164 char c;
165 int result;
169 flush();
170 #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
172 * In raw read, we don't see ^C so look here for it.
174 #if MSDOS_COMPILER==WIN32C
175 if (ABORT_SIGS())
176 return (READ_INTR);
177 c = WIN32getch();
178 #else
179 c = getch();
180 #endif
181 result = 1;
182 if (c == '\003')
183 return (READ_INTR);
184 #else
186 unsigned char uc;
187 result = iread(tty, &uc, sizeof(char));
188 c = (char) uc;
190 if (result == READ_INTR)
191 return (READ_INTR);
192 if (result < 0)
195 * Don't call error() here,
196 * because error calls getchr!
198 quit(QUIT_ERROR);
200 #endif
201 #if LESSTEST
202 if (c == LESS_DUMP_CHAR)
204 dump_screen();
205 result = 0;
206 continue;
208 #endif
209 #if 0 /* allow entering arbitrary hex chars for testing */
210 /* ctrl-A followed by two hex chars makes a byte */
212 static int hex_in = 0;
213 static int hex_value = 0;
214 if (c == CONTROL('A'))
216 hex_in = 2;
217 result = 0;
218 continue;
220 if (hex_in > 0)
222 int v;
223 if (c >= '0' && c <= '9')
224 v = c - '0';
225 else if (c >= 'a' && c <= 'f')
226 v = c - 'a' + 10;
227 else if (c >= 'A' && c <= 'F')
228 v = c - 'A' + 10;
229 else
230 v = 0;
231 hex_value = (hex_value << 4) | v;
232 if (--hex_in > 0)
234 result = 0;
235 continue;
237 c = hex_value;
240 #endif
242 * Various parts of the program cannot handle
243 * an input character of '\0'.
244 * If a '\0' was actually typed, convert it to '\340' here.
246 if (c == '\0')
247 c = '\340';
248 } while (result != 1);
250 return (c & 0xFF);