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