many many updates
[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 #include <ncursesw/curses.h>
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31
32 /* Color codes: 0 = black, 1 = red, 2 = green, 3 = yellow, 4 = blue,
33  *              5 = magenta, 6 = cyan, 7 = white. 
34  *
35  * An 'attribute' as used in this library means an 8-bit value that conveys
36  * a foreground color code, a background color code, and the bold
37  * and blink bits. Each cell in the virtual terminal screen is associated
38  * with an attribute that specifies its appearance. The bits of an attribute,
39  * from most significant to least significant, are 
40  *
41  *  bit:      7 6 5 4 3 2 1 0
42  *  content:  S F F F H B B B
43  *            | `-,-' | `-,-'
44  *            |   |   |   |
45  *            |   |   |   `----- 3-bit background color code (0 - 7)
46  *            |   |   `--------- blink bit (if on, text is blinking)
47  *            |   `------------- 3-bit foreground color code (0 - 7)
48  *            `----------------- bold bit
49  *
50  * It is however recommended that you use the provided macros rather
51  * than dealing with this format directly.
52  *
53  * Sometimes we will call the 'SFFF' nibble above the 'extended
54  * foreground color code', and the 'HBBB' nibble the 'extended background
55  * color code'. So the extended color codes are just the regular
56  * color codes except that they have an additional bit (the most significant
57  * bit) indicating bold/blink.
58  */
59
60 /* retrieve attribute fields */
61 #define ROTE_ATTR_BG(attr)              ((attr) & 0x07)
62 #define ROTE_ATTR_FG(attr)              (((attr) & 0x70) >> 4)
63
64 /* retrieve 'extended' color codes (see above for info) */
65 #define ROTE_ATTR_XBG(attr)             ((attr) & 0x0F)
66 #define ROTE_ATTR_XFG(attr)             (((attr) & 0xF0) >> 4)
67
68 /* set attribute fields. This requires attr to be an lvalue, and it will
69  * be evaluated more than once. Use with care. */
70 #define ROTE_ATTR_MOD_BG(attr, newbg)    attr &= 0xF8, attr |= (newbg)
71 #define ROTE_ATTR_MOD_FG(attr, newfg)    attr &= 0x8F, attr |= ((newfg) << 4)
72 #define ROTE_ATTR_MOD_XBG(attr, newxbg)  attr &= 0xF0, attr |= (newxbg)
73 #define ROTE_ATTR_MOD_XFG(attr, newxfg)  attr &= 0x0F, attr |= ((newxfg) << 4)
74 #define ROTE_ATTR_MOD_BOLD(attr, boldbit) \
75     attr &= 0x7F, attr |= (boldbit)?0x80:0x00
76 #define ROTE_ATTR_MOD_BLINK(attr, blinkbit) \
77     attr &= 0xF7, attr |= (blinkbit)?0x08:0x00
78
79 /* these return non-zero for 'yes', zero for 'no'. Don't rely on them being 
80  * any more specific than that (e.g. being exactly 1 for 'yes' or whatever). */
81 #define ROTE_ATTR_BOLD(attr)            ((attr) & 0x80)
82 #define ROTE_ATTR_BLINK(attr)           ((attr) & 0x08)
83
84 /* Represents each of the text cells in the terminal screen */
85 typedef struct RoteCell_ {
86     char s[4];
87     char len;
88     uint8_t attr;  /* a color attribute, as described previously */
89 } RoteCell;
90
91 /* Declaration of opaque rote_Term_Private structure */
92 typedef struct RoteTermPrivate_ RoteTermPrivate;
93
94 /* Represents a virtual terminal. You may directly access the fields
95  * of this structure, but please pay close attention to the fields
96  * marked read-only or with special usage notes. */
97 typedef struct RoteTerm_ {
98     int rows, cols;              /* terminal dimensions, READ-ONLY. You
99                                   * can't resize the terminal by changing
100                                   * this (a segfault is about all you will 
101                                   * accomplish). */
102
103     RoteCell **cells;            /* matrix of cells. This
104                                   * matrix is indexed as cell[row][column]
105                                   * where 0 <= row < rows and
106                                   *       0 <= col < cols
107                                   *
108                                   * You may freely modify the contents of
109                                   * the cells.
110                                   */
111
112     int crow, ccol;              /* cursor coordinates. READ-ONLY. */
113
114     uint8_t curattr;             /* current attribute, that is the attribute
115                                   * that will be used for newly inserted
116                                   * characters */
117
118     int   pty;                   /* pty of the process */
119     pid_t childpid;              /* pid of the child process running in the
120                                   * terminal; 0 for none. This is READ-ONLY. */
121
122     RoteTermPrivate *pd;         /* private state data */
123
124     unsigned insert : 1;         /* insert or replace mode */
125
126     /* --- dirtiness flags: the following flags will be raised when the
127      * corresponding items are modified. They can only be unset by YOU
128      * (when, for example, you redraw the term or something) --- */
129     unsigned curpos_dirty : 1;   /* whether cursor location has changed */
130     bool *line_dirty;            /* whether each row is dirty  */
131     /* --- end dirtiness flags */
132 } RoteTerm;
133
134 /* Creates a new virtual terminal with the given dimensions. You
135  * must destroy it with rote_vt_destroy after you are done with it.
136  * The terminal will be initially blank and the cursor will
137  * be at the top-left corner. 
138  *
139  * Returns NULL on error.
140  */
141 RoteTerm *rote_vt_create(int rows, int cols);
142
143 /* Destroys a virtual terminal previously created with
144  * rote_vt_create. If rt == NULL, does nothing. */
145 void rote_vt_destroy(RoteTerm *rt);
146
147 /* Starts a forked process in the terminal. The <command> parameter
148  * is a shell command to execute (it will be interpreted by '/bin/sh -c') 
149  * Returns the pid of the forked process. 
150  *
151  * Some useful reminders: If you want to be notified when child processes exit,
152  * you should handle the SIGCHLD signal.  If, on the other hand, you want to
153  * ignore exitting child processes, you should set the SIGCHLD handler to
154  * SIG_IGN to prevent child processes from hanging around the system as 'zombie
155  * processes'. 
156  *
157  * Continuing to write to a RoteTerm whose child process has died does not
158  * accomplish a lot, but is not an error and should not cause your program
159  * to crash or block indefinitely or anything of that sort :-)
160  * If, however, you want to be tidy and inform the RoteTerm that its
161  * child has died, call rote_vt_forsake_child when appropriate.
162  *
163  * If there is an error, returns -1. Notice that passing an invalid
164  * command will not cause an error at this level: the shell will try
165  * to execute the command and will exit with status 127. You can catch
166  * that by installing a SIGCHLD handler if you want.
167  */
168 pid_t rote_vt_forkpty(RoteTerm *rt, const char *path, const char *argv[]);
169
170 int rote_vt_read(RoteTerm *rt, char *buf, int buflen);
171 int rote_vt_write(RoteTerm *rt, const char *data, int length);
172
173 /* Inject data into the terminal. <data> needs NOT be 0-terminated:
174  * its length is solely determined by the <length> parameter. Please
175  * notice that this writes directly to the terminal, that is,
176  * this function does NOT send the data to the forked process
177  * running in the terminal (if any). For that, you might want
178  * to use rote_vt_write.
179  */
180 int rote_vt_inject(RoteTerm *rt, const char *data, int length);
181 void rote_vt_draw(RoteTerm *rt, WINDOW *win, int startrow, int startcol);
182
183 /* Indicates to the terminal that the given key has been pressed.
184  * This will cause the terminal to rote_vt_write() the appropriate
185  * escape sequence for that key (that is, the escape sequence
186  * that the linux text-mode console would produce for it). The argument,
187  * keycode, must be a CURSES EXTENDED KEYCODE, the ones you get
188  * when you use keypad(somewin, TRUE) (see man page). */
189 void rote_vt_keypress(RoteTerm *rt, int keycode);
190
191 #endif /* MADTTY_MADTTY_H */