1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
/*
* TTY interface header file
* Copyright
* (C) 1992 Joseph H. Allen
*
* This file is part of JOE (Joe's Own Editor)
*/
#ifndef _JOE_TTY_H
#define _JOE_TTY_H 1
struct mpx {
int ackfd; /* Packetizer response descriptor */
int kpid; /* Packetizer process id */
int pid; /* Client process id */
void (*func) (); /* Function to call when read occures */
void *object; /* First arg to pass to function */
void (*die) (); /* Function: call when client dies or closes */
void *dieobj;
};
/* void ttopen(void); Open the tty (attached to stdin) for use inside of JOE
*
* (0) Call sigjoe()
* There is also 'void ttopnn(void)' which does not do this step.
*
* (1) fflush(stdout)
*
* (2) Save the current state of the tty
*
* (3) Disable CR/LF/NL input translations,
* Disable all output processing,
* Disable echo and line editing, and
* Place tty in character at a time mode.
* (basically, disable all processing except for XON/XOFF if it's set)
*
* (4) Set this new tty state without loosing any typeahead (by using the
* proper ioctl).
*
* (5) Store the baud rate in the global variable 'baud'
*
* (6) Divide the baud rate into the constant DIVIDEND and store the result
* in the global variable 'upc'. This should come out to the number
* of microseconds needed to send each character. The constant 'DIVIDEND'
* should be chosen so that 'upc' reflects the real throughput of the
* tty, not the theoretical best throughput.
*
* (7) Create an output buffer of a size which depends on 'upc' and the
* constant 'TIMES'. 'TIMES' is the number of times per second JOE
* should check for typeahead. Since we only check for typehead after
* the output buffer is flushed, 'upc' and the size of the output buffer
* determine how often this occurs. So for example if 'upc'==1000 (~9600
* baud) and 'TIMES'==3, the output buffer size is set to 333 characters.
* Each time this buffer is completely flushed, 1/3 of a second will go by.
*/
void ttopen PARAMS((void));
void ttopnn PARAMS((void));
extern unsigned long upc; /* Microseconds per character */
extern unsigned baud; /* Baud rate */
#define TIMES 3
#define DIVIDEND 10000000
/* void ttclose(void); Restore the tty back to its original mode.
*
* (1) ttyflsh()
*
* (2) Restore the original tty mode which aopen() had saved. Do this without
* loosing any typeahead.
*
* (3) Call signrm(). There is also 'void ttyclsn(void)' which does not do
* the this step.
*/
void ttclose PARAMS((void));
void ttclsn PARAMS((void));
/* int ttgetc(void); Flush the output and get the next character from the tty
*
* (1) ttflsh()
*
* (2) Read the next input character
* If the input closed, call 'ttsig' with 0 as its argument.
*
* (3) Clear 'have'
*/
int ttgetc PARAMS((void));
/* void ttputc(char c); Write a character to the output buffer. If it becomes
* full, call ttflsh()
*/
extern int obufp; /* Output buffer index */
extern int obufsiz; /* Output buffer size */
extern unsigned char *obuf; /* Output buffer */
#define ttputc(c) { obuf[obufp++] = (c); if(obufp == obufsiz) ttflsh(); }
/* void ttputs(char *s); Write a string to the output buffer. Any time the
* output buffer gets full, call ttflsh()
*/
void ttputs PARAMS((unsigned char *s));
/* int ttshell(char *s); Run a shell command or if 's' is zero, run a
* sub-shell
*/
int ttshell PARAMS((unsigned char *cmd));
/* void ttsusp(void); Suspend the process, or if the UNIX can't do it, call
* ttshell(NULL)
*/
void ttsusp PARAMS((void));
/* int ttflsh(void); Flush the output buffer and check for typeahead.
*
* (1) write() any characters in the output buffer to the tty and then sleep
* for the amount of time it should take for the written characters to get
* to the tty. This is so that any buffering between the editor and the
* tty is defeated. If this is not done, the screen update will not be
* able to defer for typeahead.
*
* The best way to do the sleep (possible only on systems with the
* setitimer call) is to set a timer for the necessary amount, write the
* characters to the tty, and then sleep until the timer expires.
*
* If this can't be done, it's usually ok to 'write' and then to sleep for
* the necessary amount of time. However, you will notice delays in the
* screen update if the 'write' actually takes any significant amount of
* time to execute (it usually takes none since all it usually does is
* write to an operating system output buffer).
*
* (2) The way we check for typeahead is to put the TTY in nonblocking mode
* and attempt to read a character. If one could be read, the global
* variable 'have' is set to indicate that there is typeahead pending and
* the character is stored in a single character buffer until ttgetc
* is called. If the global variable 'leave' is set, the check for
* typeahead is disabled. This is so that once the program knows that it's
* about to exit, it doesn't eat the first character of your typeahead if
* ttflsh gets called. 'leave' should also be set before shell escapes and
* suspends.
*/
int ttflsh PARAMS((void));
extern int have; /* Set if we have typeahead */
extern int leave; /* Set if we're exiting (so don't check for typeahead) */
#ifdef __MSDOS__
#define ifhave bioskey(1)
#else
#define ifhave have
#endif
/* void ttsig(int n); Signal handler you provide. This is called if the
* editor gets a hangup signal, termination signal or if the input closes.
* It is called with 'n' set to the number of the caught signal or 0 if the
* input closed.
*/
void ttsig PARAMS((int sig));
/* void ttgtsz(int *x,int *y); Get size of screen from ttsize/winsize
* structure */
void ttgtsz PARAMS((int *x, int *y));
/* You don't have to call these: ttopen/ttclose does it for you. These
* may be needed to make your own shell escape sequences.
*/
/* void sigjoe(void); Set the signal handling for joe. I.E., ignore all
* signals the user can generate from the keyboard (SIGINT, SIGPIPE)
* and trap the software terminate and hangup signals (SIGTERM, SIGHUP) so
* that 'ttsig' gets called.
*/
void sigjoe PARAMS((void));
/* void signrm(void); Set above signals back to their default values.
*/
void signrm PARAMS((void));
/* MPX *mpxmk(int fd,int pid,
* void (*func)(),void *object,
* void (*die)(),void *dieobj,
* );
*
* Create an asynchronous input source handler for a process
* Child process id in 'pid'
* File descriptor to get input from in 'fd'
* Function to call with received characters in 'func'
* Function to call when process dies in 'die'
* The first arg passed to func and die is object and dieobj
*/
MPX *mpxmk PARAMS((int *ptyfd, unsigned char *cmd, unsigned char **args, void (*func) (/* ??? */), void *object, void (*die) (/* ??? */), void *dieobj, int out_only));
/* int subshell(int *ptyfd);
* Execute a subshell. Returns 'pid' of shell or zero if there was a
* problem. Returns file descriptor for the connected pty in 'ptyfd'.
*/
int subshell PARAMS(());
extern int noxon; /* Set if ^S/^Q processing should be disabled */
extern int Baud; /* Baud rate from joerc, cmd line or environment */
void tickoff PARAMS((void));
void tickon PARAMS((void));
extern long last_time; /* Current time in seconds */
extern int idleout; /* Clear to use /dev/tty for screen */
#endif
|