1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (c) 2015 Google, Inc
4  */
5 
6 #ifndef __video_console_h
7 #define __video_console_h
8 
9 #include <alist.h>
10 #include <video.h>
11 
12 struct abuf;
13 struct video_priv;
14 
15 #define VID_FRAC_DIV	256
16 
17 #define VID_TO_PIXEL(x)	((x) / VID_FRAC_DIV)
18 #define VID_TO_POS(x)	((x) * VID_FRAC_DIV)
19 
20 enum {
21 	/* cursor width in pixels */
22 	VIDCONSOLE_CURSOR_WIDTH		= 2,
23 };
24 
25 /**
26  * struct vidconsole_priv - uclass-private data about a console device
27  *
28  * Drivers must set up @rows, @cols, @x_charsize, @y_charsize in their probe()
29  * method. Drivers may set up @xstart_frac if desired.
30  *
31  * Note that these values relate to the rotated console, so that an 80x25
32  * console which is rotated 90 degrees will have rows=80 and cols=25
33  *
34  * The xcur_frac and ycur values refer to the unrotated coordinates, that is
35  * xcur_frac always advances with each character, even if its limit might be
36  * vid_priv->ysize instead of vid_priv->xsize if the console is rotated 90 or
37  * 270 degrees.
38  *
39  * @sdev:		stdio device, acting as an output sink
40  * @xcur_frac:		Current X position, in fractional units (VID_TO_POS(x))
41  * @ycur:		Current Y position in pixels (0=top)
42  * @rows:		Number of text rows
43  * @cols:		Number of text columns
44  * @x_charsize:		Character width in pixels
45  * @y_charsize:		Character height in pixels
46  * @tab_width_frac:	Tab width in fractional units
47  * @xsize_frac:		Width of the display in fractional units
48  * @xstart_frac:	Left margin for the text console in fractional units
49  * @last_ch:		Last character written to the text console on this line
50  * @escape:		TRUE if currently accumulating an ANSI escape sequence
51  * @escape_len:		Length of accumulated escape sequence so far
52  * @col_saved:		Saved X position, in fractional units (VID_TO_POS(x))
53  * @row_saved:		Saved Y position in pixels (0=top)
54  * @escape_buf:		Buffer to accumulate escape sequence
55  * @utf8_buf:		Buffer to accumulate UTF-8 byte sequence
56  * @quiet:		Suppress all output from stdio
57  */
58 struct vidconsole_priv {
59 	struct stdio_dev sdev;
60 	int xcur_frac;
61 	int ycur;
62 	int rows;
63 	int cols;
64 	int x_charsize;
65 	int y_charsize;
66 	int tab_width_frac;
67 	int xsize_frac;
68 	int xstart_frac;
69 	int last_ch;
70 	/*
71 	 * ANSI escape sequences are accumulated character by character,
72 	 * starting after the ESC char (0x1b) until the entire sequence
73 	 * is consumed at which point it is acted upon.
74 	 */
75 	int escape;
76 	int escape_len;
77 	int row_saved;
78 	int col_saved;
79 	char escape_buf[32];
80 	char utf8_buf[5];
81 	bool quiet;
82 };
83 
84 /**
85  * struct vidfont_info - information about a font
86  *
87  * @name: Font name, e.g. nimbus_sans_l_regular
88  */
89 struct vidfont_info {
90 	const char *name;
91 };
92 
93 /**
94  * struct vidconsole_colour - Holds colour information
95  *
96  * @colour_fg:	Foreground colour (pixel value)
97  * @colour_bg:	Background colour (pixel value)
98  */
99 struct vidconsole_colour {
100 	u32 colour_fg;
101 	u32 colour_bg;
102 };
103 
104 /**
105  * struct vidconsole_bbox - Bounding box of text
106  *
107  * This describes the bounding box of something, measured in pixels. The x0/y0
108  * pair is inclusive; the x1/y2 pair is exclusive, meaning that it is one pixel
109  * beyond the extent of the object
110  *
111  * @valid: Values are valid (bounding box is known)
112  * @x0: left x position, in pixels from left side
113  * @y0: top y position, in pixels from top
114  * @x1: right x position + 1
115  * @y1: botton y position + 1
116  */
117 struct vidconsole_bbox {
118 	bool valid;
119 	int x0;
120 	int y0;
121 	int x1;
122 	int y1;
123 };
124 
125 /**
126  * vidconsole_mline - Holds information about a line of measured text
127  *
128  * @bbox: Bounding box of the line, assuming it starts at 0,0
129  * @start: String index of the first character in the line
130  * @len: Number of characters in the line
131  */
132 struct vidconsole_mline {
133 	struct vidconsole_bbox bbox;
134 	int start;
135 	int len;
136 };
137 
138 /**
139  * struct vidconsole_ops - Video console operations
140  *
141  * These operations work on either an absolute console position (measured
142  * in pixels) or a text row number (measured in rows, where each row consists
143  * of an entire line of text - typically 16 pixels).
144  */
145 struct vidconsole_ops {
146 	/**
147 	 * putc_xy() - write a single character to a position
148 	 *
149 	 * @dev:	Device to write to
150 	 * @x_frac:	Fractional pixel X position (0=left-most pixel) which
151 	 *		is the X position multipled by VID_FRAC_DIV.
152 	 * @y:		Pixel Y position (0=top-most pixel)
153 	 * @cp:		UTF-32 code point to write
154 	 * @return number of fractional pixels that the cursor should move,
155 	 * if all is OK, -EAGAIN if we ran out of space on this line, other -ve
156 	 * on error
157 	 */
158 	int (*putc_xy)(struct udevice *dev, uint x_frac, uint y, int cp);
159 
160 	/**
161 	 * move_rows() - Move text rows from one place to another
162 	 *
163 	 * @dev:	Device to adjust
164 	 * @rowdst:	Destination text row (0=top)
165 	 * @rowsrc:	Source start text row
166 	 * @count:	Number of text rows to move
167 	 * @return 0 if OK, -ve on error
168 	 */
169 	int (*move_rows)(struct udevice *dev, uint rowdst, uint rowsrc,
170 			  uint count);
171 
172 	/**
173 	 * set_row() - Set the colour of a text row
174 	 *
175 	 * Every pixel contained within the text row is adjusted
176 	 *
177 	 * @dev:	Device to adjust
178 	 * @row:	Text row to adjust (0=top)
179 	 * @clr:	Raw colour (pixel value) to write to each pixel
180 	 * @return 0 if OK, -ve on error
181 	 */
182 	int (*set_row)(struct udevice *dev, uint row, int clr);
183 
184 	/**
185 	 * entry_start() - Indicate that text entry is starting afresh
186 	 *
187 	 * @dev:	Device to adjust
188 	 * Returns: 0 on success, -ve on error
189 	 *
190 	 * Consoles which use proportional fonts need to track the position of
191 	 * each character output so that backspace will return to the correct
192 	 * place. This method signals to the console driver that a new entry
193 	 * line is being start (e.g. the user pressed return to start a new
194 	 * command). The driver can use this signal to empty its list of
195 	 * positions.
196 	 */
197 	int (*entry_start)(struct udevice *dev);
198 
199 	/**
200 	 * backspace() - Handle erasing the last character
201 	 *
202 	 * @dev:	Device to adjust
203 	 * Returns: 0 on success, -ve on error
204 	 *
205 	 * With proportional fonts the vidconsole uclass cannot itself erase
206 	 * the previous character. This optional method will be called when
207 	 * a backspace is needed. The driver should erase the previous
208 	 * character and update the cursor position (xcur_frac, ycur) to the
209 	 * start of the previous character.
210 	 *
211 	 * If not implement, default behaviour will work for fixed-width
212 	 * characters.
213 	 */
214 	int (*backspace)(struct udevice *dev);
215 
216 	/**
217 	 * get_font() - Obtain information about a font (optional)
218 	 *
219 	 * @dev:	Device to check
220 	 * @seq:	Font number to query (0=first, 1=second, etc.)
221 	 * @info:	Returns font information on success
222 	 * Returns: 0 on success, -ENOENT if no such font
223 	 */
224 	int (*get_font)(struct udevice *dev, int seq,
225 			struct vidfont_info *info);
226 
227 	/**
228 	 * get_font_size() - get the current font name and size
229 	 *
230 	 * @dev: vidconsole device
231 	 * @sizep: Place to put the font size (nominal height in pixels)
232 	 * Returns: Current font name
233 	 */
234 	const char *(*get_font_size)(struct udevice *dev, uint *sizep);
235 
236 	/**
237 	 * select_font() - Select a particular font by name / size
238 	 *
239 	 * @dev:	Device to adjust
240 	 * @name:	Font name to use (NULL to use default)
241 	 * @size:	Font size to use (0 to use default)
242 	 * Returns: 0 on success, -ENOENT if no such font
243 	 */
244 	int (*select_font)(struct udevice *dev, const char *name, uint size);
245 
246 	/**
247 	 * measure() - Measure the bounding box of some text
248 	 *
249 	 * The text can include newlines
250 	 *
251 	 * @dev:	Console device to use
252 	 * @name:	Font name to use (NULL to use default)
253 	 * @size:	Font size to use (0 to use default)
254 	 * @text:	Text to measure
255 	 * @limit:	Width limit for each line, or -1 if none
256 	 * @bbox:	Returns bounding box of text, assuming it is positioned
257 	 *		at 0,0
258 	 * @lines:	If non-NULL, this must be an alist of
259 	 *		struct vidconsole_mline inited by caller. A separate
260 	 *		record is added for each line of text
261 	 *
262 	 * Returns: 0 on success, -ENOENT if no such font
263 	 */
264 	int (*measure)(struct udevice *dev, const char *name, uint size,
265 		       const char *text, int limit,
266 		       struct vidconsole_bbox *bbox, struct alist *lines);
267 
268 	/**
269 	 * nominal() - Measure the expected width of a line of text
270 	 *
271 	 * Uses an average font width and nominal height
272 	 *
273 	 * @dev: Console device to use
274 	 * @name: Font name, NULL for default
275 	 * @size: Font size, ignored if @name is NULL
276 	 * @num_chars: Number of characters to use
277 	 * @bbox: Returns nounding box of @num_chars characters
278 	 * Returns: 0 if OK, -ve on error
279 	 */
280 	int (*nominal)(struct udevice *dev, const char *name, uint size,
281 		       uint num_chars, struct vidconsole_bbox *bbox);
282 
283 	/**
284 	 * entry_save() - Save any text-entry information for later use
285 	 *
286 	 * Saves text-entry context such as a list of positions for each
287 	 * character in the string.
288 	 *
289 	 * @dev: Console device to use
290 	 * @buf: Buffer to hold saved data
291 	 * Return: 0 if OK, -ENOMEM if out of memory
292 	 */
293 	int (*entry_save)(struct udevice *dev, struct abuf *buf);
294 
295 	/**
296 	 * entry_restore() - Restore text-entry information for current use
297 	 *
298 	 * Restores text-entry context such as a list of positions for each
299 	 * character in the string.
300 	 *
301 	 * @dev: Console device to use
302 	 * @buf: Buffer containing data to restore
303 	 * Return: 0 if OK, -ve on error
304 	 */
305 	int (*entry_restore)(struct udevice *dev, struct abuf *buf);
306 
307 	/**
308 	 * set_cursor_visible() - Show or hide the cursor
309 	 *
310 	 * Shows or hides a cursor at the current position
311 	 *
312 	 * @dev: Console device to use
313 	 * @visible: true to show the cursor, false to hide it
314 	 * @x: X position in pixels
315 	 * @y: Y position in pixels
316 	 * @index: Character position (0 = at start)
317 	 * Return: 0 if OK, -ve on error
318 	 */
319 	int (*set_cursor_visible)(struct udevice *dev, bool visible,
320 				  uint x, uint y, uint index);
321 };
322 
323 /* Get a pointer to the driver operations for a video console device */
324 #define vidconsole_get_ops(dev)  ((struct vidconsole_ops *)(dev)->driver->ops)
325 
326 /**
327  * vidconsole_get_font() - Obtain information about a font
328  *
329  * @dev:	Device to check
330  * @seq:	Font number to query (0=first, 1=second, etc.)
331  * @info:	Returns font information on success
332  * Returns: 0 on success, -ENOENT if no such font, -ENOSYS if there is no such
333  * method
334  */
335 int vidconsole_get_font(struct udevice *dev, int seq,
336 			struct vidfont_info *info);
337 
338 /**
339  * vidconsole_select_font() - Select a particular font by name / size
340  *
341  * @dev:	Device to adjust
342  * @name:	Font name to use (NULL to use default)
343  * @size:	Font size to use (0 to use default)
344  */
345 int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
346 
347 /**
348  * vidconsole_measure() - Measure the bounding box of some text
349  *
350  * The text can include newlines
351  *
352  * @dev:	Device to adjust
353  * @name:	Font name to use (NULL to use default)
354  * @size:	Font size to use (0 to use default)
355  * @text:	Text to measure
356  * @limit:	Width limit for each line, or -1 if none
357  * @bbox:	Returns bounding box of text, assuming it is positioned
358  *		at 0,0
359  * @lines:	If non-NULL, this must be an alist of
360  *		struct vidconsole_mline inited by caller. The list is emptied
361  *		and then a separate record is added for each line of text
362  *
363  * Returns: 0 on success, -ENOENT if no such font
364  */
365 int vidconsole_measure(struct udevice *dev, const char *name, uint size,
366 		       const char *text, int limit,
367 		       struct vidconsole_bbox *bbox, struct alist *lines);
368 /**
369  * vidconsole_nominal() - Measure the expected width of a line of text
370  *
371  * Uses an average font width and nominal height
372  *
373  * @dev: Console device to use
374  * @name: Font name, NULL for default
375  * @size: Font size, ignored if @name is NULL
376  * @num_chars: Number of characters to use
377  * @bbox: Returns nounding box of @num_chars characters
378  * Returns: 0 if OK, -ve on error
379  */
380 int vidconsole_nominal(struct udevice *dev, const char *name, uint size,
381 		       uint num_chars, struct vidconsole_bbox *bbox);
382 
383 /**
384  * vidconsole_entry_save() - Save any text-entry information for later use
385  *
386  * Saves text-entry context such as a list of positions for each
387  * character in the string.
388  *
389  * @dev: Console device to use
390  * @buf: Buffer to hold saved data
391  * Return: 0 if OK, -ENOMEM if out of memory
392  */
393 int vidconsole_entry_save(struct udevice *dev, struct abuf *buf);
394 
395 /**
396  * entry_restore() - Restore text-entry information for current use
397  *
398  * Restores text-entry context such as a list of positions for each
399  * character in the string.
400  *
401  * @dev: Console device to use
402  * @buf: Buffer containing data to restore
403  * Return: 0 if OK, -ve on error
404  */
405 int vidconsole_entry_restore(struct udevice *dev, struct abuf *buf);
406 
407 /**
408  * vidconsole_set_cursor_visible() - Show or hide the cursor
409  *
410  * Shows or hides a cursor at the current position
411  *
412  * @dev: Console device to use
413  * @visible: true to show the cursor, false to hide it
414  * @x: X position in pixels
415  * @y: Y position in pixels
416  * @index: Character position (0 = at start)
417  * Return: 0 if OK, -ve on error
418  */
419 int vidconsole_set_cursor_visible(struct udevice *dev, bool visible,
420 				  uint x, uint y, uint index);
421 
422 /**
423  * vidconsole_push_colour() - Temporarily change the font colour
424  *
425  * @dev:	Device to adjust
426  * @fg:		Foreground colour to select
427  * @bg:		Background colour to select
428  * @old:	Place to store the current colour, so it can be restored
429  */
430 void vidconsole_push_colour(struct udevice *dev, enum colour_idx fg,
431 			    enum colour_idx bg, struct vidconsole_colour *old);
432 
433 /**
434  * vidconsole_pop_colour() - Restore the original colour
435  *
436  * @dev:	Device to adjust
437  * @old:	Old colour to be restored
438  */
439 void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old);
440 
441 /**
442  * vidconsole_putc_xy() - write a single character to a position
443  *
444  * @dev:	Device to write to
445  * @x_frac:	Fractional pixel X position (0=left-most pixel) which
446  *		is the X position multipled by VID_FRAC_DIV.
447  * @y:		Pixel Y position (0=top-most pixel)
448  * @cp:		UTF-32 code point to write
449  * Return: number of fractional pixels that the cursor should move,
450  * if all is OK, -EAGAIN if we ran out of space on this line, other -ve
451  * on error
452  */
453 int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, int cp);
454 
455 /**
456  * vidconsole_move_rows() - Move text rows from one place to another
457  *
458  * @dev:	Device to adjust
459  * @rowdst:	Destination text row (0=top)
460  * @rowsrc:	Source start text row
461  * @count:	Number of text rows to move
462  * Return: 0 if OK, -ve on error
463  */
464 int vidconsole_move_rows(struct udevice *dev, uint rowdst, uint rowsrc,
465 			 uint count);
466 
467 /**
468  * vidconsole_set_row() - Set the colour of a text row
469  *
470  * Every pixel contained within the text row is adjusted
471  *
472  * @dev:	Device to adjust
473  * @row:	Text row to adjust (0=top)
474  * @clr:	Raw colour (pixel value) to write to each pixel
475  * Return: 0 if OK, -ve on error
476  */
477 int vidconsole_set_row(struct udevice *dev, uint row, int clr);
478 
479 /**
480  * vidconsole_entry_start() - Set the start position of a vidconsole line
481  *
482  * Marks the current cursor position as the start of a line
483  *
484  * @dev:	Device to adjust
485  */
486 int vidconsole_entry_start(struct udevice *dev);
487 
488 /**
489  * vidconsole_put_char() - Output a character to the current console position
490  *
491  * Outputs a character to the console and advances the cursor. This function
492  * handles wrapping to new lines and scrolling the console. Special
493  * characters are handled also: \n, \r, \b and \t.
494  *
495  * The device always starts with the cursor at position 0,0 (top left). It
496  * can be adjusted manually using vidconsole_position_cursor().
497  *
498  * @dev:	Device to adjust
499  * @ch:		Character to write
500  * Return: 0 if OK, -ve on error
501  */
502 int vidconsole_put_char(struct udevice *dev, char ch);
503 
504 /**
505  * vidconsole_put_stringn() - Output part of a string to the current console pos
506  *
507  * Outputs part of a string to the console and advances the cursor. This
508  * function handles wrapping to new lines and scrolling the console. Special
509  * characters are handled also: \n, \r, \b and \t.
510  *
511  * The device always starts with the cursor at position 0,0 (top left). It
512  * can be adjusted manually using vidconsole_position_cursor().
513  *
514  * @dev:	Device to adjust
515  * @str:	String to write
516  * @maxlen:	Maximum chars to output, or -1 for all
517  * Return: 0 if OK, -ve on error
518  */
519 int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen);
520 
521 /**
522  * vidconsole_put_string() - Output a string to the current console position
523  *
524  * Outputs a string to the console and advances the cursor. This function
525  * handles wrapping to new lines and scrolling the console. Special
526  * characters are handled also: \n, \r, \b and \t.
527  *
528  * The device always starts with the cursor at position 0,0 (top left). It
529  * can be adjusted manually using vidconsole_position_cursor().
530  *
531  * @dev:	Device to adjust
532  * @str:	String to write
533  * Return: 0 if OK, -ve on error
534  */
535 int vidconsole_put_string(struct udevice *dev, const char *str);
536 
537 /**
538  * vidconsole_position_cursor() - Move the text cursor
539  *
540  * @dev:	Device to adjust
541  * @col:	New cursor text column
542  * @row:	New cursor text row
543  * Return: 0 if OK, -ve on error
544  */
545 void vidconsole_position_cursor(struct udevice *dev, unsigned col,
546 				unsigned row);
547 
548 /**
549  * vidconsole_clear_and_reset() - Clear the console and reset the cursor
550  *
551  * The cursor is placed at the start of the console
552  *
553  * @dev:	vidconsole device to adjust
554  */
555 int vidconsole_clear_and_reset(struct udevice *dev);
556 
557 /**
558  * vidconsole_set_cursor_pos() - set cursor position
559  *
560  * The cursor is set to the new position and the start-of-line information is
561  * updated to the same position, so that a newline will return to @x
562  *
563  * @dev:	video console device to update
564  * @x:		x position from left in pixels
565  * @y:		y position from top in pixels
566  */
567 void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y);
568 
569 /**
570  * vidconsole_list_fonts() - List the available fonts
571  *
572  * @dev: vidconsole device to check
573  *
574  * This shows a list of fonts known by this vidconsole. The list is displayed on
575  * the console (not necessarily @dev but probably)
576  */
577 void vidconsole_list_fonts(struct udevice *dev);
578 
579 /**
580  * vidconsole_get_font_size() - get the current font name and size
581  *
582  * @dev: vidconsole device
583  * @sizep: Place to put the font size (nominal height in pixels)
584  * @name: pointer to font name, a placeholder for result
585  * Return: 0 if OK, -ENOSYS if not implemented in driver
586  */
587 int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep);
588 
589 /**
590  * vidconsole_set_quiet() - Select whether the console should output stdio
591  *
592  * @dev: vidconsole device
593  * @quiet: true to suppress stdout/stderr output, false to enable it
594  */
595 void vidconsole_set_quiet(struct udevice *dev, bool quiet);
596 
597 #endif
598