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