]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/less/ttyin.c
Optionally bind ktls threads to NUMA domains
[FreeBSD/FreeBSD.git] / contrib / less / ttyin.c
1 /*
2  * Copyright (C) 1984-2020  Mark Nudelman
3  *
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.
6  *
7  * For more information, see the README file.
8  */
9
10
11 /*
12  * Routines dealing with getting input from the keyboard (i.e. from the user).
13  */
14
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 extern int sigs;
32 extern int utf_mode;
33 extern int wheel_lines;
34
35 /*
36  * Open keyboard for input.
37  */
38         public void
39 open_getchr(VOID_PARAM)
40 {
41 #if MSDOS_COMPILER==WIN32C
42         /* Need this to let child processes inherit our console handle */
43         SECURITY_ATTRIBUTES sa;
44         memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
45         sa.nLength = sizeof(SECURITY_ATTRIBUTES);
46         sa.bInheritHandle = TRUE;
47         tty = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
48                         FILE_SHARE_READ, &sa, 
49                         OPEN_EXISTING, 0L, NULL);
50         GetConsoleMode(tty, &console_mode);
51         /* Make sure we get Ctrl+C events. */
52         SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
53 #else
54 #if MSDOS_COMPILER
55         extern int fd0;
56         /*
57          * Open a new handle to CON: in binary mode 
58          * for unbuffered keyboard read.
59          */
60          fd0 = dup(0);
61          close(0);
62          tty = open("CON", OPEN_READ);
63 #if MSDOS_COMPILER==DJGPPC
64         /*
65          * Setting stdin to binary causes Ctrl-C to not
66          * raise SIGINT.  We must undo that side-effect.
67          */
68         (void) __djgpp_set_ctrl_c(1);
69 #endif
70 #else
71         /*
72          * Try /dev/tty.
73          * If that doesn't work, use file descriptor 2,
74          * which in Unix is usually attached to the screen,
75          * but also usually lets you read from the keyboard.
76          */
77 #if OS2
78         /* The __open() system call translates "/dev/tty" to "con". */
79         tty = __open("/dev/tty", OPEN_READ);
80 #else
81         tty = open("/dev/tty", OPEN_READ);
82 #endif
83         if (tty < 0)
84                 tty = 2;
85 #endif
86 #endif
87 }
88
89 /*
90  * Close the keyboard.
91  */
92         public void
93 close_getchr(VOID_PARAM)
94 {
95 #if MSDOS_COMPILER==WIN32C
96         SetConsoleMode(tty, console_mode);
97         CloseHandle(tty);
98 #endif
99 }
100
101 #if MSDOS_COMPILER==WIN32C
102 /*
103  * Close the pipe, restoring the keyboard (CMD resets it, losing the mouse).
104  */
105         int
106 pclose(f)
107         FILE *f;
108 {
109         int result;
110
111         result = _pclose(f);
112         SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
113         return result;
114 }
115 #endif
116
117 /*
118  * Get the number of lines to scroll when mouse wheel is moved.
119  */
120         public int
121 default_wheel_lines(VOID_PARAM)
122 {
123         int lines = 1;
124 #if MSDOS_COMPILER==WIN32C
125         if (SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0))
126         {
127                 if (lines == WHEEL_PAGESCROLL)
128                         lines = 3;
129         }
130 #endif
131         return lines;
132 }
133
134 /*
135  * Get a character from the keyboard.
136  */
137         public int
138 getchr(VOID_PARAM)
139 {
140         char c;
141         int result;
142
143         do
144         {
145 #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
146                 /*
147                  * In raw read, we don't see ^C so look here for it.
148                  */
149                 flush();
150 #if MSDOS_COMPILER==WIN32C
151                 if (ABORT_SIGS())
152                         return (READ_INTR);
153                 c = WIN32getch();
154 #else
155                 c = getch();
156 #endif
157                 result = 1;
158                 if (c == '\003')
159                         return (READ_INTR);
160 #else
161                 {
162                         unsigned char uc;
163                         result = iread(tty, &uc, sizeof(char));
164                         c = (char) uc;
165                 }
166                 if (result == READ_INTR)
167                         return (READ_INTR);
168                 if (result < 0)
169                 {
170                         /*
171                          * Don't call error() here,
172                          * because error calls getchr!
173                          */
174                         quit(QUIT_ERROR);
175                 }
176 #endif
177 #if 0 /* allow entering arbitrary hex chars for testing */
178                 /* ctrl-A followed by two hex chars makes a byte */
179         {
180                 static int hex_in = 0;
181                 static int hex_value = 0;
182                 if (c == CONTROL('A'))
183                 {
184                         hex_in = 2;
185                         result = 0;
186                         continue;
187                 }
188                 if (hex_in > 0)
189                 {
190                         int v;
191                         if (c >= '0' && c <= '9')
192                                 v = c - '0';
193                         else if (c >= 'a' && c <= 'f')
194                                 v = c - 'a' + 10;
195                         else if (c >= 'A' && c <= 'F')
196                                 v = c - 'A' + 10;
197                         else
198                                 v = 0;
199                         hex_value = (hex_value << 4) | v;
200                         if (--hex_in > 0)
201                         {
202                                 result = 0;
203                                 continue;
204                         }
205                         c = hex_value;
206                 }
207         }
208 #endif
209                 /*
210                  * Various parts of the program cannot handle
211                  * an input character of '\0'.
212                  * If a '\0' was actually typed, convert it to '\340' here.
213                  */
214                 if (c == '\0')
215                         c = '\340';
216         } while (result != 1);
217
218         return (c & 0xFF);
219 }