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