source: mainline/uspace/lib/c/generic/io/chargrid.c@ 6feccae

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6feccae was 68f1254c, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Terminal/console need to handle invalid coordinates

chargrid_set_cursor asserted that arguments are valid yet they are passed
directly from client by terminal/console. Chargrid is probably best
positioned to validate the agruments so instead of assert, check
the arguments and don't do anything if they are invalid.

tinput was clearly forgetting about some cases where the screen could have
scrolled so simply call tinput_update_origin every time from
tinput_position_caret. This was happenning when the input line was
longer than one screen row and tab completion was invoked
(which caused assertion failure in chargrid).

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*
2 * Copyright (c) 2006 Josef Cejka
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file
33 */
34
35#include <io/style.h>
36#include <stdlib.h>
37#include <assert.h>
38#include <stdbool.h>
39#include <stddef.h>
40#include <as.h>
41#include <io/chargrid.h>
42
43/** Create a chargrid.
44 *
45 * @param[in] cols Number of columns.
46 * @param[in] rows Number of rows.
47 * @param[in] flags Chargrid flags.
48 *
49 * @return New chargrid.
50 * @return NULL on failure.
51 *
52 */
53chargrid_t *chargrid_create(sysarg_t cols, sysarg_t rows,
54 chargrid_flag_t flags)
55{
56 size_t size =
57 sizeof(chargrid_t) + cols * rows * sizeof(charfield_t);
58 chargrid_t *scrbuf;
59
60 if ((flags & CHARGRID_FLAG_SHARED) == CHARGRID_FLAG_SHARED) {
61 scrbuf = (chargrid_t *) as_area_create(AS_AREA_ANY, size,
62 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
63 AS_AREA_UNPAGED);
64 if (scrbuf == AS_MAP_FAILED)
65 return NULL;
66 } else {
67 scrbuf = (chargrid_t *) malloc(size);
68 if (scrbuf == NULL)
69 return NULL;
70 }
71
72 scrbuf->size = size;
73 scrbuf->flags = flags;
74 scrbuf->cols = cols;
75 scrbuf->rows = rows;
76 scrbuf->cursor_visible = false;
77
78 scrbuf->attrs.type = CHAR_ATTR_STYLE;
79 scrbuf->attrs.val.style = STYLE_NORMAL;
80
81 scrbuf->top_row = 0;
82 chargrid_clear(scrbuf);
83
84 return scrbuf;
85}
86
87void chargrid_destroy(chargrid_t *srcbuf)
88{
89 // TODO
90}
91
92bool chargrid_cursor_at(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
93{
94 return ((scrbuf->cursor_visible) && (scrbuf->col == col) &&
95 (scrbuf->row == row));
96}
97
98sysarg_t chargrid_get_top_row(chargrid_t *scrbuf)
99{
100 return scrbuf->top_row;
101}
102
103static sysarg_t chargrid_update_rows(chargrid_t *scrbuf)
104{
105 if (scrbuf->row == scrbuf->rows) {
106 scrbuf->row = scrbuf->rows - 1;
107 scrbuf->top_row = (scrbuf->top_row + 1) % scrbuf->rows;
108 chargrid_clear_row(scrbuf, scrbuf->row);
109
110 return scrbuf->rows;
111 }
112
113 return 2;
114}
115
116static sysarg_t chargrid_update_cols(chargrid_t *scrbuf)
117{
118 /* Column overflow */
119 if (scrbuf->col == scrbuf->cols) {
120 scrbuf->col = 0;
121 scrbuf->row++;
122 return chargrid_update_rows(scrbuf);
123 }
124
125 return 1;
126}
127
128/** Store one character to chargrid.
129 *
130 * Its position is determined by scrbuf->col
131 * and scrbuf->row.
132 *
133 * @param scrbuf Chargrid.
134 * @param ch Character to store.
135 * @param update Update coordinates.
136 *
137 * @return Number of rows which have been affected. In usual
138 * situations this is 1. If the current position was
139 * updated to a new row, this value is 2.
140 *
141 */
142sysarg_t chargrid_putwchar(chargrid_t *scrbuf, wchar_t ch, bool update)
143{
144 assert(scrbuf->col < scrbuf->cols);
145 assert(scrbuf->row < scrbuf->rows);
146
147 charfield_t *field =
148 chargrid_charfield_at(scrbuf, scrbuf->col, scrbuf->row);
149
150 field->ch = ch;
151 field->attrs = scrbuf->attrs;
152 field->flags |= CHAR_FLAG_DIRTY;
153
154 if (update) {
155 scrbuf->col++;
156 return chargrid_update_cols(scrbuf);
157 }
158
159 return 1;
160}
161
162/** Jump to a new row in chargrid.
163 *
164 * @param scrbuf Chargrid.
165 *
166 * @return Number of rows which have been affected. In usual
167 * situations this is 2 (the original row and the new
168 * row).
169 *
170 */
171sysarg_t chargrid_newline(chargrid_t *scrbuf)
172{
173 assert(scrbuf->col < scrbuf->cols);
174 assert(scrbuf->row < scrbuf->rows);
175
176 scrbuf->col = 0;
177 scrbuf->row++;
178
179 return chargrid_update_rows(scrbuf);
180}
181
182/** Jump to a new row in chargrid.
183 *
184 * @param scrbuf Chargrid.
185 * @param tab_size Tab size.
186 *
187 * @return Number of rows which have been affected. In usual
188 * situations this is 1. If the current position was
189 * updated to a new row, this value is 2.
190 *
191 */
192sysarg_t chargrid_tabstop(chargrid_t *scrbuf, sysarg_t tab_size)
193{
194 assert(scrbuf->col < scrbuf->cols);
195 assert(scrbuf->row < scrbuf->rows);
196
197 sysarg_t spaces = tab_size - scrbuf->cols % tab_size;
198 sysarg_t flush = 1;
199
200 for (sysarg_t i = 0; i < spaces; i++)
201 flush += chargrid_putwchar(scrbuf, ' ', true) - 1;
202
203 return flush;
204}
205
206/** Jump to the previous character in chargrid.
207 *
208 * Currently no scrollback is supported.
209 *
210 * @param scrbuf Chargrid.
211 *
212 * @return Number of rows which have been affected. In usual
213 * situations this is 1. If the current position was
214 * updated to the previous row, this value is 2.
215 * @return 0 if no backspace is possible.
216 *
217 */
218sysarg_t chargrid_backspace(chargrid_t *scrbuf)
219{
220 assert(scrbuf->col < scrbuf->cols);
221 assert(scrbuf->row < scrbuf->rows);
222
223 if ((scrbuf->col == 0) && (scrbuf->row == 0))
224 return 0;
225
226 if (scrbuf->col == 0) {
227 scrbuf->col = scrbuf->cols - 1;
228 scrbuf->row--;
229
230 chargrid_putwchar(scrbuf, ' ', false);
231 return 2;
232 }
233
234 scrbuf->col--;
235 chargrid_putwchar(scrbuf, ' ', false);
236 return 1;
237}
238
239/** Clear the chargrid.
240 *
241 * @param scrbuf Chargrid.
242 *
243 */
244void chargrid_clear(chargrid_t *scrbuf)
245{
246 for (size_t pos = 0; pos < (scrbuf->cols * scrbuf->rows); pos++) {
247 scrbuf->data[pos].ch = 0;
248 scrbuf->data[pos].attrs = scrbuf->attrs;
249 scrbuf->data[pos].flags = CHAR_FLAG_DIRTY;
250 }
251
252 scrbuf->col = 0;
253 scrbuf->row = 0;
254}
255
256/** Update current chargrid coordinates
257 *
258 * @param scrbuf Chargrid.
259 * @param col New column.
260 * @param row New row.
261 *
262 */
263void chargrid_set_cursor(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
264{
265 if (col >= scrbuf->cols || row >= scrbuf->rows)
266 return;
267
268 scrbuf->col = col;
269 scrbuf->row = row;
270}
271
272void chargrid_set_cursor_visibility(chargrid_t *scrbuf, bool visible)
273{
274 scrbuf->cursor_visible = visible;
275}
276
277/** Get current chargrid coordinates
278 *
279 * @param scrbuf Chargrid.
280 * @param col Column.
281 * @param row Row.
282 *
283 */
284void chargrid_get_cursor(chargrid_t *scrbuf, sysarg_t *col,
285 sysarg_t *row)
286{
287 assert(col);
288 assert(row);
289
290 *col = scrbuf->col;
291 *row = scrbuf->row;
292}
293
294bool chargrid_get_cursor_visibility(chargrid_t *scrbuf)
295{
296 return scrbuf->cursor_visible;
297}
298
299/** Clear one buffer row.
300 *
301 * @param scrbuf Chargrid.
302 * @param row Row to clear.
303 *
304 */
305void chargrid_clear_row(chargrid_t *scrbuf, sysarg_t row)
306{
307 for (sysarg_t col = 0; col < scrbuf->cols; col++) {
308 charfield_t *field =
309 chargrid_charfield_at(scrbuf, col, row);
310
311 field->ch = 0;
312 field->attrs = scrbuf->attrs;
313 field->flags |= CHAR_FLAG_DIRTY;
314 }
315}
316
317/** Set chargrid style.
318 *
319 * @param scrbuf Chargrid.
320 * @param style Style.
321 *
322 */
323void chargrid_set_style(chargrid_t *scrbuf, console_style_t style)
324{
325 scrbuf->attrs.type = CHAR_ATTR_STYLE;
326 scrbuf->attrs.val.style = style;
327}
328
329/** Set chargrid color.
330 *
331 * @param scrbuf Chargrid.
332 * @param bgcolor Background color.
333 * @param fgcolor Foreground color.
334 * @param attr Color attribute.
335 *
336 */
337void chargrid_set_color(chargrid_t *scrbuf, console_color_t bgcolor,
338 console_color_t fgcolor, console_color_attr_t attr)
339{
340 scrbuf->attrs.type = CHAR_ATTR_INDEX;
341 scrbuf->attrs.val.index.bgcolor = bgcolor;
342 scrbuf->attrs.val.index.fgcolor = fgcolor;
343 scrbuf->attrs.val.index.attr = attr;
344}
345
346/** Set chargrid RGB color.
347 *
348 * @param scrbuf Chargrid.
349 * @param bgcolor Background color.
350 * @param fgcolor Foreground color.
351 *
352 */
353void chargrid_set_rgb_color(chargrid_t *scrbuf, pixel_t bgcolor,
354 pixel_t fgcolor)
355{
356 scrbuf->attrs.type = CHAR_ATTR_RGB;
357 scrbuf->attrs.val.rgb.bgcolor = bgcolor;
358 scrbuf->attrs.val.rgb.fgcolor = fgcolor;
359}
360
361/** @}
362 */
Note: See TracBrowser for help on using the repository browser.