📄 minedio.c
字号:
/* ================================================================== * * Editor mined * * Operating system dependant I/O * * ================================================================== */#include "mined.h"#include <errno.h>#include <signal.h>#ifdef CURSES#include <curses.h>#undef FALSE#undef TRUE#undef TERMIO /* \ must be */#undef SGTTY /* / disabled */#endif#ifdef TERMIO#include <termios.h>#endif#ifdef SGTTY#include <sys/ioctl.h> /* <sgtty.h> ? */extern void ioctl ();#endif#ifdef SIGPHONE /* this trick was taken from less' screen.c */#include <sys/window.h> /* for window size detection */#endif#ifdef msdos#define _getch_#include <dos.h>#endif#ifdef unix#include <sys/time.h> /* for struct timeval (for select in inputreadyafter) */#define selectread /* use select () ? */#endif#ifdef vms#include <socket.h> /* for select () and struct timeval */# ifdef CURSES# define _getch_# endif#endif#ifdef _getch_#ifndef CURSESextern int getch ();#endif#endif/* ================================================================== * * Unix signalling routines * * ================================================================== */voidcatch_signals (catch) void (* catch) ();{#ifdef SIGHUP signal (SIGHUP, catch);#endif#ifdef SIGILL signal (SIGILL, catch);#endif#ifdef SIGTRAP signal (SIGTRAP, catch);#endif#ifdef SIGABRT signal (SIGABRT, catch);#endif#ifdef SIGEMT signal (SIGEMT, catch);#endif#ifdef SIGFPE signal (SIGFPE, catch);#endif#ifdef SIGBUS signal (SIGBUS, catch);#endif#ifdef SIGSEGV signal (SIGSEGV, catch);#endif#ifdef SIGSYS signal (SIGSYS, catch);#endif#ifdef SIGPIPE signal (SIGPIPE, catch);#endif#ifdef SIGALRM signal (SIGALRM, catch);#endif#ifdef SIGTERM signal (SIGTERM, catch);#endif#ifdef SIGXCPU signal (SIGXCPU, catch);#endif#ifdef SIGXFSZ signal (SIGXFSZ, catch);#endif#ifdef SIGVTALRM signal (SIGVTALRM, catch);#endif#ifdef SIGPROF signal (SIGPROF, catch);#endif#ifdef SIGLOST signal (SIGLOST, catch);#endif#ifdef SIGUSR1 signal (SIGUSR1, catch);#endif#ifdef SIGUSR2 signal (SIGUSR2, catch);#endif#ifdef SIGUSR3 signal (SIGUSR3, catch);#endif}#ifdef SIGTSTPvoidsuspendmyself (){ kill (getpid (), SIGTSTP);}FLAG cansuspendmyself = TRUE;#elsevoidsuspendmyself (){}FLAG cansuspendmyself = FALSE;#endif#ifdef SIGWINCH/* * Catch the SIGWINCH signal sent to mined. */voidcatchwinch (){ winchg = TRUE;/* if (waitingforinput == TRUE) RDwin (); *//* This is now performed in __readchar () to prevent display garbage in case this interrupts occurs during display output operations which get screen size related values changed while relying on them. */ signal (SIGWINCH, catchwinch); /* Re-installation of the signal */}#endif#ifdef SIGQUIT/* * Catch the SIGQUIT signal (^\) sent to mined. It turns on the quitflag. */voidcatchquit (){#ifdef UNUSED /* Should not be needed with new __readchar () *//* Was previously needed on SUN but showed bad effects on Iris. */ static char quitchar = '\0'; if (waitingforinput == TRUE) /* simulate input to enable immediate break also during input */ ioctl (input_fd, TIOCSTI, & quitchar);#endif quit = TRUE; signal (SIGQUIT, catchquit); /* Re-installation of the signal */}#endif#ifdef SIGBREAK/* * Catch the SIGBREAK signal (control-Break) and turn on the quitflag. */voidcatchbreak (){ quit = TRUE; signal (SIGBREAK, catchbreak); /* do we need this ? */}#else# ifdef msdosintcontrolbreak (){ quit = TRUE; return 1 /* continue program execution */;}# endif#endif#ifdef SIGINT/* * Catch the SIGINT signal (^C) sent if it cannot be ignored by tty driver */voidcatchint (){ intr_char = TRUE; signal (SIGINT, catchint); /* Re-installation of the signal */}#endif/* ================================================================== * * Terminal mode switcher * * ================================================================== *//* * Set and reset tty into CBREAK or old mode according to argument `state'. * It also sets all signal characters (except for ^\) to UNDEF. ^\ is caught. */voidraw_mode (state) FLAG state;{#ifdef TERMIO static struct termios old_termio; struct termios new_termio;#ifdef TCGETS# define gettermio(fd, iopoi) ioctl (fd, TCGETS, iopoi);# ifdef TCSETSW# define settermio(fd, iopoi) ioctl (fd, TCSETSW, iopoi);# else# define settermio(fd, iopoi) ioctl (fd, TCSETS, iopoi);# endif#else# define gettermio(fd, iopoi) tcgetattr (fd, iopoi);# ifdef TCSADRAIN# define settermio(fd, iopoi) tcsetattr (fd, TCSADRAIN, iopoi);# else# define settermio(fd, iopoi) tcsetattr (fd, 0, iopoi);# endif#endif#endif /* TERMIO */#ifdef SGTTY static struct sgttyb old_tty; struct sgttyb new_tty; static int oldlmode; int lmode; static struct tchars old_tchars; static struct ltchars old_ltchars;#define NDEF '\377' static struct tchars new_tchars = {NDEF, QUITCHAR, NDEF, NDEF, NDEF, NDEF}; static struct tchars new_QStchars = {NDEF, QUITCHAR, '\021', '\023', NDEF, NDEF}; static struct ltchars new_ltchars = {NDEF, NDEF, NDEF, NDEF, NDEF, NDEF};/* correspondence between the tchars/ltchars characters of the sgtty interface and the c_cc characters of the termios interface (codes vary): sgtty termio sgtty termio t_intrc VINTR t_suspc VSUSP t_quitc VQUIT t_dsuspc VDSUSP t_startc VSTART t_rprntc VREPRINT t_stopc VSTOP t_flushc VDISCARD t_eofc VEOF (VMIN) t_werasc VWERASE t_brkc VEOL (VTIME) t_lnextc VLNEXT*/#endif /* SGTTY */ if (state == OFF) { isscreenmode = FALSE;#ifdef CURSES endwin ();#ifdef vms system ("set terminal /ttsync /nopasthru");#endif#else /* ndef CURSES: */ end_screen_mode (); flush ();#endif /* ndef CURSES */#ifdef TERMIO settermio (input_fd, & old_termio);#endif#ifdef SGTTY ioctl (input_fd, TIOCSETP, & old_tty); ioctl (input_fd, TIOCSETC, & old_tchars); ioctl (input_fd, TIOCSLTC, & old_ltchars); ioctl (input_fd, TIOCLSET, & oldlmode);#endif return; } else /* (state == ON) */ { isscreenmode = TRUE;#ifdef CURSES refresh ();#else start_screen_mode (); flush ();#endif#ifdef TERMIO gettermio (input_fd, & old_termio); gettermio (input_fd, & new_termio); if (controlQS == FALSE) new_termio.c_iflag &= ~(ISTRIP|IXON|IXOFF); else new_termio.c_iflag &= ~(ISTRIP); new_termio.c_oflag &= ~OPOST; new_termio.c_cflag &= ~(PARENB|CSIZE); new_termio.c_cflag |= CS8; new_termio.c_lflag &= ~(ICANON|ECHO);#define NDEF '\000' new_termio.c_cc [VMIN] = 1; new_termio.c_cc [VTIME] = 0; new_termio.c_cc [VQUIT] = QUITCHAR; new_termio.c_cc [VINTR] = NDEF; new_termio.c_cc [VSUSP] = NDEF;#ifdef VDISCARD new_termio.c_cc [VDISCARD] = NDEF;#endif settermio (input_fd, & new_termio);#endif /* TERMIO */#ifdef SGTTY/* Save old tty settings */ ioctl (input_fd, TIOCGETP, & old_tty); ioctl (input_fd, TIOCGETC, & old_tchars); ioctl (input_fd, TIOCGLTC, & old_ltchars); ioctl (input_fd, TIOCLGET, & oldlmode);/* Set line mode *//* If this feature should not be available on some system, RAW must be used instead of CBREAK below to enable 8 bit characters on output */ lmode = oldlmode; lmode |= LPASS8; /* enable 8 bit characters on input in CBREAK mode */ lmode |= LLITOUT; /* enable 8 bit characters on output in CBREAK mode; this may not be necessary in newer Unixes, e.g. SUN-OS 4; output handling is slightly complicated by LITOUT */ ioctl (input_fd, TIOCLSET, & lmode);/* Set tty to CBREAK (or RAW) mode */ new_tty = old_tty; new_tty.sg_flags &= ~ECHO; new_tty.sg_flags |= CBREAK; ioctl (input_fd, TIOCSETP, & new_tty);/* Unset signal chars */ if (controlQS == FALSE) ioctl (input_fd, TIOCSETC, & new_tchars); /* Only leaves QUITCHAR */ else ioctl (input_fd, TIOCSETC, & new_QStchars); /* Leaves QUITCHAR, ^Q, ^S */ ioctl (input_fd, TIOCSLTC, & new_ltchars); /* Leaves nothing */#endif /* SGTTY *//* Define signal handlers */#ifdef SIGQUIT signal (SIGQUIT, catchquit); /* Catch QUITCHAR (^\) */#endif#ifdef SIGBREAK signal (SIGBREAK, catchbreak); /* control-Break (OS/2) */#else# ifdef msdos ctrlbrk (controlbreak); /* completely useless, stupid Turbo-C! */# endif#endif#ifdef SIGINT signal (SIGINT, catchint); /* Catch INTR char (^C) */#endif#ifdef SIGWINCH signal (SIGWINCH, catchwinch); /* Catch window size changes */#endif }}/* ================================================================== * * Unix I/O routines * * ================================================================== */#ifdef CURSESvoid__putchar (c) register uchar c;{ addch (c); }voidputstring (str) register uchar * str;{ addstr (str); }voidflush (){ refresh (); }FLAG can_add_line = TRUE, can_delete_line = TRUE, can_scroll_reverse = TRUE, can_clear_eol = TRUE;voidclear_screen (){ clear ();}voidclear_eol (){ clrtoeol ();}voidscroll_forward (){ scroll (stdscr);}voidscroll_reverse (){ /* only called if cursor is at top of screen */ insertln ();}voidadd_line (y) register int y;{ move (y, 0); insertln ();}voiddelete_line (y) register int y;{ move (y, 0); deleteln ();}voidmove_cursor (x, y) register int x, y;{ move (y, x);}voidreverse_on (){ standout ();}voidreverse_off (){ standend ();}voidget_term_cap (TERMname) char * TERMname;{#ifdef vms system ("set terminal /pasthru /nottsync");#endif initscr ();#ifdef vms crmode ();#else crmode (); /* cbreak (); */ nonl ();#endif noecho (); scrollok (stdscr, TRUE);#ifdef unix#ifndef vax idlok (stdscr, TRUE);#ifndef sun typeahead (input_fd);#endif#endif#endif YMAX = LINES - 1; /* # of lines */ XMAX = COLS - 1; /* # of columns */ getwinsize ();}/*------------------------------------------------------------------------*/#else /* ndef CURSES: */void__putchar (c) register uchar c;{ writechar (output_fd, (c)); }voidputstring (str) register uchar * str;{ (void) writestring (output_fd, (str)); }voidflush (){ (void) flush_buffer (output_fd); }#ifdef unixextern int tgetent ();extern char * tgetstr ();extern int tgetnum ();extern char * tgoto ();extern int tputs ();#define termputstr(str, aff) (void) tputs (str, aff, (intfunc) __putchar)/* Storage for the terminal control sequences */char *cCL, *cCE, *cSR, *cAL, *cDL, *cCS, *cSC, *cRC, *cCM, *cSO, *cSE, *cVS, *cVE, *cTI, *cTE;#define aff1 0#define affmax YMAXFLAG can_add_line = FALSE, can_delete_line = FALSE, can_scroll_reverse = FALSE, can_clear_eol = FALSE;voidclear_screen (){ termputstr (cCL, affmax);}voidclear_eol (){ if (can_clear_eol == TRUE) termputstr (cCE, aff1);}voidscroll_forward (){ move_cursor (0, YMAX);/* putchar ('\n'); */ termputstr ("\n", affmax);}voidscroll_reverse (){ termputstr (cSR, affmax);}voidadd_line (y) register int y;{ if (cAL) { move_cursor (0, y); termputstr (cAL, affmax); } else { move_cursor (0, y); termputstr (cSC, aff1); termputstr (tgoto (cCS, YMAX, y), aff1); termputstr (cRC, aff1); termputstr (cSR, affmax); termputstr (tgoto (cCS, YMAX, 0), aff1); termputstr (cRC, aff1); }}voiddelete_line (y) register int y;{ if (cDL) { move_cursor (0, y); termputstr (cDL, affmax); } else { move_cursor (0, y); termputstr (cSC, aff1); termputstr (tgoto (cCS, YMAX, y), aff1); move_cursor (0, YMAX);/* putchar ('\n'); */ termputstr ("\n", affmax); termputstr (tgoto (cCS, YMAX, 0), aff1); termputstr (cRC, aff1); }}voidmove_cursor (x, y) register int x, y;{ termputstr (tgoto (cCM, x, y), aff1);}voidreverse_on (){ termputstr (cSO, aff1);}voidreverse_off (){ termputstr (cSE, aff1);}voidstart_screen_mode (){ termputstr (cTI, affmax); termputstr (cVS, affmax);/* Install correct scrolling region in case terminal is bigger than assumed *//* (this effect was observed after window size changes of Sun windows): */ if (cCS) termputstr (tgoto (cCS, YMAX, 0), aff1);}voidend_screen_mode (){ termputstr (cTE, affmax); termputstr (cVE, affmax);}voidget_term_cap (TERMname) char * TERMname;{#define termbuflen 100 char entry [1024]; static char termbuf [termbuflen]; char * loc = termbuf; if (tgetent (entry, TERMname) <= 0) { panic ("Unknown terminal", NIL_PTR); } YMAX = tgetnum ("li" /*, & loc */) - 1; /* # of lines */ XMAX = tgetnum ("co" /*, & loc */) - 1; /* # of columns *//* getenv ("LINES"), getenv ("COLUMNS") ?! */ getwinsize (); cCL = tgetstr ("cl", & loc); /* clear screen */ cCE = tgetstr ("ce", & loc); /* clear to end of line */ cSR = tgetstr ("sr", & loc); /* scroll reverse */ cAL = tgetstr ("al", & loc); /* add line */ if (!cSR) cSR = cAL; cDL = tgetstr ("dl", & loc); /* delete line */ cCS = tgetstr ("cs", & loc); /* change scrolling region */ cSC = tgetstr ("sc", & loc); /* save cursor \ needed with vt100 */ cRC = tgetstr ("rc", & loc); /* restore cursor / for add/delete line */ cCM = tgetstr ("cm", & loc); /* cursor motion */ cSO = tgetstr ("so", & loc); /* stand out mode */ cSE = tgetstr ("se", & loc); /* end " */ cVS = tgetstr ("vs", & loc); /* visual mode */ cVE = tgetstr ("ve", & loc); /* end " */ cTI = tgetstr ("ti", & loc); /* positioning mode */ cTE = tgetstr ("te", & loc); /* end " */ if (cAL || (cSR && cCS)) can_add_line = TRUE; if (cSR) can_scroll_reverse = TRUE; if (cDL || cCS) can_delete_line = TRUE; if (cCE) can_clear_eol = TRUE; if (loc > termbuf + termbuflen) { panic ("Terminal control strings don't fit", NIL_PTR); } if (!cCL || !cCM || !cSR || !cCE /* || !cSO || !cSE */ ) { panic ("Sorry, no mined on this type of terminal", NIL_PTR); }}/*------------------------------------------------------------------------*/#endif /* unix */#ifdef msdos/* * checkwin checks if a screen size change has occurred BIOS data: 40:4A word video columns can also be determined with INT10h, function 0Fh 40:84 byte video lines - 1 (EGA/VGA required) 40:85 word character height (pixels) (EGA/VGA required) can also be determined with INT10h, function 11h/30h */intcheckwin (){ return peek (0x40, 0x4A) != XMAX + 1/* the following line requires EGA or VGA: */ || peekb (0x40, 0x84) != YMAX ;}/* * getch () reads in a character from keyboard. We seem to need our
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -