comparison arogue5/mdport.c @ 63:0ed67132cf10

Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 09 Aug 2012 22:58:48 +0000
parents
children c49f7927b0fa
comparison
equal deleted inserted replaced
62:0ef99244acb8 63:0ed67132cf10
1 /*
2 mdport.c - Machine Dependent Code for Porting Unix/Curses games
3
4 Copyright (C) 2005 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 #if defined(_WIN32)
33 #include <Windows.h>
34 #include <Lmcons.h>
35 #include <process.h>
36 #include <shlobj.h>
37 #include <sys/types.h>
38 #undef MOUSE_MOVED
39 #elif defined(__DJGPP__)
40 #include <process.h>
41 #else
42 #include <pwd.h>
43 #include <sys/utsname.h>
44 #include <unistd.h>
45 #endif
46
47 #include <stdlib.h>
48
49 #if defined(_WIN32) && !defined(__MINGW32__)
50 #define PATH_MAX MAX_PATH
51 #endif
52
53 #include <curses.h>
54
55 #if defined(__INTERIX) || defined(__MSYS__)
56 #include <term.h>
57 #else
58 #ifdef NCURSES_VERSION
59 #include <ncurses/term.h>
60 #endif
61 #endif
62
63 #include <stdio.h>
64 #include <fcntl.h>
65 #include <limits.h>
66 #include <sys/stat.h>
67 #include <signal.h>
68
69 #define MOD_MOVE(c) (toupper(c) )
70
71 void
72 md_init()
73 {
74 #ifdef __INTERIX
75 char *term;
76
77 term = getenv("TERM");
78
79 if (term == NULL)
80 setenv("TERM","interix");
81 #endif
82 #if defined(__DJGPP__) || defined(_WIN32)
83 _fmode = _O_BINARY;
84 #endif
85 #if defined(__CYGWIN__) || defined(__MSYS__)
86 ESCDELAY=250;
87 #endif
88 }
89
90 int
91 md_hasclreol()
92 {
93 #ifndef attron
94 return(!CE);
95 #elif !defined(__PDCURSES__)
96 return(clr_eol != NULL);
97 #else
98 return(TRUE);
99 #endif
100 }
101
102 #ifdef attron
103 # define _puts(s) tputs(s, 0, md_putchar);
104 # define SO enter_standout_mode
105 # define SE exit_standout_mode
106 #endif
107
108 int
109 md_putchar(int c)
110 {
111 putchar(c);
112 }
113
114 static int md_standout_mode = 0;
115
116 int
117 md_raw_standout()
118 {
119 #ifdef _WIN32
120 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
121 HANDLE hStdout;
122 int fgattr,bgattr;
123
124 if (md_standout_mode == 0)
125 {
126 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
127 GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
128 fgattr = (csbiInfo.wAttributes & 0xF);
129 bgattr = (csbiInfo.wAttributes & 0xF0);
130 SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
131 md_standout_mode = 1;
132 }
133 #elif !defined(__PDCURSES__)
134 _puts(SO);
135 fflush(stdout);
136 #endif
137 }
138
139 int
140 md_raw_standend()
141 {
142 #ifdef _WIN32
143 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
144 HANDLE hStdout;
145 int fgattr,bgattr;
146
147 if (md_standout_mode == 1)
148 {
149 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
150 GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
151 fgattr = (csbiInfo.wAttributes & 0xF);
152 bgattr = (csbiInfo.wAttributes & 0xF0);
153 SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
154 md_standout_mode = 0;
155 }
156 #elif !defined(__PDCURSES__)
157 _puts(SE);
158 fflush(stdout);
159 #endif
160 }
161
162 int
163 md_unlink_open_file(char *file, int inf)
164 {
165 #ifdef _WIN32
166 close(inf);
167 chmod(file, 0600);
168 return( _unlink(file) );
169 #else
170 return(unlink(file));
171 #endif
172 }
173
174 int
175 md_unlink(char *file)
176 {
177 #ifdef _WIN32
178 chmod(file, 0600);
179 return( _unlink(file) );
180 #else
181 return(unlink(file));
182 #endif
183 }
184
185 int
186 md_creat(char *file, int mode)
187 {
188 int fd;
189 #ifdef _WIN32
190 mode = _S_IREAD | _S_IWRITE;
191 #endif
192 fd = open(file,O_CREAT | O_EXCL | O_WRONLY, mode);
193
194 return(fd);
195 }
196
197
198 int
199 md_normaluser()
200 {
201 #ifndef _WIN32
202 setuid(getuid());
203 setgid(getgid());
204 #endif
205 }
206
207 int
208 md_getuid()
209 {
210 #ifndef _WIN32
211 return( getuid() );
212 #else
213 return(42);
214 #endif
215 }
216
217 char *
218 md_getusername()
219 {
220 static char login[80];
221 char *l = NULL;
222 #ifdef _WIN32
223 LPSTR mybuffer;
224 DWORD size = UNLEN + 1;
225 TCHAR buffer[UNLEN + 1];
226
227 mybuffer = buffer;
228 GetUserName(mybuffer,&size);
229 l = mybuffer;
230 #endif
231 #if !defined(_WIN32) && !defined(DJGPP)
232 struct passwd *pw;
233
234 pw = getpwuid(getuid());
235
236 l = pw->pw_name;
237 #endif
238
239 if ((l == NULL) || (*l == '\0'))
240 if ( (l = getenv("USERNAME")) == NULL )
241 if ( (l = getenv("LOGNAME")) == NULL )
242 if ( (l = getenv("USER")) == NULL )
243 l = "nobody";
244
245 strncpy(login,l,80);
246 login[79] = 0;
247
248 return(login);
249 }
250
251 char *
252 md_gethomedir()
253 {
254 static char homedir[PATH_MAX];
255 char *h = NULL;
256 size_t len;
257 #if defined(_WIN32)
258 TCHAR szPath[PATH_MAX];
259 #endif
260 #if defined(_WIN32) || defined(DJGPP)
261 char slash = '\\';
262 #else
263 char slash = '/';
264 struct passwd *pw;
265 pw = getpwuid(getuid());
266
267 h = pw->pw_dir;
268
269 if (strcmp(h,"/") == 0)
270 h = NULL;
271 #endif
272 homedir[0] = 0;
273 #ifdef _WIN32
274 if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath)))
275 h = szPath;
276 #endif
277
278 if ( (h == NULL) || (*h == '\0') )
279 if ( (h = getenv("HOME")) == NULL )
280 if ( (h = getenv("HOMEDRIVE")) == NULL)
281 h = "";
282 else
283 {
284 strncpy(homedir,h,PATH_MAX-1);
285 homedir[PATH_MAX-1] = 0;
286
287 if ( (h = getenv("HOMEPATH")) == NULL)
288 h = "";
289 }
290
291
292 len = strlen(homedir);
293 strncat(homedir,h,PATH_MAX-len-1);
294 len = strlen(homedir);
295
296 if ((len > 0) && (homedir[len-1] != slash)) {
297 homedir[len] = slash;
298 homedir[len+1] = 0;
299 }
300
301 return(homedir);
302 }
303
304 int
305 md_sleep(int s)
306 {
307 #ifdef _WIN32
308 _sleep(s);
309 #else
310 sleep(s);
311 #endif
312 }
313
314 char *
315 md_getshell()
316 {
317 static char shell[PATH_MAX];
318 char *s = NULL;
319 #ifdef _WIN32
320 char *def = "C:\\WINDOWS\\SYSTEM32\\CMD.EXE";
321 #elif defined(__DJGPP__)
322 char *def = "C:\\COMMAND.COM";
323 #else
324 char *def = "/bin/sh";
325 struct passwd *pw;
326 pw = getpwuid(getuid());
327 s = pw->pw_shell;
328 #endif
329 if ((s == NULL) || (*s == '\0'))
330 if ( (s = getenv("COMSPEC")) == NULL)
331 if ( (s = getenv("SHELL")) == NULL)
332 if ( (s = getenv("SystemRoot")) == NULL)
333 s = def;
334
335 strncpy(shell,s,PATH_MAX);
336 shell[PATH_MAX-1] = 0;
337
338 return(shell);
339 }
340
341 int
342 md_shellescape()
343 {
344 #if (!defined(_WIN32) && !defined(__DJGPP__))
345 int ret_status;
346 int pid;
347 void (*myquit)(int);
348 void (*myend)(int);
349 #endif
350 char *sh;
351
352 sh = md_getshell();
353
354 #if defined(_WIN32)
355 return((int)_spawnl(_P_WAIT,sh,"shell",NULL,0));
356 #elif defined(__DJGPP__)
357 return ( spawnl(P_WAIT,sh,"shell",NULL,0) );
358 #else
359 while((pid = fork()) < 0)
360 sleep(1);
361
362 if (pid == 0) /* Shell Process */
363 {
364 /*
365 * Set back to original user, just in case
366 */
367 setuid(getuid());
368 setgid(getgid());
369 execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", 0);
370 perror("No shelly");
371 _exit(-1);
372 }
373 else /* Application */
374 {
375 myend = signal(SIGINT, SIG_IGN);
376 #ifdef SIGQUIT
377 myquit = signal(SIGQUIT, SIG_IGN);
378 #endif
379 while (wait(&ret_status) != pid)
380 continue;
381
382 signal(SIGINT, myquit);
383 #ifdef SIGQUIT
384 signal(SIGQUIT, myend);
385 #endif
386 }
387
388 return(ret_status);
389 #endif
390 }
391
392 int
393 directory_exists(char *dirname)
394 {
395 struct stat sb;
396
397 if (stat(dirname, &sb) == 0) /* path exists */
398 return (sb.st_mode & S_IFDIR);
399
400 return(0);
401 }
402
403 char *
404 md_getroguedir()
405 {
406 static char path[1024];
407 char *end,*home;
408
409 if ( (home = getenv("ROGUEHOME")) != NULL)
410 {
411 if (*home)
412 {
413 strncpy(path, home, PATH_MAX - 20);
414
415 end = &path[strlen(path)-1];
416
417 while( (end >= path) && ((*end == '/') || (*end == '\\')))
418 *end-- = '\0';
419
420 if (directory_exists(path))
421 return(path);
422 }
423 }
424
425 if (directory_exists("/var/games/roguelike"))
426 return("/var/games/roguelike");
427 if (directory_exists("/var/lib/roguelike"))
428 return("/var/lib/roguelike");
429 if (directory_exists("/var/roguelike"))
430 return("/var/roguelike");
431 if (directory_exists("/usr/games/lib"))
432 return("/usr/games/lib");
433 if (directory_exists("/games/roguelik"))
434 return("/games/roguelik");
435
436 return("");
437 }
438
439 char *
440 md_getrealname(int uid)
441 {
442 static char uidstr[20];
443 #if !defined(_WIN32) && !defined(DJGPP)
444 struct passwd *pp;
445
446 if ((pp = getpwuid(uid)) == NULL)
447 {
448 sprintf(uidstr,"%d", uid);
449 return(uidstr);
450 }
451 else
452 return(pp->pw_name);
453 #else
454 sprintf(uidstr,"%d", uid);
455 return(uidstr);
456 #endif
457 }
458
459 extern char *xcrypt(char *key, char *salt);
460
461 char *
462 md_crypt(char *key, char *salt)
463 {
464 return( xcrypt(key,salt) );
465 }
466
467 char *
468 md_getpass(prompt)
469 char *prompt;
470 {
471 #ifdef _WIN32
472 static char password_buffer[9];
473 char *p = password_buffer;
474 int c, count = 0;
475 int max_length = 9;
476
477 fflush(stdout);
478 /* If we can't prompt, abort */
479 if (fputs(prompt, stderr) < 0)
480 {
481 *p = '\0';
482 return NULL;
483 }
484
485 for(;;)
486 {
487 /* Get a character with no echo */
488 c = _getch();
489
490 /* Exit on interrupt (^c or ^break) */
491 if (c == '\003' || c == 0x100)
492 exit(1);
493
494 /* Terminate on end of line or file (^j, ^m, ^d, ^z) */
495 if (c == '\r' || c == '\n' || c == '\004' || c == '\032')
496 break;
497
498 /* Back up on backspace */
499 if (c == '\b')
500 {
501 if (count)
502 count--;
503 else if (p > password_buffer)
504 p--;
505 continue;
506 }
507
508 /* Ignore DOS extended characters */
509 if ((c & 0xff) != c)
510 continue;
511
512 /* Add to password if it isn't full */
513 if (p < password_buffer + max_length - 1)
514 *p++ = c;
515 else
516 count++;
517 }
518 *p = '\0';
519
520 fputc('\n', stderr);
521
522 return password_buffer;
523 #else
524 return( (char *) getpass(prompt) );
525 #endif
526 }
527
528
529 int md_endian = 0x01020304;
530
531 unsigned long int
532 md_ntohl(unsigned long int x)
533 {
534 #ifdef _WIN32
535 if ( *((char *)&md_endian) == 0x01 )
536 return(x);
537 else
538 return( ((x & 0x000000ffU) << 24) |
539 ((x & 0x0000ff00U) << 8) |
540 ((x & 0x00ff0000U) >> 8) |
541 ((x & 0xff000000U) >> 24) );
542 #else
543 return( ntohl(x) );
544 #endif
545 }
546
547 unsigned long int
548 md_htonl(unsigned long int x)
549 {
550 #ifdef _WIN32
551 if ( *((char *)&md_endian) == 0x01 )
552 return(x);
553 else
554 return( ((x & 0x000000ffU) << 24) |
555 ((x & 0x0000ff00U) << 8) |
556 ((x & 0x00ff0000U) >> 8) |
557 ((x & 0xff000000U) >> 24) );
558 #else
559 return( htonl(x) );
560 #endif
561 }
562
563 int
564 md_rand()
565 {
566 #ifdef _WIN32
567 return(rand());
568 #else
569 return(lrand48() & 0x7fffffff);
570 #endif
571 }
572
573 int
574 md_srand(seed)
575 register int seed;
576 {
577 #ifdef _WIN32
578 srand(seed);
579 #else
580 srand48(seed);
581 #endif
582 }
583
584 long
585 md_memused()
586 {
587 #ifdef _WIN32
588 MEMORYSTATUS stat;
589
590 GlobalMemoryStatus(&stat);
591
592 return((long)stat.dwTotalPageFile);
593 #else
594 return( (long)sbrk(0) );
595 #endif
596 }
597
598 char *
599 md_gethostname()
600 {
601 static char nodename[80];
602 char *n = NULL;
603 #if !defined(_WIN32) && !defined(__DJGPP__)
604 struct utsname ourname;
605
606 if (uname(&ourname) == 0)
607 n = ourname.nodename;
608 #endif
609 if ((n == NULL) || (*n == '\0'))
610 if ( (n = getenv("COMPUTERNAME")) == NULL)
611 if ( (n = getenv("HOSTNAME")) == NULL)
612 n = "localhost";
613
614 strncpy(nodename, n, 80);
615 nodename[79] = 0;
616
617 return(nodename);
618 }
619
620 int
621 md_erasechar()
622 {
623 #ifdef BSD
624 return(_tty.sg_erase); /* process erase character */
625 #elif defined(USG5_0)
626 return(_tty.c_cc[VERASE]); /* process erase character */
627 #else /* USG5_2 .... curses */
628 return( erasechar() ); /* process erase character */
629 #endif
630 }
631
632 int
633 md_killchar()
634 {
635 #ifdef BSD
636 return(_tty.sg_kill);
637 #elif defined(USG5_0)
638 return(_tty.c_cc[VKILL]);
639 #else /* USG5_2 ..... curses */
640 return( killchar() );
641 #endif
642 }
643
644 /*
645 * unctrl:
646 * Print a readable version of a certain character
647 */
648
649 char *
650 md_unctrl(ch)
651 char ch;
652 {
653 #if USG5_0
654 extern char *_unctrl[]; /* Defined in curses library */
655
656 return _unctrl[ch&0177];
657 #else
658 return( unctrl(ch) );
659 #endif
660 }
661
662 void
663 md_flushinp()
664 {
665 #ifdef BSD
666 ioctl(0, TIOCFLUSH);
667 #elif defined(USG5_0)
668 ioctl(_tty_ch,TCFLSH,0)
669 #else /* USG5_2.... curses */
670 flushinp();
671 #endif
672 }
673
674 /*
675 Cursor/Keypad Support
676
677 Sadly Cursor/Keypad support is less straightforward than it should be.
678
679 The various terminal emulators/consoles choose to differentiate the
680 cursor and keypad keys (with modifiers) in different ways (if at all!).
681 Furthermore they use different code set sequences for each key only
682 a subset of which the various curses libraries recognize. Partly due
683 to incomplete termcap/terminfo entries and partly due to inherent
684 limitations of those terminal capability databases.
685
686 I give curses first crack at decoding the sequences. If it fails to decode
687 it we check for common ESC-prefixed sequences.
688
689 All cursor/keypad results are translated into standard rogue movement
690 commands.
691
692 Unmodified keys are translated to walk commands: hjklyubn
693 Modified (shift,control,alt) are translated to run commands: HJKLYUBN
694
695 Console and supported (differentiated) keys
696 Interix: Cursor Keys, Keypad, Ctl-Keypad
697 Cygwin: Cursor Keys, Keypad, Alt-Cursor Keys
698 MSYS: Cursor Keys, Keypad, Ctl-Cursor Keys, Ctl-Keypad
699 Win32: Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
700 DJGPP: Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
701
702 Interix Console (raw, ncurses)
703 ==============================
704 normal shift ctrl alt
705 ESC [D, ESC F^, ESC [D, ESC [D /# Left #/
706 ESC [C, ESC F$, ESC [C, ESC [C /# Right #/
707 ESC [A, ESC F-, local win, ESC [A /# Up #/
708 ESC [B, ESC F+, local win, ESC [B /# Down #/
709 ESC [H, ESC [H, ESC [H, ESC [H /# Home #/
710 ESC [S, local win, ESC [S, ESC [S /# Page Up #/
711 ESC [T, local win, ESC [T, ESC [T /# Page Down #/
712 ESC [U, ESC [U, ESC [U, ESC [U /# End #/
713 ESC [D, ESC F^, ESC [D, O /# Keypad Left #/
714 ESC [C, ESC F$, ESC [C, O /# Keypad Right #/
715 ESC [A, ESC [A, ESC [-1, O /# Keypad Up #/
716 ESC [B, ESC [B, ESC [-2, O /# Keypad Down #/
717 ESC [H, ESC [H, ESC [-263, O /# Keypad Home #/
718 ESC [S, ESC [S, ESC [-19, O /# Keypad PgUp #/
719 ESC [T, ESC [T, ESC [-20, O /# Keypad PgDn #/
720 ESC [U, ESC [U, ESC [-21, O /# Keypad End #/
721 nothing, nothing, nothing, O /# Kaypad 5 #/
722
723 Interix Console (term=interix, ncurses)
724 ==============================
725 KEY_LEFT, ESC F^, KEY_LEFT, KEY_LEFT /# Left #/
726 KEY_RIGHT, ESC F$, KEY_RIGHT, KEY_RIGHT /# Right #/
727 KEY_UP, 0x146, local win, KEY_UP /# Up #/
728 KEY_DOWN, 0x145, local win, KEY_DOWN /# Down #/
729 ESC [H, ESC [H, ESC [H, ESC [H /# Home #/
730 KEY_PPAGE, local win, KEY_PPAGE, KEY_PPAGE /# Page Up #/
731 KEY_NPAGE, local win, KEY_NPAGE, KEY_NPAGE /# Page Down #/
732 KEY_LL, KEY_LL, KEY_LL, KEY_LL /# End #/
733 KEY_LEFT, ESC F^, ESC [-4, O /# Keypad Left #/
734 KEY_RIGHT, ESC F$, ESC [-3, O /# Keypad Right #/
735 KEY_UP, KEY_UP, ESC [-1, O /# Keypad Up #/
736 KEY_DOWN, KEY_DOWN, ESC [-2, O /# Keypad Down #/
737 ESC [H, ESC [H, ESC [-263, O /# Keypad Home #/
738 KEY_PPAGE, KEY_PPAGE, ESC [-19, O /# Keypad PgUp #/
739 KEY_NPAGE, KEY_NPAGE, ESC [-20, O /# Keypad PgDn #/
740 KEY_LL, KEY_LL, ESC [-21, O /# Keypad End #/
741 nothing, nothing, nothing, O /# Keypad 5 #/
742
743 Cygwin Console (raw, ncurses)
744 ==============================
745 normal shift ctrl alt
746 ESC [D, ESC [D, ESC [D, ESC ESC [D /# Left #/
747 ESC [C, ESC [C, ESC [C, ESC ESC [C /# Rght #/
748 ESC [A, ESC [A, ESC [A, ESC ESC [A /# Up #/
749 ESC [B, ESC [B, ESC [B, ESC ESC [B /# Down #/
750 ESC [1~, ESC [1~, ESC [1~, ESC ESC [1~ /# Home #/
751 ESC [5~, ESC [5~, ESC [5~, ESC ESC [5~ /# Page Up #/
752 ESC [6~, ESC [6~, ESC [6~, ESC ESC [6~ /# Page Down #/
753 ESC [4~, ESC [4~, ESC [4~, ESC ESC [4~ /# End #/
754 ESC [D, ESC [D, ESC [D, ESC ESC [D,O /# Keypad Left #/
755 ESC [C, ESC [C, ESC [C, ESC ESC [C,O /# Keypad Right #/
756 ESC [A, ESC [A, ESC [A, ESC ESC [A,O /# Keypad Up #/
757 ESC [B, ESC [B, ESC [B, ESC ESC [B,O /# Keypad Down #/
758 ESC [1~, ESC [1~, ESC [1~, ESC ESC [1~,O /# Keypad Home #/
759 ESC [5~, ESC [5~, ESC [5~, ESC ESC [5~,O /# Keypad PgUp #/
760 ESC [6~, ESC [6~, ESC [6~, ESC ESC [6~,O /# Keypad PgDn #/
761 ESC [4~, ESC [4~, ESC [4~, ESC ESC [4~,O /# Keypad End #/
762 ESC [-71, nothing, nothing, O /# Keypad 5 #/
763
764 Cygwin Console (term=cygwin, ncurses)
765 ==============================
766 KEY_LEFT, KEY_LEFT, KEY_LEFT, ESC-260 /# Left #/
767 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, ESC-261 /# Rght #/
768 KEY_UP, KEY_UP, KEY_UP, ESC-259 /# Up #/
769 KEY_DOWN, KEY_DOWN, KEY_DOWN, ESC-258 /# Down #/
770 KEY_HOME, KEY_HOME, KEY_HOME, ESC-262 /# Home #/
771 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, ESC-339 /# Page Up #/
772 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, ESC-338 /# Page Down #/
773 KEY_END, KEY_END, KEY_END, ESC-360 /# End #/
774 KEY_LEFT, KEY_LEFT, KEY_LEFT, ESC-260,O /# Keypad Left #/
775 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, ESC-261,O /# Keypad Right #/
776 KEY_UP, KEY_UP, KEY_UP, ESC-259,O /# Keypad Up #/
777 KEY_DOWN, KEY_DOWN, KEY_DOWN, ESC-258,O /# Keypad Down #/
778 KEY_HOME, KEY_HOME, KEY_HOME, ESC-262,O /# Keypad Home #/
779 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, ESC-339,O /# Keypad PgUp #/
780 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, ESC-338,O /# Keypad PgDn #/
781 KEY_END, KEY_END, KEY_END, ESC-360,O /# Keypad End #/
782 ESC [G, nothing, nothing, O /# Keypad 5 #/
783
784 MSYS Console (raw, ncurses)
785 ==============================
786 normal shift ctrl alt
787 ESC OD, ESC [d, ESC Od nothing /# Left #/
788 ESC OE, ESC [e, ESC Oe, nothing /# Right #/
789 ESC OA, ESC [a, ESC Oa, nothing /# Up #/
790 ESC OB, ESC [b, ESC Ob, nothing /# Down #/
791 ESC [7~, ESC [7$, ESC [7^, nothing /# Home #/
792 ESC [5~, local window, ESC [5^, nothing /# Page Up #/
793 ESC [6~, local window, ESC [6^, nothing /# Page Down #/
794 ESC [8~, ESC [8$, ESC [8^, nothing /# End #/
795 ESC OD, ESC [d, ESC Od O /# Keypad Left #/
796 ESC OE, ESC [c, ESC Oc, O /# Keypad Right #/
797 ESC OA, ESC [a, ESC Oa, O /# Keypad Up #/
798 ESC OB, ESC [b, ESC Ob, O /# Keypad Down #/
799 ESC [7~, ESC [7$, ESC [7^, O /# Keypad Home #/
800 ESC [5~, local window, ESC [5^, O /# Keypad PgUp #/
801 ESC [6~, local window, ESC [6^, O /# Keypad PgDn #/
802 ESC [8~, ESC [8$, ESC [8^, O /# Keypad End #/
803 11, 11, 11, O /# Keypad 5 #/
804
805 MSYS Console (term=rxvt, ncurses)
806 ==============================
807 normal shift ctrl alt
808 KEY_LEFT, KEY_SLEFT, 514 nothing /# Left #/
809 KEY_RIGHT, KEY_SRIGHT, 516, nothing /# Right #/
810 KEY_UP, 518, 519, nothing /# Up #/
811 KEY_DOWN, 511, 512, nothing /# Down #/
812 KEY_HOME, KEY_SHOME, ESC [7^, nothing /# Home #/
813 KEY_PPAGE, local window, ESC [5^, nothing /# Page Up #/
814 KEY_NPAGE, local window, ESC [6^, nothing /# Page Down #/
815 KEY_END, KEY_SEND, KEY_EOL, nothing /# End #/
816 KEY_LEFT, KEY_SLEFT, 514 O /# Keypad Left #/
817 KEY_RIGHT, KEY_SRIGHT, 516, O /# Keypad Right #/
818 KEY_UP, 518, 519, O /# Keypad Up #/
819 KEY_DOWN, 511, 512, O /# Keypad Down #/
820 KEY_HOME, KEY_SHOME, ESC [7^, O /# Keypad Home #/
821 KEY_PPAGE, local window, ESC [5^, O /# Keypad PgUp #/
822 KEY_NPAGE, local window, ESC [6^, O /# Keypad PgDn #/
823 KEY_END, KEY_SEND, KEY_EOL, O /# Keypad End #/
824 11, 11, 11, O /# Keypad 5 #/
825
826 Win32 Console (raw, pdcurses)
827 DJGPP Console (raw, pdcurses)
828 ==============================
829 normal shift ctrl alt
830 260, 391, 443, 493 /# Left #/
831 261, 400, 444, 492 /# Right #/
832 259, 547, 480, 490 /# Up #/
833 258, 548, 481, 491 /# Down #/
834 262, 388, 447, 524 /# Home #/
835 339, 396, 445, 526 /# Page Up #/
836 338, 394, 446, 520 /# Page Down #/
837 358, 384, 448, 518 /# End #/
838 452, 52('4'), 511, 521 /# Keypad Left #/
839 454, 54('6'), 513, 523 /# Keypad Right #/
840 450, 56('8'), 515, 525 /# Keypad Up #/
841 456, 50('2'), 509, 519 /# Keypad Down #/
842 449, 55('7'), 514, 524 /# Keypad Home #/
843 451, 57('9'), 516, 526 /# Keypad PgUp #/
844 457, 51('3'), 510, 520 /# Keypad PgDn #/
845 455, 49('1'), 508, 518 /# Keypad End #/
846 453, 53('5'), 512, 522 /# Keypad 5 #/
847
848 Win32 Console (pdcurses, MSVC/MingW32)
849 DJGPP Console (pdcurses)
850 ==============================
851 normal shift ctrl alt
852 KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT /# Left #/
853 KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT /# Right #/
854 KEY_UP, KEY_SUP, CTL_UP, ALT_UP /# Up #/
855 KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN /# Down #/
856 KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME /# Home #/
857 KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP /# Page Up #/
858 KEY_NPAGE, KEY_SNEXTE, CTL_PGDN, ALT_PGDN /# Page Down #/
859 KEY_END, KEY_SEND, CTL_END, ALT_END /# End #/
860 KEY_B1, 52('4'), CTL_PAD4, ALT_PAD4 /# Keypad Left #/
861 KEY_B3, 54('6'), CTL_PAD6, ALT_PAD6 /# Keypad Right #/
862 KEY_A2, 56('8'), CTL_PAD8, ALT_PAD8 /# Keypad Up #/
863 KEY_C2, 50('2'), CTL_PAD2, ALT_PAD2 /# Keypad Down #/
864 KEY_A1, 55('7'), CTL_PAD7, ALT_PAD7 /# Keypad Home #/
865 KEY_A3, 57('9'), CTL_PAD9, ALT_PAD9 /# Keypad PgUp #/
866 KEY_C3, 51('3'), CTL_PAD3, ALT_PAD3 /# Keypad PgDn #/
867 KEY_C1, 49('1'), CTL_PAD1, ALT_PAD1 /# Keypad End #/
868 KEY_B2, 53('5'), CTL_PAD5, ALT_PAD5 /# Keypad 5 #/
869
870 Windows Telnet (raw)
871 ==============================
872 normal shift ctrl alt
873 ESC [D, ESC [D, ESC [D, ESC [D /# Left #/
874 ESC [C, ESC [C, ESC [C, ESC [C /# Right #/
875 ESC [A, ESC [A, ESC [A, ESC [A /# Up #/
876 ESC [B, ESC [B, ESC [B, ESC [B /# Down #/
877 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Home #/
878 ESC [5~, ESC [5~, ESC [5~, ESC [5~ /# Page Up #/
879 ESC [6~, ESC [6~, ESC [6~, ESC [6~ /# Page Down #/
880 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# End #/
881 ESC [D, ESC [D, ESC [D, ESC [D /# Keypad Left #/
882 ESC [C, ESC [C, ESC [C, ESC [C /# Keypad Right #/
883 ESC [A, ESC [A, ESC [A, ESC [A /# Keypad Up #/
884 ESC [B, ESC [B, ESC [B, ESC [B /# Keypad Down #/
885 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Keypad Home #/
886 ESC [5~, ESC [5~, ESC [5~, ESC [5~ /# Keypad PgUp #/
887 ESC [6~, ESC [6~, ESC [6~, ESC [6~ /# Keypad PgDn #/
888 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# Keypad End #/
889 nothing, nothing, nothing, nothing /# Keypad 5 #/
890
891 Windows Telnet (term=xterm)
892 ==============================
893 normal shift ctrl alt
894 KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT /# Left #/
895 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, KEY_RIGHT /# Right #/
896 KEY_UP, KEY_UP, KEY_UP, KEY_UP /# Up #/
897 KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN /# Down #/
898 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Home #/
899 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, KEY_PPAGE /# Page Up #/
900 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, KEY_NPAGE /# Page Down #/
901 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# End #/
902 KEY_LEFT, KEY_LEFT, KEY_LEFT, O /# Keypad Left #/
903 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, O /# Keypad Right #/
904 KEY_UP, KEY_UP, KEY_UP, O /# Keypad Up #/
905 KEY_DOWN, KEY_DOWN, KEY_DOWN, O /# Keypad Down #/
906 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Keypad Home #/
907 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, KEY_PPAGE /# Keypad PgUp #/
908 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, KEY_NPAGE /# Keypad PgDn #/
909 ESC [4~, ESC [4~, ESC [4~, O /# Keypad End #/
910 ESC [-71, nothing, nothing, O /# Keypad 5 #/
911
912 PuTTY
913 ==============================
914 normal shift ctrl alt
915 ESC [D, ESC [D, ESC OD, ESC [D /# Left #/
916 ESC [C, ESC [C, ESC OC, ESC [C /# Right #/
917 ESC [A, ESC [A, ESC OA, ESC [A /# Up #/
918 ESC [B, ESC [B, ESC OB, ESC [B /# Down #/
919 ESC [1~, ESC [1~, local win, ESC [1~ /# Home #/
920 ESC [5~, local win, local win, ESC [5~ /# Page Up #/
921 ESC [6~, local win, local win, ESC [6~ /# Page Down #/
922 ESC [4~, ESC [4~, local win, ESC [4~ /# End #/
923 ESC [D, ESC [D, ESC [D, O /# Keypad Left #/
924 ESC [C, ESC [C, ESC [C, O /# Keypad Right #/
925 ESC [A, ESC [A, ESC [A, O /# Keypad Up #/
926 ESC [B, ESC [B, ESC [B, O /# Keypad Down #/
927 ESC [1~, ESC [1~, ESC [1~, O /# Keypad Home #/
928 ESC [5~, ESC [5~, ESC [5~, O /# Keypad PgUp #/
929 ESC [6~, ESC [6~, ESC [6~, O /# Keypad PgDn #/
930 ESC [4~, ESC [4~, ESC [4~, O /# Keypad End #/
931 nothing, nothing, nothing, O /# Keypad 5 #/
932
933 PuTTY
934 ==============================
935 normal shift ctrl alt
936 KEY_LEFT, KEY_LEFT, ESC OD, ESC KEY_LEFT /# Left #/
937 KEY_RIGHT KEY_RIGHT, ESC OC, ESC KEY_RIGHT /# Right #/
938 KEY_UP, KEY_UP, ESC OA, ESC KEY_UP /# Up #/
939 KEY_DOWN, KEY_DOWN, ESC OB, ESC KEY_DOWN /# Down #/
940 ESC [1~, ESC [1~, local win, ESC ESC [1~ /# Home #/
941 KEY_PPAGE local win, local win, ESC KEY_PPAGE /# Page Up #/
942 KEY_NPAGE local win, local win, ESC KEY_NPAGE /# Page Down #/
943 ESC [4~, ESC [4~, local win, ESC ESC [4~ /# End #/
944 ESC Ot, ESC Ot, ESC Ot, O /# Keypad Left #/
945 ESC Ov, ESC Ov, ESC Ov, O /# Keypad Right #/
946 ESC Ox, ESC Ox, ESC Ox, O /# Keypad Up #/
947 ESC Or, ESC Or, ESC Or, O /# Keypad Down #/
948 ESC Ow, ESC Ow, ESC Ow, O /# Keypad Home #/
949 ESC Oy, ESC Oy, ESC Oy, O /# Keypad PgUp #/
950 ESC Os, ESC Os, ESC Os, O /# Keypad PgDn #/
951 ESC Oq, ESC Oq, ESC Oq, O /# Keypad End #/
952 ESC Ou, ESC Ou, ESC Ou, O /# Keypad 5 #/
953 */
954
955 #define M_NORMAL 0
956 #define M_ESC 1
957 #define M_KEYPAD 2
958 #define M_TRAIL 3
959
960 int
961 md_readchar(WINDOW *win)
962 {
963 int ch = 0;
964 int lastch = 0;
965 int mode = M_NORMAL;
966 int mode2 = M_NORMAL;
967
968 for(;;)
969 {
970 ch = wgetch(win);
971
972 if (ch == ERR) /* timed out waiting for valid sequence */
973 { /* flush input so far and start over */
974 mode = M_NORMAL;
975 nocbreak();
976 raw();
977 ch = 27;
978 break;
979 }
980
981 if (mode == M_TRAIL)
982 {
983 if (ch == '^') /* msys console : 7,5,6,8: modified*/
984 ch = MOD_MOVE( toupper(lastch) );
985
986 if (ch == '~') /* cygwin console: 1,5,6,4: normal */
987 ch = tolower(lastch); /* windows telnet: 1,5,6,4: normal */
988 /* msys console : 7,5,6,8: normal */
989
990 if (mode2 == M_ESC) /* cygwin console: 1,5,6,4: modified*/
991 ch = MOD_MOVE( toupper(ch) );
992
993 break;
994 }
995
996 if (mode == M_ESC)
997 {
998 if (ch == 27)
999 {
1000 mode2 = M_ESC;
1001 continue;
1002 }
1003
1004 if ((ch == 'F') || (ch == 'O') || (ch == '['))
1005 {
1006 mode = M_KEYPAD;
1007 continue;
1008 }
1009
1010
1011 switch(ch)
1012 {
1013 /* Cygwin Console */
1014 /* PuTTY */
1015 case KEY_LEFT : ch = MOD_MOVE('H'); break;
1016 case KEY_RIGHT: ch = MOD_MOVE('L'); break;
1017 case KEY_UP : ch = MOD_MOVE('K'); break;
1018 case KEY_DOWN : ch = MOD_MOVE('J'); break;
1019 case KEY_HOME : ch = MOD_MOVE('Y'); break;
1020 case KEY_PPAGE: ch = MOD_MOVE('U'); break;
1021 case KEY_NPAGE: ch = MOD_MOVE('N'); break;
1022 case KEY_END : ch = MOD_MOVE('B'); break;
1023
1024 default: break;
1025 }
1026
1027 break;
1028 }
1029
1030 if (mode == M_KEYPAD)
1031 {
1032 switch(ch)
1033 {
1034 /* ESC F - Interix Console codes */
1035 case '^': ch = MOD_MOVE('H'); break; /* Shift-Left */
1036 case '$': ch = MOD_MOVE('L'); break; /* Shift-Right */
1037
1038 /* ESC [ - Interix Console codes */
1039 case 'H': ch = 'y'; break; /* Home */
1040 case 1: ch = MOD_MOVE('K'); break; /* Ctl-Keypad Up */
1041 case 2: ch = MOD_MOVE('J'); break; /* Ctl-Keypad Down */
1042 case 3: ch = MOD_MOVE('L'); break; /* Ctl-Keypad Right */
1043 case 4: ch = MOD_MOVE('H'); break; /* Ctl-Keypad Left */
1044 case 263: ch = MOD_MOVE('Y'); break; /* Ctl-Keypad Home */
1045 case 19: ch = MOD_MOVE('U'); break; /* Ctl-Keypad PgUp */
1046 case 20: ch = MOD_MOVE('N'); break; /* Ctl-Keypad PgDn */
1047 case 21: ch = MOD_MOVE('B'); break; /* Ctl-Keypad End */
1048
1049 /* ESC [ - Cygwin Console codes */
1050 case 'G': ch = '.'; break; /* Keypad 5 */
1051 case '7': lastch = 'Y'; mode=M_TRAIL; break; /* Ctl-Home */
1052 case '5': lastch = 'U'; mode=M_TRAIL; break; /* Ctl-PgUp */
1053 case '6': lastch = 'N'; mode=M_TRAIL; break; /* Ctl-PgDn */
1054
1055 /* ESC [ - Win32 Telnet, PuTTY */
1056 case '1': lastch = 'y'; mode=M_TRAIL; break; /* Home */
1057 case '4': lastch = 'b'; mode=M_TRAIL; break; /* End */
1058
1059 /* ESC O - PuTTY */
1060 case 'D': ch = MOD_MOVE('H'); break;
1061 case 'C': ch = MOD_MOVE('L'); break;
1062 case 'A': ch = MOD_MOVE('K'); break;
1063 case 'B': ch = MOD_MOVE('J'); break;
1064 case 't': ch = 'h'; break;
1065 case 'v': ch = 'l'; break;
1066 case 'x': ch = 'k'; break;
1067 case 'r': ch = 'j'; break;
1068 case 'w': ch = 'y'; break;
1069 case 'y': ch = 'u'; break;
1070 case 's': ch = 'n'; break;
1071 case 'q': ch = 'b'; break;
1072 case 'u': ch = '.'; break;
1073 }
1074
1075 if (mode != M_KEYPAD)
1076 continue;
1077 }
1078
1079 if (ch == 27)
1080 {
1081 halfdelay(1);
1082 mode = M_ESC;
1083 continue;
1084 }
1085
1086 switch(ch)
1087 {
1088 case KEY_LEFT : ch = 'h'; break;
1089 case KEY_DOWN : ch = 'j'; break;
1090 case KEY_UP : ch = 'k'; break;
1091 case KEY_RIGHT : ch = 'l'; break;
1092 case KEY_HOME : ch = 'y'; break;
1093 case KEY_PPAGE : ch = 'u'; break;
1094 case KEY_END : ch = 'b'; break;
1095 #ifdef KEY_LL
1096 case KEY_LL : ch = 'b'; break;
1097 #endif
1098 case KEY_NPAGE : ch = 'n'; break;
1099
1100 #ifdef KEY_B1
1101 case KEY_B1 : ch = 'h'; break;
1102 case KEY_C2 : ch = 'j'; break;
1103 case KEY_A2 : ch = 'k'; break;
1104 case KEY_B3 : ch = 'l'; break;
1105 #endif
1106 case KEY_A1 : ch = 'y'; break;
1107 case KEY_A3 : ch = 'u'; break;
1108 case KEY_C1 : ch = 'b'; break;
1109 case KEY_C3 : ch = 'n'; break;
1110 /* next should be '.', but for problem with putty/linux */
1111 case KEY_B2 : ch = 'u'; break;
1112
1113 #ifdef KEY_SLEFT
1114 case KEY_SRIGHT : ch = MOD_MOVE('L'); break;
1115 case KEY_SLEFT : ch = MOD_MOVE('H'); break;
1116 #ifdef KEY_SUP
1117 case KEY_SUP : ch = MOD_MOVE('K'); break;
1118 case KEY_SDOWN : ch = MOD_MOVE('J'); break;
1119 #endif
1120 case KEY_SHOME : ch = MOD_MOVE('Y'); break;
1121 case KEY_SPREVIOUS:ch = MOD_MOVE('U'); break;
1122 case KEY_SEND : ch = MOD_MOVE('B'); break;
1123 case KEY_SNEXT : ch = MOD_MOVE('N'); break;
1124 #endif
1125 case 0x146 : ch = MOD_MOVE('K'); break; /* Shift-Up */
1126 case 0x145 : ch = MOD_MOVE('J'); break; /* Shift-Down */
1127
1128 #ifdef CTL_RIGHT
1129 case CTL_RIGHT : ch = MOD_MOVE('L'); break;
1130 case CTL_LEFT : ch = MOD_MOVE('H'); break;
1131 case CTL_UP : ch = MOD_MOVE('K'); break;
1132 case CTL_DOWN : ch = MOD_MOVE('J'); break;
1133 case CTL_HOME : ch = MOD_MOVE('Y'); break;
1134 case CTL_PGUP : ch = MOD_MOVE('U'); break;
1135 case CTL_END : ch = MOD_MOVE('B'); break;
1136 case CTL_PGDN : ch = MOD_MOVE('N'); break;
1137 #endif
1138 #ifdef KEY_EOL
1139 case KEY_EOL : ch = MOD_MOVE('B'); break;
1140 #endif
1141
1142 #ifndef CTL_PAD1
1143 /* MSYS rxvt console */
1144 case 511 : ch = MOD_MOVE('J'); break; /* Shift Dn */
1145 case 512 : ch = MOD_MOVE('J'); break; /* Ctl Down */
1146 case 514 : ch = MOD_MOVE('H'); break; /* Ctl Left */
1147 case 516 : ch = MOD_MOVE('L'); break; /* Ctl Right*/
1148 case 518 : ch = MOD_MOVE('K'); break; /* Shift Up */
1149 case 519 : ch = MOD_MOVE('K'); break; /* Ctl Up */
1150 #endif
1151
1152 #ifdef CTL_PAD1
1153 case CTL_PAD1 : ch = MOD_MOVE('B'); break;
1154 case CTL_PAD2 : ch = MOD_MOVE('J'); break;
1155 case CTL_PAD3 : ch = MOD_MOVE('N'); break;
1156 case CTL_PAD4 : ch = MOD_MOVE('H'); break;
1157 case CTL_PAD5 : ch = '.'; break;
1158 case CTL_PAD6 : ch = MOD_MOVE('L'); break;
1159 case CTL_PAD7 : ch = MOD_MOVE('Y'); break;
1160 case CTL_PAD8 : ch = MOD_MOVE('K'); break;
1161 case CTL_PAD9 : ch = MOD_MOVE('U'); break;
1162 #endif
1163
1164 #ifdef ALT_RIGHT
1165 case ALT_RIGHT : ch = MOD_MOVE('L'); break;
1166 case ALT_LEFT : ch = MOD_MOVE('H'); break;
1167 case ALT_DOWN : ch = MOD_MOVE('J'); break;
1168 case ALT_HOME : ch = MOD_MOVE('Y'); break;
1169 case ALT_PGUP : ch = MOD_MOVE('U'); break;
1170 case ALT_END : ch = MOD_MOVE('B'); break;
1171 case ALT_PGDN : ch = MOD_MOVE('N'); break;
1172 #endif
1173
1174 #ifdef ALT_PAD1
1175 case ALT_PAD1 : ch = MOD_MOVE('B'); break;
1176 case ALT_PAD2 : ch = MOD_MOVE('J'); break;
1177 case ALT_PAD3 : ch = MOD_MOVE('N'); break;
1178 case ALT_PAD4 : ch = MOD_MOVE('H'); break;
1179 case ALT_PAD5 : ch = '.'; break;
1180 case ALT_PAD6 : ch = MOD_MOVE('L'); break;
1181 case ALT_PAD7 : ch = MOD_MOVE('Y'); break;
1182 case ALT_PAD8 : ch = MOD_MOVE('K'); break;
1183 case ALT_PAD9 : ch = MOD_MOVE('U'); break;
1184 #endif
1185 }
1186
1187 break;
1188 }
1189
1190 nocbreak(); /* disable halfdelay mode if on */
1191 raw();
1192
1193 return(ch & 0x7F);
1194 }