I want the pty to be seen.
[apps/madtty.git] / madtty / madtty.h
1 /*
2     LICENSE INFORMATION:
3     This program is free software; you can redistribute it and/or
4     modify it under the terms of the GNU Lesser General Public
5     License (LGPL) as published by the Free Software Foundation.
6
7     Please refer to the COPYING file for more information.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12     General Public License for more details.
13
14     You should have received a copy of the GNU Lesser General Public
15     License along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17
18     Copyright © 2004 Bruno T. C. de Oliveira
19     Copyright © 2006 Pierre Habouzit
20  */
21
22 #ifndef MADTTY_MADTTY_H
23 #define MADTTY_MADTTY_H
24
25 #ifdef USE_NCURSES
26 #include <ncurses.h>
27 #else
28 #include <stdbool.h>
29 #endif
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33
34 /* Color codes: 0 = black, 1 = red, 2 = green, 3 = yellow, 4 = blue,
35  *              5 = magenta, 6 = cyan, 7 = white. 
36  *
37  * An 'attribute' as used in this library means an 8-bit value that conveys
38  * a foreground color code, a background color code, and the bold
39  * and blink bits. Each cell in the virtual terminal screen is associated
40  * with an attribute that specifies its appearance. The bits of an attribute,
41  * from most significant to least significant, are 
42  *
43  *  bit:      7 6 5 4 3 2 1 0
44  *  content:  S F F F H B B B
45  *            | `-,-' | `-,-'
46  *            |   |   |   |
47  *            |   |   |   `----- 3-bit background color code (0 - 7)
48  *            |   |   `--------- blink bit (if on, text is blinking)
49  *            |   `------------- 3-bit foreground color code (0 - 7)
50  *            `----------------- bold bit
51  *
52  * It is however recommended that you use the provided macros rather
53  * than dealing with this format directly.
54  *
55  * Sometimes we will call the 'SFFF' nibble above the 'extended
56  * foreground color code', and the 'HBBB' nibble the 'extended background
57  * color code'. So the extended color codes are just the regular
58  * color codes except that they have an additional bit (the most significant
59  * bit) indicating bold/blink.
60  */
61
62 /* retrieve attribute fields */
63 #define ROTE_ATTR_BG(attr)              ((attr) & 0x07)
64 #define ROTE_ATTR_FG(attr)              (((attr) & 0x70) >> 4)
65
66 /* retrieve 'extended' color codes (see above for info) */
67 #define ROTE_ATTR_XBG(attr)             ((attr) & 0x0F)
68 #define ROTE_ATTR_XFG(attr)             (((attr) & 0xF0) >> 4)
69
70 /* set attribute fields. This requires attr to be an lvalue, and it will
71  * be evaluated more than once. Use with care. */
72 #define ROTE_ATTR_MOD_BG(attr, newbg)    attr &= 0xF8, attr |= (newbg)
73 #define ROTE_ATTR_MOD_FG(attr, newfg)    attr &= 0x8F, attr |= ((newfg) << 4)
74 #define ROTE_ATTR_MOD_XBG(attr, newxbg)  attr &= 0xF0, attr |= (newxbg)
75 #define ROTE_ATTR_MOD_XFG(attr, newxfg)  attr &= 0x0F, attr |= ((newxfg) << 4)
76 #define ROTE_ATTR_MOD_BOLD(attr, boldbit) \
77     attr &= 0x7F, attr |= (boldbit)?0x80:0x00
78 #define ROTE_ATTR_MOD_BLINK(attr, blinkbit) \
79     attr &= 0xF7, attr |= (blinkbit)?0x08:0x00
80
81 /* these return non-zero for 'yes', zero for 'no'. Don't rely on them being 
82  * any more specific than that (e.g. being exactly 1 for 'yes' or whatever). */
83 #define ROTE_ATTR_BOLD(attr)            ((attr) & 0x80)
84 #define ROTE_ATTR_BLINK(attr)           ((attr) & 0x08)
85
86 /* Represents each of the text cells in the terminal screen */
87 typedef struct RoteCell_ {
88     unsigned char ch;    /* >= 32, that is, control characters are not
89                           * allowed to be on the virtual screen */
90
91     unsigned char attr;  /* a color attribute, as described previously */
92 } RoteCell;
93
94 /* Declaration of opaque rote_Term_Private structure */
95 typedef struct RoteTermPrivate_ RoteTermPrivate;
96
97 /* Represents a virtual terminal. You may directly access the fields
98  * of this structure, but please pay close attention to the fields
99  * marked read-only or with special usage notes. */
100 typedef struct RoteTerm_ {
101     int rows, cols;              /* terminal dimensions, READ-ONLY. You
102                                   * can't resize the terminal by changing
103                                   * this (a segfault is about all you will 
104                                   * accomplish). */
105
106     RoteCell **cells;            /* matrix of cells. This
107                                   * matrix is indexed as cell[row][column]
108                                   * where 0 <= row < rows and
109                                   *       0 <= col < cols
110                                   *
111                                   * You may freely modify the contents of
112                                   * the cells.
113                                   */
114
115     int crow, ccol;              /* cursor coordinates. READ-ONLY. */
116
117     unsigned char curattr;       /* current attribute, that is the attribute
118                                   * that will be used for newly inserted
119                                   * characters */
120
121     int   pty;                   /* pty of the process */
122     pid_t childpid;              /* pid of the child process running in the
123                                   * terminal; 0 for none. This is READ-ONLY. */
124
125     RoteTermPrivate *pd;         /* private state data */
126
127     bool insert;                 /* insert or replace mode */
128     /* --- dirtiness flags: the following flags will be raised when the
129      * corresponding items are modified. They can only be unset by YOU
130      * (when, for example, you redraw the term or something) --- */
131     bool curpos_dirty;           /* whether cursor location has changed */
132     bool *line_dirty;            /* whether each row is dirty  */
133     /* --- end dirtiness flags */
134 } RoteTerm;
135
136 /* Creates a new virtual terminal with the given dimensions. You
137  * must destroy it with rote_vt_destroy after you are done with it.
138  * The terminal will be initially blank and the cursor will
139  * be at the top-left corner. 
140  *
141  * Returns NULL on error.
142  */
143 RoteTerm *rote_vt_create(int rows, int cols);
144
145 /* Destroys a virtual terminal previously created with
146  * rote_vt_create. If rt == NULL, does nothing. */
147 void rote_vt_destroy(RoteTerm *rt);
148
149 /* Starts a forked process in the terminal. The <command> parameter
150  * is a shell command to execute (it will be interpreted by '/bin/sh -c') 
151  * Returns the pid of the forked process. 
152  *
153  * Some useful reminders: If you want to be notified when child processes exit,
154  * you should handle the SIGCHLD signal.  If, on the other hand, you want to
155  * ignore exitting child processes, you should set the SIGCHLD handler to
156  * SIG_IGN to prevent child processes from hanging around the system as 'zombie
157  * processes'. 
158  *
159  * Continuing to write to a RoteTerm whose child process has died does not
160  * accomplish a lot, but is not an error and should not cause your program
161  * to crash or block indefinitely or anything of that sort :-)
162  * If, however, you want to be tidy and inform the RoteTerm that its
163  * child has died, call rote_vt_forsake_child when appropriate.
164  *
165  * If there is an error, returns -1. Notice that passing an invalid
166  * command will not cause an error at this level: the shell will try
167  * to execute the command and will exit with status 127. You can catch
168  * that by installing a SIGCHLD handler if you want.
169  */
170 pid_t rote_vt_forkpty(RoteTerm *rt, const char *path, const char *argv[]);
171
172 /* Disconnects the RoteTerm from its forked child process. This function
173  * should be called when the child process dies or something of the sort.
174  * It is not strictly necessary to call this function, but it is
175  * certainly tidy. */
176 void rote_vt_forsake_child(RoteTerm *rt);
177
178 /* Does some data plumbing, that is, sees if the sub process has
179  * something to write to the terminal, and if so, write it. If you
180  * called rote_vt_fork to start a forked process, you must call
181  * this function regularly to update the terminal. 
182  *
183  * This function will not block, that is, if there is no data to be
184  * read from the child process it will return immediately. */
185 void rote_vt_update(RoteTerm *rt);
186
187 int rote_vt_read(RoteTerm *rt, char *buf, int buflen);
188
189 /* Puts data into the terminal: if there is a forked process running,
190  * the data will be sent to it. If there is no forked process,
191  * the data will simply be injected into the terminal (as in
192  * rote_vt_inject) */
193 void rote_vt_write(RoteTerm *rt, const char *data, int length);
194
195 /* Inject data into the terminal. <data> needs NOT be 0-terminated:
196  * its length is solely determined by the <length> parameter. Please
197  * notice that this writes directly to the terminal, that is,
198  * this function does NOT send the data to the forked process
199  * running in the terminal (if any). For that, you might want
200  * to use rote_vt_write.
201  */
202 void rote_vt_inject(RoteTerm *rt, const char *data, int length);
203
204 #ifdef USE_NCURSES
205 /* Paints the virtual terminal screen on the given window, putting
206  * the top-left corner at the given position. The cur_set_attr
207  * function must set the curses attributes given a Rote attribute
208  * byte. It should, for example, do wattrset(win, COLOR_PAIR(n)) where
209  * n is the colorpair appropriate for the attribute and such.
210  *
211  * If you pass NULL for cur_set_attr, the default implementation will
212  * set the color pair given by (bg * 8 + 7 - fg), which seems to be
213  * a common mapping, and the bold and blink attributes will be mapped 
214  * to A_BOLD and A_BLINK.
215  *
216  * At the end of the function, the cursor will be left where the virtual 
217  * cursor of the terminal is supposed to be.
218  *
219  * This function does not call wrefresh(win); you have to do that yourself.
220  * This function automatically calls rote_vt_update prior to drawing
221  * so that the drawn contents are accurate.
222  */
223 void rote_vt_draw(RoteTerm *rt, WINDOW *win, int startrow, int startcol,
224                   void (*cur_set_attr)(WINDOW *win, unsigned char attr));
225
226 #endif
227 /* Indicates to the terminal that the given key has been pressed.
228  * This will cause the terminal to rote_vt_write() the appropriate
229  * escape sequence for that key (that is, the escape sequence
230  * that the linux text-mode console would produce for it). The argument,
231  * keycode, must be a CURSES EXTENDED KEYCODE, the ones you get
232  * when you use keypad(somewin, TRUE) (see man page). */
233 void rote_vt_keypress(RoteTerm *rt, int keycode);
234
235 /* Takes a snapshot of the current contents of the terminal and
236  * saves them to a dynamically allocated buffer. Returns a pointer
237  * to the newly created buffer, which you can pass to
238  * rote_vt_restore_snapshot. Caller is responsible for free()'ing when
239  * the snapshot is no longer needed. */
240 void *rote_vt_take_snapshot(RoteTerm *rt);
241
242 /* Restores a snapshot previously taken with rote_vt_take_snapshot.
243  * This function does NOT free() the passed buffer */
244 void rote_vt_restore_snapshot(RoteTerm *rt, void *snapbuf);
245
246 #endif /* MADTTY_MADTTY_H */