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