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