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