comparison arogue7/mdport.c @ 125:adfa37e67084

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