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 <video.h>
10 
11 struct video_priv;
12 
13 #define VID_FRAC_DIV	256
14 
15 #define VID_TO_PIXEL(x)	((x) / VID_FRAC_DIV)
16 #define VID_TO_POS(x)	((x) * VID_FRAC_DIV)
17 
18 /**
19  * struct vidconsole_priv - uclass-private data about a console device
20  *
21  * Drivers must set up @rows, @cols, @x_charsize, @y_charsize in their probe()
22  * method. Drivers may set up @xstart_frac if desired.
23  *
24  * @sdev:		stdio device, acting as an output sink
25  * @xcur_frac:		Current X position, in fractional units (VID_TO_POS(x))
26  * @ycur:		Current Y position in pixels (0=top)
27  * @rows:		Number of text rows
28  * @cols:		Number of text columns
29  * @x_charsize:		Character width in pixels
30  * @y_charsize:		Character height in pixels
31  * @tab_width_frac:	Tab width in fractional units
32  * @xsize_frac:		Width of the display in fractional units
33  * @xstart_frac:	Left margin for the text console in fractional units
34  * @last_ch:		Last character written to the text console on this line
35  * @escape:		TRUE if currently accumulating an ANSI escape sequence
36  * @escape_len:		Length of accumulated escape sequence so far
37  * @col_saved:		Saved X position, in fractional units (VID_TO_POS(x))
38  * @row_saved:		Saved Y position in pixels (0=top)
39  * @escape_buf:		Buffer to accumulate escape sequence
40  */
41 struct vidconsole_priv {
42 	struct stdio_dev sdev;
43 	int xcur_frac;
44 	int ycur;
45 	int rows;
46 	int cols;
47 	int x_charsize;
48 	int y_charsize;
49 	int tab_width_frac;
50 	int xsize_frac;
51 	int xstart_frac;
52 	int last_ch;
53 	/*
54 	 * ANSI escape sequences are accumulated character by character,
55 	 * starting after the ESC char (0x1b) until the entire sequence
56 	 * is consumed at which point it is acted upon.
57 	 */
58 	int escape;
59 	int escape_len;
60 	int row_saved;
61 	int col_saved;
62 	char escape_buf[32];
63 };
64 
65 /**
66  * struct vidfont_info - information about a font
67  *
68  * @name: Font name, e.g. nimbus_sans_l_regular
69  */
70 struct vidfont_info {
71 	const char *name;
72 };
73 
74 /**
75  * struct vidconsole_ops - Video console operations
76  *
77  * These operations work on either an absolute console position (measured
78  * in pixels) or a text row number (measured in rows, where each row consists
79  * of an entire line of text - typically 16 pixels).
80  */
81 struct vidconsole_ops {
82 	/**
83 	 * putc_xy() - write a single character to a position
84 	 *
85 	 * @dev:	Device to write to
86 	 * @x_frac:	Fractional pixel X position (0=left-most pixel) which
87 	 *		is the X position multipled by VID_FRAC_DIV.
88 	 * @y:		Pixel Y position (0=top-most pixel)
89 	 * @ch:		Character to write
90 	 * @return number of fractional pixels that the cursor should move,
91 	 * if all is OK, -EAGAIN if we ran out of space on this line, other -ve
92 	 * on error
93 	 */
94 	int (*putc_xy)(struct udevice *dev, uint x_frac, uint y, char ch);
95 
96 	/**
97 	 * move_rows() - Move text rows from one place to another
98 	 *
99 	 * @dev:	Device to adjust
100 	 * @rowdst:	Destination text row (0=top)
101 	 * @rowsrc:	Source start text row
102 	 * @count:	Number of text rows to move
103 	 * @return 0 if OK, -ve on error
104 	 */
105 	int (*move_rows)(struct udevice *dev, uint rowdst, uint rowsrc,
106 			  uint count);
107 
108 	/**
109 	 * set_row() - Set the colour of a text row
110 	 *
111 	 * Every pixel contained within the text row is adjusted
112 	 *
113 	 * @dev:	Device to adjust
114 	 * @row:	Text row to adjust (0=top)
115 	 * @clr:	Raw colour (pixel value) to write to each pixel
116 	 * @return 0 if OK, -ve on error
117 	 */
118 	int (*set_row)(struct udevice *dev, uint row, int clr);
119 
120 	/**
121 	 * entry_start() - Indicate that text entry is starting afresh
122 	 *
123 	 * @dev:	Device to adjust
124 	 * Returns: 0 on success, -ve on error
125 	 *
126 	 * Consoles which use proportional fonts need to track the position of
127 	 * each character output so that backspace will return to the correct
128 	 * place. This method signals to the console driver that a new entry
129 	 * line is being start (e.g. the user pressed return to start a new
130 	 * command). The driver can use this signal to empty its list of
131 	 * positions.
132 	 */
133 	int (*entry_start)(struct udevice *dev);
134 
135 	/**
136 	 * backspace() - Handle erasing the last character
137 	 *
138 	 * @dev:	Device to adjust
139 	 * Returns: 0 on success, -ve on error
140 	 *
141 	 * With proportional fonts the vidconsole uclass cannot itself erase
142 	 * the previous character. This optional method will be called when
143 	 * a backspace is needed. The driver should erase the previous
144 	 * character and update the cursor position (xcur_frac, ycur) to the
145 	 * start of the previous character.
146 	 *
147 	 * If not implement, default behaviour will work for fixed-width
148 	 * characters.
149 	 */
150 	int (*backspace)(struct udevice *dev);
151 
152 	/**
153 	 * get_font() - Obtain information about a font (optional)
154 	 *
155 	 * @dev:	Device to check
156 	 * @seq:	Font number to query (0=first, 1=second, etc.)
157 	 * @info:	Returns font information on success
158 	 * Returns: 0 on success, -ENOENT if no such font
159 	 */
160 	int (*get_font)(struct udevice *dev, int seq,
161 			struct vidfont_info *info);
162 
163 	/**
164 	 * get_font_size() - get the current font name and size
165 	 *
166 	 * @dev: vidconsole device
167 	 * @sizep: Place to put the font size (nominal height in pixels)
168 	 * Returns: Current font name
169 	 */
170 	const char *(*get_font_size)(struct udevice *dev, uint *sizep);
171 
172 	/**
173 	 * select_font() - Select a particular font by name / size
174 	 *
175 	 * @dev:	Device to adjust
176 	 * @name:	Font name to use (NULL to use default)
177 	 * @size:	Font size to use (0 to use default)
178 	 * Returns: 0 on success, -ENOENT if no such font
179 	 */
180 	int (*select_font)(struct udevice *dev, const char *name, uint size);
181 };
182 
183 /* Get a pointer to the driver operations for a video console device */
184 #define vidconsole_get_ops(dev)  ((struct vidconsole_ops *)(dev)->driver->ops)
185 
186 /**
187  * vidconsole_get_font() - Obtain information about a font
188  *
189  * @dev:	Device to check
190  * @seq:	Font number to query (0=first, 1=second, etc.)
191  * @info:	Returns font information on success
192  * Returns: 0 on success, -ENOENT if no such font, -ENOSYS if there is no such
193  * method
194  */
195 int vidconsole_get_font(struct udevice *dev, int seq,
196 			struct vidfont_info *info);
197 
198 /**
199  * vidconsole_select_font() - Select a particular font by name / size
200  *
201  * @dev:	Device to adjust
202  * @name:	Font name to use (NULL to use default)
203  * @size:	Font size to use (0 to use default)
204  */
205 int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
206 
207 /**
208  * vidconsole_putc_xy() - write a single character to a position
209  *
210  * @dev:	Device to write to
211  * @x_frac:	Fractional pixel X position (0=left-most pixel) which
212  *		is the X position multipled by VID_FRAC_DIV.
213  * @y:		Pixel Y position (0=top-most pixel)
214  * @ch:		Character to write
215  * Return: number of fractional pixels that the cursor should move,
216  * if all is OK, -EAGAIN if we ran out of space on this line, other -ve
217  * on error
218  */
219 int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, char ch);
220 
221 /**
222  * vidconsole_move_rows() - Move text rows from one place to another
223  *
224  * @dev:	Device to adjust
225  * @rowdst:	Destination text row (0=top)
226  * @rowsrc:	Source start text row
227  * @count:	Number of text rows to move
228  * Return: 0 if OK, -ve on error
229  */
230 int vidconsole_move_rows(struct udevice *dev, uint rowdst, uint rowsrc,
231 			 uint count);
232 
233 /**
234  * vidconsole_set_row() - Set the colour of a text row
235  *
236  * Every pixel contained within the text row is adjusted
237  *
238  * @dev:	Device to adjust
239  * @row:	Text row to adjust (0=top)
240  * @clr:	Raw colour (pixel value) to write to each pixel
241  * Return: 0 if OK, -ve on error
242  */
243 int vidconsole_set_row(struct udevice *dev, uint row, int clr);
244 
245 /**
246  * vidconsole_put_char() - Output a character to the current console position
247  *
248  * Outputs a character to the console and advances the cursor. This function
249  * handles wrapping to new lines and scrolling the console. Special
250  * characters are handled also: \n, \r, \b and \t.
251  *
252  * The device always starts with the cursor at position 0,0 (top left). It
253  * can be adjusted manually using vidconsole_position_cursor().
254  *
255  * @dev:	Device to adjust
256  * @ch:		Character to write
257  * Return: 0 if OK, -ve on error
258  */
259 int vidconsole_put_char(struct udevice *dev, char ch);
260 
261 /**
262  * vidconsole_put_string() - Output a string to the current console position
263  *
264  * Outputs a string to the console and advances the cursor. This function
265  * handles wrapping to new lines and scrolling the console. Special
266  * characters are handled also: \n, \r, \b and \t.
267  *
268  * The device always starts with the cursor at position 0,0 (top left). It
269  * can be adjusted manually using vidconsole_position_cursor().
270  *
271  * @dev:	Device to adjust
272  * @str:	String to write
273  * Return: 0 if OK, -ve on error
274  */
275 int vidconsole_put_string(struct udevice *dev, const char *str);
276 
277 /**
278  * vidconsole_position_cursor() - Move the text cursor
279  *
280  * @dev:	Device to adjust
281  * @col:	New cursor text column
282  * @row:	New cursor text row
283  * Return: 0 if OK, -ve on error
284  */
285 void vidconsole_position_cursor(struct udevice *dev, unsigned col,
286 				unsigned row);
287 
288 /**
289  * vidconsole_clear_and_reset() - Clear the console and reset the cursor
290  *
291  * The cursor is placed at the start of the console
292  *
293  * @dev:	vidconsole device to adjust
294  */
295 int vidconsole_clear_and_reset(struct udevice *dev);
296 
297 /**
298  * vidconsole_set_cursor_pos() - set cursor position
299  *
300  * The cursor is set to the new position and the start-of-line information is
301  * updated to the same position, so that a newline will return to @x
302  *
303  * @dev:	video console device to update
304  * @x:		x position from left in pixels
305  * @y:		y position from top in pixels
306  */
307 void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y);
308 
309 /**
310  * vidconsole_list_fonts() - List the available fonts
311  *
312  * @dev: vidconsole device to check
313  *
314  * This shows a list of fonts known by this vidconsole. The list is displayed on
315  * the console (not necessarily @dev but probably)
316  */
317 void vidconsole_list_fonts(struct udevice *dev);
318 
319 /**
320  * vidconsole_get_font_size() - get the current font name and size
321  *
322  * @dev: vidconsole device
323  * @sizep: Place to put the font size (nominal height in pixels)
324  * @name: pointer to font name, a placeholder for result
325  * Return: 0 if OK, -ENOSYS if not implemented in driver
326  */
327 int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep);
328 
329 #ifdef CONFIG_VIDEO_COPY
330 /**
331  * vidconsole_sync_copy() - Sync back to the copy framebuffer
332  *
333  * This ensures that the copy framebuffer has the same data as the framebuffer
334  * for a particular region. It should be called after the framebuffer is updated
335  *
336  * @from and @to can be in either order. The region between them is synced.
337  *
338  * @dev: Vidconsole device being updated
339  * @from: Start/end address within the framebuffer (->fb)
340  * @to: Other address within the frame buffer
341  * Return: 0 if OK, -EFAULT if the start address is before the start of the
342  *	frame buffer start
343  */
344 int vidconsole_sync_copy(struct udevice *dev, void *from, void *to);
345 
346 /**
347  * vidconsole_memmove() - Perform a memmove() within the frame buffer
348  *
349  * This handles a memmove(), e.g. for scrolling. It also updates the copy
350  * framebuffer.
351  *
352  * @dev: Vidconsole device being updated
353  * @dst: Destination address within the framebuffer (->fb)
354  * @src: Source address within the framebuffer (->fb)
355  * @size: Number of bytes to transfer
356  * Return: 0 if OK, -EFAULT if the start address is before the start of the
357  *	frame buffer start
358  */
359 int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
360 		       int size);
361 #else
362 
363 #include <string.h>
364 
vidconsole_sync_copy(struct udevice * dev,void * from,void * to)365 static inline int vidconsole_sync_copy(struct udevice *dev, void *from,
366 				       void *to)
367 {
368 	return 0;
369 }
370 
vidconsole_memmove(struct udevice * dev,void * dst,const void * src,int size)371 static inline int vidconsole_memmove(struct udevice *dev, void *dst,
372 				     const void *src, int size)
373 {
374 	memmove(dst, src, size);
375 
376 	return 0;
377 }
378 
379 #endif
380 
381 #endif
382