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
30 // ////////////////////////////////////////////////////////////////////////// //
31 // the cell buffer will never be less than this
32 // it doesn't matter if it cannot fit into the window
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)
43 #define CMODE_GREEN (2)
44 #define CMODE_AMBER (3)
45 #define CMODE_AMBER_TINT (4)
50 #define CIDX_DEFAULT_FG (256)
51 #define CIDX_DEFAULT_BG (257)
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)
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)
94 #define CELL_INVERSE (0x0001U)
95 #define CELL_UNDERLINE (0x0002U)
96 #define CELL_BOLD (0x0004U)
97 #define CELL_BLINK (0x0008U)
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)
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
114 uint32_t fg
; // rgb color
115 uint32_t bg
; // rgb color
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
127 int width
; // never zero
128 int height
; // never zero
129 CharCell
*buf
; // current buffer, and temp buffer
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
);
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
);