added "amber tint" mode for selection (default)
[yterm.git] / src / cellwin.h
blob6fb20ad9977e7346d92c8240174a6a3c4b211642
1 /*
2 * YTerm -- (mostly) GNU/Linux X11 terminal emulator
4 * Simple cell (character) windows
6 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
7 * Understanding is not required. Only obedience.
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, version 3 of the License ONLY.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * this module implements character cell buffer and subwindows in it
24 #ifndef YTERM_HEADER_CELL_WINDOW
25 #define YTERM_HEADER_CELL_WINDOW
27 #include "common.h"
30 // ////////////////////////////////////////////////////////////////////////// //
31 // the cell buffer will never be less than this
32 // it doesn't matter if it cannot fit into the window
33 // just because
34 #define MinBufferWidth (1)
35 #define MinBufferHeight (1)
36 // ...and will never be higher than this
37 #define MaxBufferWidth (32767)
38 #define MaxBufferHeight (32767)
41 #define CMODE_NORMAL (0)
42 #define CMODE_BW (1)
43 #define CMODE_GREEN (2)
44 #define CMODE_AMBER (3)
45 #define CMODE_AMBER_TINT (4)
47 extern int colorMode;
50 #define CIDX_DEFAULT_FG (256)
51 #define CIDX_DEFAULT_BG (257)
53 // high-intensity
54 #define CIDX_DEFAULT_HIGH_FG (258)
55 #define CIDX_DEFAULT_HIGH_BG (259)
57 // indicies for special colors (foreground only)
58 #define CIDX_BOLD_FG (260)
59 #define CIDX_UNDER_FG (261)
60 #define CIDX_BOLD_UNDER_FG (262)
61 // with blink set
62 #define CIDX_BOLD_HIGH_FG (263)
63 #define CIDX_UNDER_HIGH_FG (264)
64 #define CIDX_BOLD_UNDER_HIGH_FG (265)
66 #define CIDX_MAX (265)
68 extern uint32_t colorsTTY[CIDX_MAX + 1];
69 extern uint32_t colorSelectionFG;
70 extern uint32_t colorSelectionBG;
71 // amber mode is used when selection mode is active
72 extern uint32_t colorAmberFG;
73 extern uint32_t colorAmberBG;
75 // draw underlines when we cannot use attrs?
76 extern yterm_bool enableUnderline;
78 // invert inverse flag ;-)
79 extern yterm_bool cbufInverse;
81 // init default palette
82 void cbuf_init_palette (void);
85 // ////////////////////////////////////////////////////////////////////////// //
86 // if `&CELL_ATTR_MASK` is not zero, this is TTY color, not rgb
87 // TTY color `0xffffU` is "default"
88 #define CELL_RGB_MASK (0x00ffffffU)
89 #define CELL_ATTR_MASK (0xff000000U)
91 #define CELL_DEFAULT_ATTR (0xffffU)
93 // cells flags
94 #define CELL_INVERSE (0x0001U)
95 #define CELL_UNDERLINE (0x0002U)
96 #define CELL_BOLD (0x0004U)
97 #define CELL_BLINK (0x0008U)
98 // selection
99 #define CELL_SELECTION (0x0100U)
100 // set if this line was automatically wrapped around.
101 // has any sense only for the last char.
102 #define CELL_AUTO_WRAP (0x4000U)
103 // dirty flag
104 #define CELL_DIRTY (0x8000U)
107 #define CELL_STD_COLOR(c_) ((uint32_t)(c_)|CELL_ATTR_MASK)
110 // history buffer will compress lines with the same attrs
111 typedef struct YTERM_PACKED {
112 uint16_t ch; // unicrap char
113 uint16_t flags;
114 uint32_t fg; // rgb color
115 uint32_t bg; // rgb color
116 } CharCell;
119 // cell buffer contains two copies of the screen
120 // the first copy is the one where we're doing all rendering, and
121 // the second copy is what was rendered last time
122 // this way no matter how many times the contents of the first copy
123 // was changed, the backend only have to re-render what was truly changed
124 // the backend is responsible for syncing copies when rendering, and for
125 // keeping `dirty_chars` valid
126 typedef struct {
127 int width; // never zero
128 int height; // never zero
129 CharCell *buf; // current buffer, and temp buffer
130 int dirtyCount;
131 } CellBuffer;
134 // ////////////////////////////////////////////////////////////////////////// //
135 // initialize cell buffer, allocate cells
136 void cbuf_new (CellBuffer *cbuf, int nwidth, int nheight);
137 // free cell buffer cells, zero out `*cbuf`
138 void cbuf_free (CellBuffer *cbuf);
140 // resize cell buffer
141 void cbuf_resize (CellBuffer *cbuf, int nwidth, int nheight, yterm_bool relayout);
144 // ////////////////////////////////////////////////////////////////////////// //
145 YTERM_STATIC_INLINE CharCell *cbuf_cell_at (CellBuffer *cbuf, int x, int y) {
146 return (cbuf && x >= 0 && y >= 0 && x < cbuf->width && y < cbuf->height ?
147 &cbuf->buf[y * cbuf->width + x] : NULL);
151 // ////////////////////////////////////////////////////////////////////////// //
152 // all output pointers should be non-NULL
153 void cbuf_decode_attrs (const CharCell *cc, uint32_t *fg, uint32_t *bg, yterm_bool *under);
155 void cbuf_set_cell_defaults (CharCell *cell);
158 // ////////////////////////////////////////////////////////////////////////// //
159 // region is inclusive
160 void cbuf_mark_region_dirty (CellBuffer *cbuf, int x0, int y0, int x1, int y1);
161 void cbuf_mark_region_clean (CellBuffer *cbuf, int x0, int y0, int x1, int y1);
163 void cbuf_mark_line_autowrap (CellBuffer *cbuf, int y);
164 void cbuf_unmark_line_autowrap (CellBuffer *cbuf, int y);
166 // this is called on screen switching.
167 // only non-dirty and totally unchanged cells will remain non-dirty.
168 void cbuf_merge_all_dirty (CellBuffer *cbuf, const CellBuffer *sbuf);
170 YTERM_STATIC_INLINE void cbuf_mark_dirty (CellBuffer *cbuf, int x, int y) {
171 cbuf_mark_region_dirty(cbuf, x, y, x, y);
174 YTERM_STATIC_INLINE void cbuf_mark_line_dirty (CellBuffer *cbuf, int y) {
175 if (cbuf != NULL) cbuf_mark_region_dirty(cbuf, 0, y, cbuf->width - 1, y);
178 YTERM_STATIC_INLINE void cbuf_mark_all_dirty (CellBuffer *cbuf) {
179 if (cbuf != NULL) cbuf_mark_region_dirty(cbuf, 0, 0, cbuf->width - 1, cbuf->height - 1);
182 YTERM_STATIC_INLINE void cbuf_mark_all_clean (CellBuffer *cbuf) {
183 if (cbuf != NULL) cbuf_mark_region_clean(cbuf, 0, 0, cbuf->width - 1, cbuf->height - 1);
187 // ////////////////////////////////////////////////////////////////////////// //
188 // if `attr` is `NULL`, use default colors.
189 void cbuf_write_wchar_count (CellBuffer *cbuf, int x, int y, uint32_t ch,
190 int count, const CharCell *attr);
192 YTERM_STATIC_INLINE void cbuf_write_wchar (CellBuffer *cbuf, int x, int y, uint32_t ch,
193 const CharCell *attr)
195 cbuf_write_wchar_count(cbuf, x, y, ch, 1, attr);
199 // ////////////////////////////////////////////////////////////////////////// //
200 // if `attr` is `NULL`, use default colors.
201 void cbuf_write_str_utf (CellBuffer *cbuf, int x, int y, const char *str, const CharCell *attr);
203 enum {
204 CBUF_DIRTY_OVERWRITE = 0,
205 CBUF_DIRTY_MERGE = 1,
208 // vertical area scroll.
209 // will scroll the region from `y0` to `y1` (inclusive).
210 // dirty flags will be copied.
211 // it is caller's responsibility to clear new lines.
212 // `merge_dirty` tells if dirty state should be merged, or overwritten.
213 // `dir` is `-1` or `1` (actually, positive or negative).
214 // if `attr` is `NULL`, do not clear scrolled out region.
215 // `attr->ch` will be used as fill char.
216 void cbuf_scroll_area (CellBuffer *cbuf, int y0, int y1, int lines,
217 int dir, yterm_bool merge_dirty, const CharCell *attr);
219 YTERM_STATIC_INLINE void cbuf_scroll_area_up (CellBuffer *cbuf, int y0, int y1, int lines,
220 yterm_bool merge_dirty, const CharCell *attr)
222 cbuf_scroll_area(cbuf, y0, y1, lines, -1, merge_dirty, attr);
225 YTERM_STATIC_INLINE void cbuf_scroll_area_down (CellBuffer *cbuf, int y0, int y1, int lines,
226 yterm_bool merge_dirty, const CharCell *attr)
228 cbuf_scroll_area(cbuf, y0, y1, lines, 1, merge_dirty, attr);
231 // region is inclusive.
232 // if `attr` is `NULL`, use default colors and space.
233 // `attr->ch` will be used as fill char.
234 void cbuf_clear_region (CellBuffer *cbuf, int x0, int y0, int x1, int y1,
235 const CharCell *attr);
237 // insert blank chars into line.
238 // if `attr` is `NULL`, use default colors and space.
239 // `attr->ch` will be used as fill char.
240 void cbuf_insert_chars (CellBuffer *cbuf, int x, int y, int count, const CharCell *attr);
242 // delete blank chars from line.
243 // if `attr` is `NULL`, use default colors and space.
244 // `attr->ch` will be used as fill char.
245 void cbuf_delete_chars (CellBuffer *cbuf, int x, int y, int count, const CharCell *attr);
248 // ////////////////////////////////////////////////////////////////////////// //
249 // region is inclusive.
250 // copy region from `srcbuf` to `cbuf`
251 // perform proper cliping; out-ouf-bounds cells will not be copied.
252 // this correctly sets dirty status of `cbuf` (source dirty status is ignored).
253 void cbuf_copy_region (CellBuffer *cbuf, int destx, int desty,
254 const CellBuffer *srcbuf, int x0, int y0, int x1, int y1);
257 // ////////////////////////////////////////////////////////////////////////// //
258 void cbuf_merge_cell (CellBuffer *cbuf, int x, int y, const CharCell *cell);
261 #endif