comparison urogue/mdport.c @ 256:c495a4f288c6

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