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.
7 Please refer to the COPYING file for more information.
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.
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
18 Copyright © 2004 Bruno T. C. de Oliveira
19 Copyright © 2006 Pierre Habouzit
22 #ifndef MADTTY_MADTTY_H
23 #define MADTTY_MADTTY_H
25 #include <ncursesw/curses.h>
29 #include <sys/types.h>
32 /* Color codes: 0 = black, 1 = red, 2 = green, 3 = yellow, 4 = blue,
33 * 5 = magenta, 6 = cyan, 7 = white.
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
41 * bit: 7 6 5 4 3 2 1 0
42 * content: S F F F H B B B
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
50 * It is however recommended that you use the provided macros rather
51 * than dealing with this format directly.
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.
60 /* retrieve attribute fields */
61 #define ROTE_ATTR_BG(attr) ((attr) & 0x07)
62 #define ROTE_ATTR_FG(attr) (((attr) & 0x70) >> 4)
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)
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
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)
84 /* Represents each of the text cells in the terminal screen */
85 typedef struct RoteCell_ {
88 uint8_t attr; /* a color attribute, as described previously */
91 /* Declaration of opaque rote_Term_Private structure */
92 typedef struct RoteTermPrivate_ RoteTermPrivate;
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
103 RoteCell **cells; /* matrix of cells. This
104 * matrix is indexed as cell[row][column]
105 * where 0 <= row < rows and
108 * You may freely modify the contents of
112 int crow, ccol; /* cursor coordinates. READ-ONLY. */
114 uint8_t curattr; /* current attribute, that is the attribute
115 * that will be used for newly inserted
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. */
122 RoteTermPrivate *pd; /* private state data */
124 unsigned insert : 1; /* insert or replace mode */
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 */
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.
139 * Returns NULL on error.
141 RoteTerm *rote_vt_create(int rows, int cols);
143 /* Destroys a virtual terminal previously created with
144 * rote_vt_create. If rt == NULL, does nothing. */
145 void rote_vt_destroy(RoteTerm *rt);
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.
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
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.
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.
168 pid_t rote_vt_forkpty(RoteTerm *rt, const char *path, const char *argv[]);
170 int rote_vt_read(RoteTerm *rt, char *buf, int buflen);
171 int rote_vt_write(RoteTerm *rt, const char *data, int length);
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.
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);
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);
191 #endif /* MADTTY_MADTTY_H */