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