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