86
|
1 /*
|
|
2 mdport.c - Machine Dependent Code
|
|
3
|
|
4 Copyright (C) 2005-2008 Nicholas J. Kisseberth
|
|
5 All rights reserved.
|
|
6
|
|
7 Redistribution and use in source and binary forms, with or without
|
|
8 modification, are permitted provided that the following conditions
|
|
9 are met:
|
|
10 1. Redistributions of source code must retain the above copyright
|
|
11 notice, this list of conditions and the following disclaimer.
|
|
12 2. Redistributions in binary form must reproduce the above copyright
|
|
13 notice, this list of conditions and the following disclaimer in the
|
|
14 documentation and/or other materials provided with the distribution.
|
|
15 3. Neither the name(s) of the author(s) nor the names of other contributors
|
|
16 may be used to endorse or promote products derived from this software
|
|
17 without specific prior written permission.
|
|
18
|
|
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
|
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
22 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
|
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
25 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
27 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
28 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
29 SUCH DAMAGE.
|
|
30 */
|
|
31
|
|
32 /* This is a temporary stub version of rogue5's mdport.c. It is only to make
|
|
33 * md_readchar() available until srogue is ported to autoconf. Then the
|
|
34 * whole file should work.
|
|
35 */
|
|
36
|
|
37 #include <stdlib.h>
|
|
38 #include <string.h>
|
|
39
|
|
40 #if defined(_WIN32)
|
|
41 #include <Windows.h>
|
|
42 #include <Lmcons.h>
|
|
43 #include <io.h>
|
|
44 #include <conio.h>
|
|
45 #pragma warning( disable: 4201 )
|
|
46 #include <shlobj.h>
|
|
47 #pragma warning( default: 4201 )
|
|
48 #include <Shlwapi.h>
|
|
49 #undef MOUSE_MOVED
|
|
50 #endif
|
|
51
|
|
52 #include <sys/types.h>
|
|
53
|
|
54 #include <curses.h> /* AIX requires curses.h be included before term.h */
|
|
55
|
|
56 #include <ctype.h>
|
|
57 #include "rogue.h"
|
|
58
|
|
59 /*
|
|
60 Cursor/Keypad Support
|
|
61
|
|
62 Sadly Cursor/Keypad support is less straightforward than it should be.
|
|
63
|
|
64 The various terminal emulators/consoles choose to differentiate the
|
|
65 cursor and keypad keys (with modifiers) in different ways (if at all!).
|
|
66 Furthermore they use different code set sequences for each key only
|
|
67 a subset of which the various curses libraries recognize. Partly due
|
|
68 to incomplete termcap/terminfo entries and partly due to inherent
|
|
69 limitations of those terminal capability databases.
|
|
70
|
|
71 I give curses first crack at decoding the sequences. If it fails to decode
|
|
72 it we check for common ESC-prefixed sequences.
|
|
73
|
|
74 All cursor/keypad results are translated into standard rogue movement
|
|
75 commands.
|
|
76
|
|
77 Unmodified keys are translated to walk commands: hjklyubn
|
|
78 Modified (shift,control,alt) are translated to run commands: HJKLYUBN
|
|
79
|
|
80 Console and supported (differentiated) keys
|
|
81 Interix: Cursor Keys, Keypad, Ctl-Keypad
|
|
82 Cygwin: Cursor Keys, Keypad, Alt-Cursor Keys
|
|
83 MSYS: Cursor Keys, Keypad, Ctl-Cursor Keys, Ctl-Keypad
|
|
84 Win32: Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
|
|
85 DJGPP: Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
|
|
86
|
|
87 Interix Console (raw, ncurses)
|
|
88 ==============================
|
|
89 normal shift ctrl alt
|
|
90 ESC [D, ESC F^, ESC [D, ESC [D /# Left #/
|
|
91 ESC [C, ESC F$, ESC [C, ESC [C /# Right #/
|
|
92 ESC [A, ESC F-, local win, ESC [A /# Up #/
|
|
93 ESC [B, ESC F+, local win, ESC [B /# Down #/
|
|
94 ESC [H, ESC [H, ESC [H, ESC [H /# Home #/
|
|
95 ESC [S, local win, ESC [S, ESC [S /# Page Up #/
|
|
96 ESC [T, local win, ESC [T, ESC [T /# Page Down #/
|
|
97 ESC [U, ESC [U, ESC [U, ESC [U /# End #/
|
|
98 ESC [D, ESC F^, ESC [D, O /# Keypad Left #/
|
|
99 ESC [C, ESC F$, ESC [C, O /# Keypad Right #/
|
|
100 ESC [A, ESC [A, ESC [-1, O /# Keypad Up #/
|
|
101 ESC [B, ESC [B, ESC [-2, O /# Keypad Down #/
|
|
102 ESC [H, ESC [H, ESC [-263, O /# Keypad Home #/
|
|
103 ESC [S, ESC [S, ESC [-19, O /# Keypad PgUp #/
|
|
104 ESC [T, ESC [T, ESC [-20, O /# Keypad PgDn #/
|
|
105 ESC [U, ESC [U, ESC [-21, O /# Keypad End #/
|
|
106 nothing, nothing, nothing, O /# Kaypad 5 #/
|
|
107
|
|
108 Interix Console (term=interix, ncurses)
|
|
109 ==============================
|
|
110 KEY_LEFT, ESC F^, KEY_LEFT, KEY_LEFT /# Left #/
|
|
111 KEY_RIGHT, ESC F$, KEY_RIGHT, KEY_RIGHT /# Right #/
|
|
112 KEY_UP, 0x146, local win, KEY_UP /# Up #/
|
|
113 KEY_DOWN, 0x145, local win, KEY_DOWN /# Down #/
|
|
114 ESC [H, ESC [H, ESC [H, ESC [H /# Home #/
|
|
115 KEY_PPAGE, local win, KEY_PPAGE, KEY_PPAGE /# Page Up #/
|
|
116 KEY_NPAGE, local win, KEY_NPAGE, KEY_NPAGE /# Page Down #/
|
|
117 KEY_LL, KEY_LL, KEY_LL, KEY_LL /# End #/
|
|
118 KEY_LEFT, ESC F^, ESC [-4, O /# Keypad Left #/
|
|
119 KEY_RIGHT, ESC F$, ESC [-3, O /# Keypad Right #/
|
|
120 KEY_UP, KEY_UP, ESC [-1, O /# Keypad Up #/
|
|
121 KEY_DOWN, KEY_DOWN, ESC [-2, O /# Keypad Down #/
|
|
122 ESC [H, ESC [H, ESC [-263, O /# Keypad Home #/
|
|
123 KEY_PPAGE, KEY_PPAGE, ESC [-19, O /# Keypad PgUp #/
|
|
124 KEY_NPAGE, KEY_NPAGE, ESC [-20, O /# Keypad PgDn #/
|
|
125 KEY_LL, KEY_LL, ESC [-21, O /# Keypad End #/
|
|
126 nothing, nothing, nothing, O /# Keypad 5 #/
|
|
127
|
|
128 Cygwin Console (raw, ncurses)
|
|
129 ==============================
|
|
130 normal shift ctrl alt
|
|
131 ESC [D, ESC [D, ESC [D, ESC ESC [D /# Left #/
|
|
132 ESC [C, ESC [C, ESC [C, ESC ESC [C /# Rght #/
|
|
133 ESC [A, ESC [A, ESC [A, ESC ESC [A /# Up #/
|
|
134 ESC [B, ESC [B, ESC [B, ESC ESC [B /# Down #/
|
|
135 ESC [1~, ESC [1~, ESC [1~, ESC ESC [1~ /# Home #/
|
|
136 ESC [5~, ESC [5~, ESC [5~, ESC ESC [5~ /# Page Up #/
|
|
137 ESC [6~, ESC [6~, ESC [6~, ESC ESC [6~ /# Page Down #/
|
|
138 ESC [4~, ESC [4~, ESC [4~, ESC ESC [4~ /# End #/
|
|
139 ESC [D, ESC [D, ESC [D, ESC ESC [D,O /# Keypad Left #/
|
|
140 ESC [C, ESC [C, ESC [C, ESC ESC [C,O /# Keypad Right #/
|
|
141 ESC [A, ESC [A, ESC [A, ESC ESC [A,O /# Keypad Up #/
|
|
142 ESC [B, ESC [B, ESC [B, ESC ESC [B,O /# Keypad Down #/
|
|
143 ESC [1~, ESC [1~, ESC [1~, ESC ESC [1~,O /# Keypad Home #/
|
|
144 ESC [5~, ESC [5~, ESC [5~, ESC ESC [5~,O /# Keypad PgUp #/
|
|
145 ESC [6~, ESC [6~, ESC [6~, ESC ESC [6~,O /# Keypad PgDn #/
|
|
146 ESC [4~, ESC [4~, ESC [4~, ESC ESC [4~,O /# Keypad End #/
|
|
147 ESC [-71, nothing, nothing, O /# Keypad 5 #/
|
|
148
|
|
149 Cygwin Console (term=cygwin, ncurses)
|
|
150 ==============================
|
|
151 KEY_LEFT, KEY_LEFT, KEY_LEFT, ESC-260 /# Left #/
|
|
152 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, ESC-261 /# Rght #/
|
|
153 KEY_UP, KEY_UP, KEY_UP, ESC-259 /# Up #/
|
|
154 KEY_DOWN, KEY_DOWN, KEY_DOWN, ESC-258 /# Down #/
|
|
155 KEY_HOME, KEY_HOME, KEY_HOME, ESC-262 /# Home #/
|
|
156 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, ESC-339 /# Page Up #/
|
|
157 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, ESC-338 /# Page Down #/
|
|
158 KEY_END, KEY_END, KEY_END, ESC-360 /# End #/
|
|
159 KEY_LEFT, KEY_LEFT, KEY_LEFT, ESC-260,O /# Keypad Left #/
|
|
160 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, ESC-261,O /# Keypad Right #/
|
|
161 KEY_UP, KEY_UP, KEY_UP, ESC-259,O /# Keypad Up #/
|
|
162 KEY_DOWN, KEY_DOWN, KEY_DOWN, ESC-258,O /# Keypad Down #/
|
|
163 KEY_HOME, KEY_HOME, KEY_HOME, ESC-262,O /# Keypad Home #/
|
|
164 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, ESC-339,O /# Keypad PgUp #/
|
|
165 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, ESC-338,O /# Keypad PgDn #/
|
|
166 KEY_END, KEY_END, KEY_END, ESC-360,O /# Keypad End #/
|
|
167 ESC [G, nothing, nothing, O /# Keypad 5 #/
|
|
168
|
|
169 MSYS Console (raw, ncurses)
|
|
170 ==============================
|
|
171 normal shift ctrl alt
|
|
172 ESC OD, ESC [d, ESC Od nothing /# Left #/
|
|
173 ESC OE, ESC [e, ESC Oe, nothing /# Right #/
|
|
174 ESC OA, ESC [a, ESC Oa, nothing /# Up #/
|
|
175 ESC OB, ESC [b, ESC Ob, nothing /# Down #/
|
|
176 ESC [7~, ESC [7$, ESC [7^, nothing /# Home #/
|
|
177 ESC [5~, local window, ESC [5^, nothing /# Page Up #/
|
|
178 ESC [6~, local window, ESC [6^, nothing /# Page Down #/
|
|
179 ESC [8~, ESC [8$, ESC [8^, nothing /# End #/
|
|
180 ESC OD, ESC [d, ESC Od O /# Keypad Left #/
|
|
181 ESC OE, ESC [c, ESC Oc, O /# Keypad Right #/
|
|
182 ESC OA, ESC [a, ESC Oa, O /# Keypad Up #/
|
|
183 ESC OB, ESC [b, ESC Ob, O /# Keypad Down #/
|
|
184 ESC [7~, ESC [7$, ESC [7^, O /# Keypad Home #/
|
|
185 ESC [5~, local window, ESC [5^, O /# Keypad PgUp #/
|
|
186 ESC [6~, local window, ESC [6^, O /# Keypad PgDn #/
|
|
187 ESC [8~, ESC [8$, ESC [8^, O /# Keypad End #/
|
|
188 11, 11, 11, O /# Keypad 5 #/
|
|
189
|
|
190 MSYS Console (term=rxvt, ncurses)
|
|
191 ==============================
|
|
192 normal shift ctrl alt
|
|
193 KEY_LEFT, KEY_SLEFT, 514 nothing /# Left #/
|
|
194 KEY_RIGHT, KEY_SRIGHT, 516, nothing /# Right #/
|
|
195 KEY_UP, 518, 519, nothing /# Up #/
|
|
196 KEY_DOWN, 511, 512, nothing /# Down #/
|
|
197 KEY_HOME, KEY_SHOME, ESC [7^, nothing /# Home #/
|
|
198 KEY_PPAGE, local window, ESC [5^, nothing /# Page Up #/
|
|
199 KEY_NPAGE, local window, ESC [6^, nothing /# Page Down #/
|
|
200 KEY_END, KEY_SEND, KEY_EOL, nothing /# End #/
|
|
201 KEY_LEFT, KEY_SLEFT, 514 O /# Keypad Left #/
|
|
202 KEY_RIGHT, KEY_SRIGHT, 516, O /# Keypad Right #/
|
|
203 KEY_UP, 518, 519, O /# Keypad Up #/
|
|
204 KEY_DOWN, 511, 512, O /# Keypad Down #/
|
|
205 KEY_HOME, KEY_SHOME, ESC [7^, O /# Keypad Home #/
|
|
206 KEY_PPAGE, local window, ESC [5^, O /# Keypad PgUp #/
|
|
207 KEY_NPAGE, local window, ESC [6^, O /# Keypad PgDn #/
|
|
208 KEY_END, KEY_SEND, KEY_EOL, O /# Keypad End #/
|
|
209 11, 11, 11, O /# Keypad 5 #/
|
|
210
|
|
211 Win32 Console (raw, pdcurses)
|
|
212 DJGPP Console (raw, pdcurses)
|
|
213 ==============================
|
|
214 normal shift ctrl alt
|
|
215 260, 391, 443, 493 /# Left #/
|
|
216 261, 400, 444, 492 /# Right #/
|
|
217 259, 547, 480, 490 /# Up #/
|
|
218 258, 548, 481, 491 /# Down #/
|
|
219 262, 388, 447, 524 /# Home #/
|
|
220 339, 396, 445, 526 /# Page Up #/
|
|
221 338, 394, 446, 520 /# Page Down #/
|
|
222 358, 384, 448, 518 /# End #/
|
|
223 452, 52('4'), 511, 521 /# Keypad Left #/
|
|
224 454, 54('6'), 513, 523 /# Keypad Right #/
|
|
225 450, 56('8'), 515, 525 /# Keypad Up #/
|
|
226 456, 50('2'), 509, 519 /# Keypad Down #/
|
|
227 449, 55('7'), 514, 524 /# Keypad Home #/
|
|
228 451, 57('9'), 516, 526 /# Keypad PgUp #/
|
|
229 457, 51('3'), 510, 520 /# Keypad PgDn #/
|
|
230 455, 49('1'), 508, 518 /# Keypad End #/
|
|
231 453, 53('5'), 512, 522 /# Keypad 5 #/
|
|
232
|
|
233 Win32 Console (pdcurses, MSVC/MingW32)
|
|
234 DJGPP Console (pdcurses)
|
|
235 ==============================
|
|
236 normal shift ctrl alt
|
|
237 KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT /# Left #/
|
|
238 KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT /# Right #/
|
|
239 KEY_UP, KEY_SUP, CTL_UP, ALT_UP /# Up #/
|
|
240 KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN /# Down #/
|
|
241 KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME /# Home #/
|
|
242 KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP /# Page Up #/
|
|
243 KEY_NPAGE, KEY_SNEXTE, CTL_PGDN, ALT_PGDN /# Page Down #/
|
|
244 KEY_END, KEY_SEND, CTL_END, ALT_END /# End #/
|
|
245 KEY_B1, 52('4'), CTL_PAD4, ALT_PAD4 /# Keypad Left #/
|
|
246 KEY_B3, 54('6'), CTL_PAD6, ALT_PAD6 /# Keypad Right #/
|
|
247 KEY_A2, 56('8'), CTL_PAD8, ALT_PAD8 /# Keypad Up #/
|
|
248 KEY_C2, 50('2'), CTL_PAD2, ALT_PAD2 /# Keypad Down #/
|
|
249 KEY_A1, 55('7'), CTL_PAD7, ALT_PAD7 /# Keypad Home #/
|
|
250 KEY_A3, 57('9'), CTL_PAD9, ALT_PAD9 /# Keypad PgUp #/
|
|
251 KEY_C3, 51('3'), CTL_PAD3, ALT_PAD3 /# Keypad PgDn #/
|
|
252 KEY_C1, 49('1'), CTL_PAD1, ALT_PAD1 /# Keypad End #/
|
|
253 KEY_B2, 53('5'), CTL_PAD5, ALT_PAD5 /# Keypad 5 #/
|
|
254
|
|
255 Windows Telnet (raw)
|
|
256 ==============================
|
|
257 normal shift ctrl alt
|
|
258 ESC [D, ESC [D, ESC [D, ESC [D /# Left #/
|
|
259 ESC [C, ESC [C, ESC [C, ESC [C /# Right #/
|
|
260 ESC [A, ESC [A, ESC [A, ESC [A /# Up #/
|
|
261 ESC [B, ESC [B, ESC [B, ESC [B /# Down #/
|
|
262 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Home #/
|
|
263 ESC [5~, ESC [5~, ESC [5~, ESC [5~ /# Page Up #/
|
|
264 ESC [6~, ESC [6~, ESC [6~, ESC [6~ /# Page Down #/
|
|
265 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# End #/
|
|
266 ESC [D, ESC [D, ESC [D, ESC [D /# Keypad Left #/
|
|
267 ESC [C, ESC [C, ESC [C, ESC [C /# Keypad Right #/
|
|
268 ESC [A, ESC [A, ESC [A, ESC [A /# Keypad Up #/
|
|
269 ESC [B, ESC [B, ESC [B, ESC [B /# Keypad Down #/
|
|
270 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Keypad Home #/
|
|
271 ESC [5~, ESC [5~, ESC [5~, ESC [5~ /# Keypad PgUp #/
|
|
272 ESC [6~, ESC [6~, ESC [6~, ESC [6~ /# Keypad PgDn #/
|
|
273 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# Keypad End #/
|
|
274 nothing, nothing, nothing, nothing /# Keypad 5 #/
|
|
275
|
|
276 Windows Telnet (term=xterm)
|
|
277 ==============================
|
|
278 normal shift ctrl alt
|
|
279 KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT /# Left #/
|
|
280 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, KEY_RIGHT /# Right #/
|
|
281 KEY_UP, KEY_UP, KEY_UP, KEY_UP /# Up #/
|
|
282 KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN /# Down #/
|
|
283 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Home #/
|
|
284 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, KEY_PPAGE /# Page Up #/
|
|
285 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, KEY_NPAGE /# Page Down #/
|
|
286 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# End #/
|
|
287 KEY_LEFT, KEY_LEFT, KEY_LEFT, O /# Keypad Left #/
|
|
288 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, O /# Keypad Right #/
|
|
289 KEY_UP, KEY_UP, KEY_UP, O /# Keypad Up #/
|
|
290 KEY_DOWN, KEY_DOWN, KEY_DOWN, O /# Keypad Down #/
|
|
291 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Keypad Home #/
|
|
292 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, KEY_PPAGE /# Keypad PgUp #/
|
|
293 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, KEY_NPAGE /# Keypad PgDn #/
|
|
294 ESC [4~, ESC [4~, ESC [4~, O /# Keypad End #/
|
|
295 ESC [-71, nothing, nothing, O /# Keypad 5 #/
|
|
296
|
|
297 PuTTY
|
|
298 ==============================
|
|
299 normal shift ctrl alt
|
|
300 ESC [D, ESC [D, ESC OD, ESC [D /# Left #/
|
|
301 ESC [C, ESC [C, ESC OC, ESC [C /# Right #/
|
|
302 ESC [A, ESC [A, ESC OA, ESC [A /# Up #/
|
|
303 ESC [B, ESC [B, ESC OB, ESC [B /# Down #/
|
|
304 ESC [1~, ESC [1~, local win, ESC [1~ /# Home #/
|
|
305 ESC [5~, local win, local win, ESC [5~ /# Page Up #/
|
|
306 ESC [6~, local win, local win, ESC [6~ /# Page Down #/
|
|
307 ESC [4~, ESC [4~, local win, ESC [4~ /# End #/
|
|
308 ESC [D, ESC [D, ESC [D, O /# Keypad Left #/
|
|
309 ESC [C, ESC [C, ESC [C, O /# Keypad Right #/
|
|
310 ESC [A, ESC [A, ESC [A, O /# Keypad Up #/
|
|
311 ESC [B, ESC [B, ESC [B, O /# Keypad Down #/
|
|
312 ESC [1~, ESC [1~, ESC [1~, O /# Keypad Home #/
|
|
313 ESC [5~, ESC [5~, ESC [5~, O /# Keypad PgUp #/
|
|
314 ESC [6~, ESC [6~, ESC [6~, O /# Keypad PgDn #/
|
|
315 ESC [4~, ESC [4~, ESC [4~, O /# Keypad End #/
|
|
316 nothing, nothing, nothing, O /# Keypad 5 #/
|
|
317
|
|
318 PuTTY
|
|
319 ==============================
|
|
320 normal shift ctrl alt
|
|
321 KEY_LEFT, KEY_LEFT, ESC OD, ESC KEY_LEFT /# Left #/
|
|
322 KEY_RIGHT KEY_RIGHT, ESC OC, ESC KEY_RIGHT /# Right #/
|
|
323 KEY_UP, KEY_UP, ESC OA, ESC KEY_UP /# Up #/
|
|
324 KEY_DOWN, KEY_DOWN, ESC OB, ESC KEY_DOWN /# Down #/
|
|
325 ESC [1~, ESC [1~, local win, ESC ESC [1~ /# Home #/
|
|
326 KEY_PPAGE local win, local win, ESC KEY_PPAGE /# Page Up #/
|
|
327 KEY_NPAGE local win, local win, ESC KEY_NPAGE /# Page Down #/
|
|
328 ESC [4~, ESC [4~, local win, ESC ESC [4~ /# End #/
|
|
329 ESC Ot, ESC Ot, ESC Ot, O /# Keypad Left #/
|
|
330 ESC Ov, ESC Ov, ESC Ov, O /# Keypad Right #/
|
|
331 ESC Ox, ESC Ox, ESC Ox, O /# Keypad Up #/
|
|
332 ESC Or, ESC Or, ESC Or, O /# Keypad Down #/
|
|
333 ESC Ow, ESC Ow, ESC Ow, O /# Keypad Home #/
|
|
334 ESC Oy, ESC Oy, ESC Oy, O /# Keypad PgUp #/
|
|
335 ESC Os, ESC Os, ESC Os, O /# Keypad PgDn #/
|
|
336 ESC Oq, ESC Oq, ESC Oq, O /# Keypad End #/
|
|
337 ESC Ou, ESC Ou, ESC Ou, O /# Keypad 5 #/
|
|
338 */
|
|
339
|
|
340 #define M_NORMAL 0
|
|
341 #define M_ESC 1
|
|
342 #define M_KEYPAD 2
|
|
343 #define M_TRAIL 3
|
|
344
|
|
345 int undo[5];
|
|
346 int uindex = -1;
|
|
347
|
|
348 int
|
|
349 reread()
|
|
350 {
|
|
351 int redo;
|
|
352
|
|
353 if (uindex < 0)
|
|
354 return 0;
|
|
355
|
|
356 redo = undo[0];
|
|
357 undo[0] = undo[1];
|
|
358 undo[1] = undo[2];
|
|
359 undo[2] = undo[3];
|
|
360 undo[3] = undo[4];
|
|
361 uindex--;
|
|
362 return redo;
|
|
363 }
|
|
364
|
|
365 void
|
|
366 unread(int c)
|
|
367 {
|
|
368 if (uindex >= 4)
|
|
369 abort();
|
|
370
|
|
371 undo[++uindex] = c;
|
|
372 }
|
|
373
|
|
374 int
|
|
375 md_readchar(WINDOW *win)
|
|
376 {
|
|
377 int ch = 0;
|
|
378 int lastch = 0;
|
|
379 int mode = M_NORMAL;
|
|
380 int mode2 = M_NORMAL;
|
|
381 int nodelayf = 0;
|
|
382 int count = 0;
|
|
383
|
|
384 for(;;)
|
|
385 {
|
|
386 if (mode == M_NORMAL && uindex >= 0)
|
|
387 {
|
|
388 ch = reread();
|
|
389 break;
|
|
390 }
|
|
391
|
|
392 ch = wgetch(win);
|
|
393
|
|
394 if (ch == ERR) /* timed out or error */
|
|
395 {
|
|
396 if (nodelayf) /* likely timed out, switch to */
|
|
397 { /* normal mode and block on */
|
|
398 mode = M_NORMAL; /* next read */
|
|
399 nodelayf = 0;
|
|
400 nodelay(win,0);
|
|
401 }
|
|
402 else if (count > 10) /* after 10 errors assume */
|
|
403 auto_save(0); /* input stream is broken and */
|
|
404 else /* auto save and exit */
|
|
405 count++;
|
|
406
|
|
407 continue;
|
|
408 }
|
|
409
|
|
410 count = 0; /* reset input error count */
|
|
411
|
|
412 if (mode == M_TRAIL)
|
|
413 {
|
|
414 if (ch == '^') /* msys console : 7,5,6,8: modified*/
|
|
415 ch = CTRL( toupper(lastch) );
|
|
416 else if (ch == '~') /* cygwin console: 1,5,6,4: normal */
|
|
417 ch = tolower(lastch); /* windows telnet: 1,5,6,4: normal */
|
|
418 /* msys console : 7,5,6,8: normal */
|
|
419 else if (mode2 == M_ESC) /* cygwin console: 1,5,6,4: modified*/
|
|
420 ch = CTRL( toupper(ch) );
|
|
421 else
|
|
422 {
|
|
423 mode = M_NORMAL;
|
|
424 unread(ch);
|
|
425 continue;
|
|
426 }
|
|
427
|
|
428 break;
|
|
429 }
|
|
430
|
|
431 if (mode == M_ESC)
|
|
432 {
|
|
433 if (ch == 27)
|
|
434 {
|
|
435 mode2 = M_ESC;
|
|
436 unread(ch);
|
|
437 continue;
|
|
438 }
|
|
439
|
|
440 if ((ch == 'F') || (ch == 'O') || (ch == '['))
|
|
441 {
|
|
442 mode = M_KEYPAD;
|
|
443 unread(ch);
|
|
444 continue;
|
|
445 }
|
|
446
|
|
447
|
|
448 switch(ch)
|
|
449 {
|
|
450 /* Cygwin Console */
|
|
451 /* PuTTY */
|
|
452 case KEY_LEFT : ch = CTRL('H'); break;
|
|
453 case KEY_RIGHT: ch = CTRL('L'); break;
|
|
454 case KEY_UP : ch = CTRL('K'); break;
|
|
455 case KEY_DOWN : ch = CTRL('J'); break;
|
|
456 case KEY_HOME : ch = CTRL('Y'); break;
|
|
457 case KEY_PPAGE: ch = CTRL('U'); break;
|
|
458 case KEY_NPAGE: ch = CTRL('N'); break;
|
|
459 case KEY_END : ch = CTRL('B'); break;
|
|
460
|
|
461 default: mode = M_NORMAL;
|
|
462 mode2 = M_NORMAL;
|
|
463 unread(ch);
|
|
464 continue;
|
|
465 }
|
|
466
|
|
467 break;
|
|
468 }
|
|
469
|
|
470 if (mode == M_KEYPAD)
|
|
471 {
|
|
472 switch(ch)
|
|
473 {
|
|
474 /* ESC F - Interix Console codes */
|
|
475 case '^': ch = CTRL('H'); break; /* Shift-Left */
|
|
476 case '$': ch = CTRL('L'); break; /* Shift-Right */
|
|
477
|
|
478 /* ESC [ - Interix Console codes */
|
|
479 case 'H': ch = 'y'; break; /* Home */
|
|
480 case 1: ch = CTRL('K'); break; /* Ctl-Keypad Up */
|
|
481 case 2: ch = CTRL('J'); break; /* Ctl-Keypad Down */
|
|
482 case 3: ch = CTRL('L'); break; /* Ctl-Keypad Right */
|
|
483 case 4: ch = CTRL('H'); break; /* Ctl-Keypad Left */
|
|
484 case 263: ch = CTRL('Y'); break; /* Ctl-Keypad Home */
|
|
485 case 19: ch = CTRL('U'); break; /* Ctl-Keypad PgUp */
|
|
486 case 20: ch = CTRL('N'); break; /* Ctl-Keypad PgDn */
|
|
487 case 21: ch = CTRL('B'); break; /* Ctl-Keypad End */
|
|
488
|
|
489 /* ESC [ - Cygwin Console codes */
|
|
490 case 'G': ch = '.'; break; /* Keypad 5 */
|
|
491 case '7': lastch = 'Y'; mode=M_TRAIL; break; /* Ctl-Home */
|
|
492 case '5': lastch = 'U'; mode=M_TRAIL; break; /* Ctl-PgUp */
|
|
493 case '6': lastch = 'N'; mode=M_TRAIL; break; /* Ctl-PgDn */
|
|
494
|
|
495 /* ESC [ - Win32 Telnet, PuTTY */
|
|
496 case '1': lastch = 'y'; mode=M_TRAIL; break; /* Home */
|
|
497 case '4': lastch = 'b'; mode=M_TRAIL; break; /* End */
|
|
498
|
|
499 /* ESC [ - not understood by screen/tmux */
|
|
500 case 'E': ch = '.'; break; /* Keypad 5 */
|
|
501
|
|
502 /* ESC O - PuTTY */
|
|
503 case 'D': ch = CTRL('H'); break;
|
|
504 case 'C': ch = CTRL('L'); break;
|
|
505 case 'A': ch = CTRL('K'); break;
|
|
506 case 'B': ch = CTRL('J'); break;
|
|
507 case 't': ch = 'h'; break;
|
|
508 case 'v': ch = 'l'; break;
|
|
509 case 'x': ch = 'k'; break;
|
|
510 case 'r': ch = 'j'; break;
|
|
511 case 'w': ch = 'y'; break;
|
|
512 case 'y': ch = 'u'; break;
|
|
513 case 's': ch = 'n'; break;
|
|
514 case 'q': ch = 'b'; break;
|
|
515 case 'u': ch = '.'; break;
|
|
516 }
|
|
517
|
|
518 if (mode != M_KEYPAD)
|
|
519 {
|
|
520 unread(ch);
|
|
521 continue;
|
|
522 }
|
|
523 }
|
|
524
|
|
525 if (ch == 27)
|
|
526 {
|
|
527 nodelay(win,1);
|
|
528 mode = M_ESC;
|
|
529 nodelayf = 1;
|
|
530 unread(ch);
|
|
531 continue;
|
|
532 }
|
|
533
|
|
534 switch(ch)
|
|
535 {
|
|
536 case KEY_LEFT : ch = 'h'; break;
|
|
537 case KEY_DOWN : ch = 'j'; break;
|
|
538 case KEY_UP : ch = 'k'; break;
|
|
539 case KEY_RIGHT : ch = 'l'; break;
|
|
540 case KEY_HOME : ch = 'y'; break;
|
|
541 case KEY_PPAGE : ch = 'u'; break;
|
|
542 case KEY_END : ch = 'b'; break;
|
|
543 #ifdef KEY_LL
|
|
544 case KEY_LL : ch = 'b'; break;
|
|
545 #endif
|
|
546 case KEY_NPAGE : ch = 'n'; break;
|
|
547 case KEY_BEG : ch = '.'; break;
|
|
548
|
|
549 #ifdef KEY_B1
|
|
550 case KEY_B1 : ch = 'h'; break;
|
|
551 case KEY_C2 : ch = 'j'; break;
|
|
552 case KEY_A2 : ch = 'k'; break;
|
|
553 case KEY_B3 : ch = 'l'; break;
|
|
554 #endif
|
|
555 case KEY_A1 : ch = 'y'; break;
|
|
556 case KEY_A3 : ch = 'u'; break;
|
|
557 case KEY_C1 : ch = 'b'; break;
|
|
558 case KEY_C3 : ch = 'n'; break;
|
|
559 case KEY_B2 : ch = '.'; break;
|
|
560
|
|
561 #ifdef KEY_SLEFT
|
|
562 case KEY_SRIGHT : ch = CTRL('L'); break;
|
|
563 case KEY_SLEFT : ch = CTRL('H'); break;
|
|
564 #ifdef KEY_SUP
|
|
565 case KEY_SUP : ch = CTRL('K'); break;
|
|
566 case KEY_SDOWN : ch = CTRL('J'); break;
|
|
567 #endif
|
|
568 case KEY_SHOME : ch = CTRL('Y'); break;
|
|
569 case KEY_SPREVIOUS:ch = CTRL('U'); break;
|
|
570 case KEY_SEND : ch = CTRL('B'); break;
|
|
571 case KEY_SNEXT : ch = CTRL('N'); break;
|
|
572 #endif
|
|
573 case 0x146 : ch = CTRL('K'); break; /* Shift-Up */
|
|
574 case 0x145 : ch = CTRL('J'); break; /* Shift-Down */
|
|
575
|
|
576
|
|
577 #ifdef CTL_RIGHT
|
|
578 case CTL_RIGHT : ch = CTRL('L'); break;
|
|
579 case CTL_LEFT : ch = CTRL('H'); break;
|
|
580 case CTL_UP : ch = CTRL('K'); break;
|
|
581 case CTL_DOWN : ch = CTRL('J'); break;
|
|
582 case CTL_HOME : ch = CTRL('Y'); break;
|
|
583 case CTL_PGUP : ch = CTRL('U'); break;
|
|
584 case CTL_END : ch = CTRL('B'); break;
|
|
585 case CTL_PGDN : ch = CTRL('N'); break;
|
|
586 #endif
|
|
587 #ifdef KEY_EOL
|
|
588 case KEY_EOL : ch = CTRL('B'); break;
|
|
589 #endif
|
|
590
|
|
591 #ifndef CTL_PAD1
|
|
592 /* MSYS rxvt console */
|
|
593 case 511 : ch = CTRL('J'); break; /* Shift Dn */
|
|
594 case 512 : ch = CTRL('J'); break; /* Ctl Down */
|
|
595 case 514 : ch = CTRL('H'); break; /* Ctl Left */
|
|
596 case 516 : ch = CTRL('L'); break; /* Ctl Right*/
|
|
597 case 518 : ch = CTRL('K'); break; /* Shift Up */
|
|
598 case 519 : ch = CTRL('K'); break; /* Ctl Up */
|
|
599 #endif
|
|
600
|
|
601 #ifdef CTL_PAD1
|
|
602 case CTL_PAD1 : ch = CTRL('B'); break;
|
|
603 case CTL_PAD2 : ch = CTRL('J'); break;
|
|
604 case CTL_PAD3 : ch = CTRL('N'); break;
|
|
605 case CTL_PAD4 : ch = CTRL('H'); break;
|
|
606 case CTL_PAD5 : ch = '.'; break;
|
|
607 case CTL_PAD6 : ch = CTRL('L'); break;
|
|
608 case CTL_PAD7 : ch = CTRL('Y'); break;
|
|
609 case CTL_PAD8 : ch = CTRL('K'); break;
|
|
610 case CTL_PAD9 : ch = CTRL('U'); break;
|
|
611 #endif
|
|
612
|
|
613 #ifdef ALT_RIGHT
|
|
614 case ALT_RIGHT : ch = CTRL('L'); break;
|
|
615 case ALT_LEFT : ch = CTRL('H'); break;
|
|
616 case ALT_DOWN : ch = CTRL('J'); break;
|
|
617 case ALT_HOME : ch = CTRL('Y'); break;
|
|
618 case ALT_PGUP : ch = CTRL('U'); break;
|
|
619 case ALT_END : ch = CTRL('B'); break;
|
|
620 case ALT_PGDN : ch = CTRL('N'); break;
|
|
621 #endif
|
|
622
|
|
623 #ifdef ALT_PAD1
|
|
624 case ALT_PAD1 : ch = CTRL('B'); break;
|
|
625 case ALT_PAD2 : ch = CTRL('J'); break;
|
|
626 case ALT_PAD3 : ch = CTRL('N'); break;
|
|
627 case ALT_PAD4 : ch = CTRL('H'); break;
|
|
628 case ALT_PAD5 : ch = '.'; break;
|
|
629 case ALT_PAD6 : ch = CTRL('L'); break;
|
|
630 case ALT_PAD7 : ch = CTRL('Y'); break;
|
|
631 case ALT_PAD8 : ch = CTRL('K'); break;
|
|
632 case ALT_PAD9 : ch = CTRL('U'); break;
|
|
633 #endif
|
|
634 #ifdef KEY_BACKSPACE /* NCURSES in Keypad mode sends this for Ctrl-H */
|
98
|
635 case KEY_BACKSPACE: ch = erasechar(); break;
|
86
|
636 #endif
|
|
637 }
|
|
638
|
|
639 break;
|
|
640 }
|
|
641
|
|
642 if (nodelayf)
|
|
643 nodelay(win,0);
|
|
644
|
|
645 uindex = -1;
|
|
646
|
|
647 return(ch & 0x7F);
|
|
648 }
|