blob: 001f7db2553fdff4f45fbbd2f89e6f862aaea5b6 [file] [log] [blame]
Simon Glassd8adbe92023-01-06 08:52:36 -06001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright 2022 Google LLC
4 * Written by Simon Glass <sjg@chromium.org>
5 */
6
Simon Glass8df4a4e2023-08-14 16:40:25 -06007#ifndef __EXPO_H
8#define __EXPO_H
Simon Glassd8adbe92023-01-06 08:52:36 -06009
Simon Glassa968f5f2023-10-01 19:13:31 -060010#include <abuf.h>
Simon Glasscfb4f2c2025-05-02 08:46:42 -060011#include <alist.h>
Simon Glassc999e172023-06-01 10:22:53 -060012#include <dm/ofnode_decl.h>
Simon Glassebec4972025-05-02 08:46:33 -060013#include <linux/bitops.h>
Simon Glassd8adbe92023-01-06 08:52:36 -060014#include <linux/list.h>
15
16struct udevice;
17
Simon Glassa968f5f2023-10-01 19:13:31 -060018#include <cli.h>
19
Simon Glassd8adbe92023-01-06 08:52:36 -060020/**
Simon Glass53a0a2f2024-10-14 16:31:57 -060021 * enum expo_id_t - standard expo IDs
22 *
23 * These are assumed to be in use at all times. Expos should use IDs starting
24 * from EXPOID_BASE_ID,
25 *
26 * @EXPOID_NONE: Not used, invalid ID 0
27 * @EXPOID_SAVE: User has requested that the expo data be saved
28 * @EXPOID_DISCARD: User has requested that the expo data be discarded
29 * @EXPOID_BASE_ID: First ID which can be used for expo objects
30 */
31enum expo_id_t {
32 EXPOID_NONE,
33
34 EXPOID_SAVE,
35 EXPOID_DISCARD,
36
37 EXPOID_BASE_ID = 5,
38};
39
40/**
Simon Glassd8adbe92023-01-06 08:52:36 -060041 * enum expoact_type - types of actions reported by the expo
42 *
43 * @EXPOACT_NONE: no action
Simon Glassf0e1e8c2023-06-01 10:22:59 -060044 * @EXPOACT_POINT_OBJ: object was highlighted (@id indicates which)
Simon Glass719a3c62023-06-01 10:22:56 -060045 * @EXPOACT_POINT_ITEM: menu item was highlighted (@id indicates which)
Simon Glassd8adbe92023-01-06 08:52:36 -060046 * @EXPOACT_SELECT: menu item was selected (@id indicates which)
Simon Glassf0e1e8c2023-06-01 10:22:59 -060047 * @EXPOACT_OPEN: menu was opened, so an item can be selected (@id indicates
48 * which menu object)
49 * @EXPOACT_CLOSE: menu was closed (@id indicates which menu object)
Simon Glassd8adbe92023-01-06 08:52:36 -060050 * @EXPOACT_QUIT: request to exit the menu
51 */
52enum expoact_type {
53 EXPOACT_NONE,
Simon Glassf0e1e8c2023-06-01 10:22:59 -060054 EXPOACT_POINT_OBJ,
Simon Glass719a3c62023-06-01 10:22:56 -060055 EXPOACT_POINT_ITEM,
Simon Glassd8adbe92023-01-06 08:52:36 -060056 EXPOACT_SELECT,
Simon Glassf0e1e8c2023-06-01 10:22:59 -060057 EXPOACT_OPEN,
58 EXPOACT_CLOSE,
Simon Glassd8adbe92023-01-06 08:52:36 -060059 EXPOACT_QUIT,
60};
61
62/**
63 * struct expo_action - an action report by the expo
64 *
65 * @type: Action type (EXPOACT_NONE if there is no action)
Simon Glass719a3c62023-06-01 10:22:56 -060066 * @select: Used for EXPOACT_POINT_ITEM and EXPOACT_SELECT
Heinrich Schuchardta99e8fe2024-09-18 23:58:03 +020067 * @select.id: ID number of the object affected.
Simon Glassd8adbe92023-01-06 08:52:36 -060068 */
69struct expo_action {
70 enum expoact_type type;
71 union {
72 struct {
73 int id;
74 } select;
75 };
76};
77
78/**
Simon Glassc999e172023-06-01 10:22:53 -060079 * struct expo_theme - theme for the expo
80 *
81 * @font_size: Default font size for all text
82 * @menu_inset: Inset width (on each side and top/bottom) for menu items
83 * @menuitem_gap_y: Gap between menu items in pixels
Simon Glass377f18e2024-10-14 16:31:55 -060084 * @menu_title_margin_x: Gap between right side of menu title and left size of
85 * menu label
Simon Glassc999e172023-06-01 10:22:53 -060086 */
87struct expo_theme {
88 u32 font_size;
89 u32 menu_inset;
90 u32 menuitem_gap_y;
Simon Glass377f18e2024-10-14 16:31:55 -060091 u32 menu_title_margin_x;
Simon Glassc999e172023-06-01 10:22:53 -060092};
93
94/**
Simon Glassd8adbe92023-01-06 08:52:36 -060095 * struct expo - information about an expo
96 *
97 * A group of scenes which can be presented to the user, typically to obtain
98 * input or to make a selection.
99 *
100 * @name: Name of the expo (allocated)
101 * @display: Display to use (`UCLASS_VIDEO`), or NULL to use text mode
Simon Glass67e2af12023-06-01 10:22:34 -0600102 * @cons: Console to use (`UCLASS_VIDEO_CONSOLE`), or NULL to use text mode
Simon Glassd8adbe92023-01-06 08:52:36 -0600103 * @scene_id: Current scene ID (0 if none)
104 * @next_id: Next ID number to use, for automatic allocation
105 * @action: Action selected by user. At present only one is supported, with the
106 * type set to EXPOACT_NONE if there is no action
107 * @text_mode: true to use text mode for the menu (no vidconsole)
Simon Glassd353b752023-06-01 10:22:55 -0600108 * @popup: true to use popup menus, instead of showing all items
Simon Glassd8adbe92023-01-06 08:52:36 -0600109 * @priv: Private data for the controller
Simon Glass527d8642025-05-02 08:46:20 -0600110 * @done: Indicates that a cedit session is complete and the user has quit
111 * @save: Indicates that cedit data should be saved, rather than discarded
Simon Glassc999e172023-06-01 10:22:53 -0600112 * @theme: Information about fonts styles, etc.
Simon Glassd8adbe92023-01-06 08:52:36 -0600113 * @scene_head: List of scenes
114 * @str_head: list of strings
Simon Glass683d8832025-05-02 08:46:15 -0600115 * @cch: Keyboard context for input
Simon Glassd8adbe92023-01-06 08:52:36 -0600116 */
117struct expo {
118 char *name;
119 struct udevice *display;
Simon Glass67e2af12023-06-01 10:22:34 -0600120 struct udevice *cons;
Simon Glassd8adbe92023-01-06 08:52:36 -0600121 uint scene_id;
122 uint next_id;
123 struct expo_action action;
124 bool text_mode;
Simon Glassd353b752023-06-01 10:22:55 -0600125 bool popup;
Simon Glassd8adbe92023-01-06 08:52:36 -0600126 void *priv;
Simon Glass527d8642025-05-02 08:46:20 -0600127 bool done;
128 bool save;
Simon Glassc999e172023-06-01 10:22:53 -0600129 struct expo_theme theme;
Simon Glassd8adbe92023-01-06 08:52:36 -0600130 struct list_head scene_head;
131 struct list_head str_head;
Simon Glass683d8832025-05-02 08:46:15 -0600132 struct cli_ch_state cch;
Simon Glassd8adbe92023-01-06 08:52:36 -0600133};
134
135/**
136 * struct expo_string - a string that can be used in an expo
137 *
138 * @id: ID number of the string
Simon Glassda337752025-05-02 08:46:32 -0600139 * @buf: String (contains nul terminator)
Simon Glassd8adbe92023-01-06 08:52:36 -0600140 * @sibling: Node to link this object to its siblings
141 */
142struct expo_string {
143 uint id;
Simon Glassda337752025-05-02 08:46:32 -0600144 struct abuf buf;
Simon Glassd8adbe92023-01-06 08:52:36 -0600145 struct list_head sibling;
146};
147
148/**
149 * struct scene - information about a scene in an expo
150 *
151 * A collection of text/image/menu items in an expo
152 *
153 * @expo: Expo this scene is part of
154 * @name: Name of the scene (allocated)
155 * @id: ID number of the scene
Simon Glassea274b62023-06-01 10:22:27 -0600156 * @title_id: String ID of title of the scene (allocated)
Simon Glassd353b752023-06-01 10:22:55 -0600157 * @highlight_id: ID of highlighted object, if any
Simon Glassa968f5f2023-10-01 19:13:31 -0600158 * @cls: cread state to use for input
159 * @buf: Buffer for input
160 * @entry_save: Buffer to hold vidconsole text-entry information
Simon Glassd8adbe92023-01-06 08:52:36 -0600161 * @sibling: Node to link this scene to its siblings
162 * @obj_head: List of objects in the scene
163 */
164struct scene {
165 struct expo *expo;
166 char *name;
167 uint id;
Simon Glassea274b62023-06-01 10:22:27 -0600168 uint title_id;
Simon Glassd353b752023-06-01 10:22:55 -0600169 uint highlight_id;
Simon Glassa968f5f2023-10-01 19:13:31 -0600170 struct cli_line_state cls;
171 struct abuf buf;
172 struct abuf entry_save;
Simon Glassd8adbe92023-01-06 08:52:36 -0600173 struct list_head sibling;
174 struct list_head obj_head;
175};
176
177/**
178 * enum scene_obj_t - type of a scene object
179 *
180 * @SCENEOBJT_NONE: Used to indicate that the type does not matter
181 * @SCENEOBJT_IMAGE: Image data to render
Simon Glass138a3972025-05-02 08:46:44 -0600182 * @SCENEOBJT_BOX: Rectangular box
Simon Glassd8adbe92023-01-06 08:52:36 -0600183 * @SCENEOBJT_TEXT: Text line to render
184 * @SCENEOBJT_MENU: Menu containing items the user can select
Simon Glass6116e762023-10-01 19:13:32 -0600185 * @SCENEOBJT_TEXTLINE: Line of text the user can edit
Simon Glassd8adbe92023-01-06 08:52:36 -0600186 */
187enum scene_obj_t {
188 SCENEOBJT_NONE = 0,
189 SCENEOBJT_IMAGE,
190 SCENEOBJT_TEXT,
Simon Glass138a3972025-05-02 08:46:44 -0600191 SCENEOBJT_BOX,
Simon Glass193bfea2023-10-01 19:13:27 -0600192
193 /* types from here on can be highlighted */
Simon Glassd8adbe92023-01-06 08:52:36 -0600194 SCENEOBJT_MENU,
Simon Glass6116e762023-10-01 19:13:32 -0600195 SCENEOBJT_TEXTLINE,
Simon Glassd8adbe92023-01-06 08:52:36 -0600196};
197
198/**
Simon Glass854ca692025-05-02 08:46:30 -0600199 * struct scene_obj_bbox - Dimensions of an object
Simon Glass7b043952023-06-01 10:22:49 -0600200 *
Simon Glassbc3a15f2025-05-02 08:46:31 -0600201 * @x0: x position, in pixels from left side
202 * @y0: y position, in pixels from top
Simon Glassebec4972025-05-02 08:46:33 -0600203 * @x1: x position of right size
204 * @y1: y position of bottom
Simon Glass7b043952023-06-01 10:22:49 -0600205 */
Simon Glass854ca692025-05-02 08:46:30 -0600206struct scene_obj_bbox {
Simon Glassbc3a15f2025-05-02 08:46:31 -0600207 int x0;
208 int y0;
Simon Glassebec4972025-05-02 08:46:33 -0600209 int x1;
210 int y1;
Simon Glass7b043952023-06-01 10:22:49 -0600211};
212
213/**
Simon Glass5beb0572025-05-02 08:46:45 -0600214 * struct scene_obj_offset - Offsets for drawing the object
215 *
216 * Stores the offset from x0, x1 at which objects are drawn
217 *
218 * @xofs: x offset
219 * @yofs: y offset
220 */
221struct scene_obj_offset {
222 int xofs;
223 int yofs;
224};
225
226/**
Simon Glassebec4972025-05-02 08:46:33 -0600227 * struct scene_obj_dims - Dimensions of the object being drawn
228 *
229 * Image and text objects have a dimension which can change depending on what
230 * they contain. For images this stores the size. For text it stores the size as
231 * rendered on the display
232 *
233 * @x: x dimension
234 * @y: y dimension
235 */
236struct scene_obj_dims {
237 int x;
238 int y;
239};
240
241/**
Simon Glass5beb0572025-05-02 08:46:45 -0600242 * enum scene_obj_halign - Horizontal alignment of objects
243 *
244 * Objects are normally drawn on the left size of their bounding box. This
245 * properly allows aligning on the right or having the object centred.
246 *
247 * @SCENEOA_LEFT: Left of object is aligned with its x coordinate
248 * @SCENEOA_RIGHT: Right of object is aligned with x + w
249 * @SCENEOA_CENTRE: Centre of object is aligned with centre of bounding box
250 * @SCENEOA_TOP: Left of object is aligned with its x coordinate
251 * @SCENEOA_BOTTOM: Right of object is aligned with x + w
252 *
253 * Note: It would be nice to make this a char type but Sphinx riddles:
254 * ./include/expo.h:258: error: Cannot parse enum!
255 * enum scene_obj_align : char {
256 */
257enum scene_obj_align {
258 SCENEOA_LEFT,
259 SCENEOA_RIGHT,
260 SCENEOA_CENTRE,
261 SCENEOA_TOP = SCENEOA_LEFT,
262 SCENEOA_BOTTOM = SCENEOA_RIGHT,
263};
264
265/**
Simon Glass6081b0f2023-06-01 10:22:50 -0600266 * enum scene_obj_flags_t - flags for objects
267 *
268 * @SCENEOF_HIDE: object should be hidden
Simon Glassd353b752023-06-01 10:22:55 -0600269 * @SCENEOF_POINT: object should be highlighted
270 * @SCENEOF_OPEN: object should be opened (e.g. menu is opened so that an option
271 * can be selected)
Simon Glassebec4972025-05-02 08:46:33 -0600272 * @SCENEOF_SIZE_VALID: object's size (width/height) is valid, so any adjustment
273 * to x0/y0 should maintain the width/height of the object
Simon Glass6081b0f2023-06-01 10:22:50 -0600274 */
275enum scene_obj_flags_t {
276 SCENEOF_HIDE = 1 << 0,
Simon Glassd353b752023-06-01 10:22:55 -0600277 SCENEOF_POINT = 1 << 1,
278 SCENEOF_OPEN = 1 << 2,
Simon Glassebec4972025-05-02 08:46:33 -0600279 SCENEOF_SIZE_VALID = BIT(3),
Simon Glass6081b0f2023-06-01 10:22:50 -0600280};
281
Simon Glassa968f5f2023-10-01 19:13:31 -0600282enum {
283 /* Maximum number of characters allowed in an line editor */
284 EXPO_MAX_CHARS = 250,
285};
286
Simon Glass6081b0f2023-06-01 10:22:50 -0600287/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600288 * struct scene_obj - information about an object in a scene
289 *
290 * @scene: Scene that this object relates to
291 * @name: Name of the object (allocated)
292 * @id: ID number of the object
293 * @type: Type of this object
Simon Glassebec4972025-05-02 08:46:33 -0600294 * @bbox: Bounding box for this object
Simon Glass5beb0572025-05-02 08:46:45 -0600295 * @ofs: Offset from x0, y0 where the object is drawn
Simon Glassebec4972025-05-02 08:46:33 -0600296 * @dims: Dimensions of the text/image (may be smaller than bbox)
Simon Glass5beb0572025-05-02 08:46:45 -0600297 * @horiz: Horizonal alignment
298 * @vert: Vertical alignment
Simon Glass6081b0f2023-06-01 10:22:50 -0600299 * @flags: Flags for this object
Simon Glass2b91ca62023-08-14 16:40:37 -0600300 * @bit_length: Number of bits used for this object in CMOS RAM
301 * @start_bit: Start bit to use for this object in CMOS RAM
Simon Glassd8adbe92023-01-06 08:52:36 -0600302 * @sibling: Node to link this object to its siblings
303 */
304struct scene_obj {
305 struct scene *scene;
306 char *name;
307 uint id;
308 enum scene_obj_t type;
Simon Glass854ca692025-05-02 08:46:30 -0600309 struct scene_obj_bbox bbox;
Simon Glass5beb0572025-05-02 08:46:45 -0600310 struct scene_obj_offset ofs;
Simon Glassebec4972025-05-02 08:46:33 -0600311 struct scene_obj_dims dims;
Simon Glass5beb0572025-05-02 08:46:45 -0600312 enum scene_obj_align horiz;
313 enum scene_obj_align vert;
Simon Glass2b91ca62023-08-14 16:40:37 -0600314 u8 flags;
315 u8 bit_length;
316 u16 start_bit;
Simon Glassd8adbe92023-01-06 08:52:36 -0600317 struct list_head sibling;
318};
319
Simon Glass193bfea2023-10-01 19:13:27 -0600320/* object can be highlighted when moving around expo */
321static inline bool scene_obj_can_highlight(const struct scene_obj *obj)
322{
323 return obj->type >= SCENEOBJT_MENU;
324}
325
Simon Glassd8adbe92023-01-06 08:52:36 -0600326/**
327 * struct scene_obj_img - information about an image object in a scene
328 *
329 * This is a rectangular image which is blitted onto the display
330 *
331 * @obj: Basic object information
332 * @data: Image data in BMP format
333 */
334struct scene_obj_img {
335 struct scene_obj obj;
336 char *data;
337};
338
339/**
Simon Glass9ef02aa2025-05-02 08:46:37 -0600340 * struct scene_txt_generic - Generic information common to text objects
Simon Glassd8adbe92023-01-06 08:52:36 -0600341 *
Simon Glassd8adbe92023-01-06 08:52:36 -0600342 * @str_id: ID of the text string to display
343 * @font_name: Name of font (allocated by caller)
344 * @font_size: Nominal size of font in pixels
Simon Glasscfb4f2c2025-05-02 08:46:42 -0600345 * @lines: alist of struct vidconsole_mline with a separate record for each
346 * line of text
Simon Glassd8adbe92023-01-06 08:52:36 -0600347 */
Simon Glass9ef02aa2025-05-02 08:46:37 -0600348struct scene_txt_generic {
Simon Glassd8adbe92023-01-06 08:52:36 -0600349 uint str_id;
350 const char *font_name;
351 uint font_size;
Simon Glasscfb4f2c2025-05-02 08:46:42 -0600352 struct alist lines;
Simon Glassd8adbe92023-01-06 08:52:36 -0600353};
354
355/**
Simon Glass9ef02aa2025-05-02 08:46:37 -0600356 * struct scene_obj_txt - information about a text object in a scene
357 *
358 * This is a single-line text object
359 *
360 * @obj: Basic object information
361 * @gen: Generic information common to all objects which show text
362 */
363struct scene_obj_txt {
364 struct scene_obj obj;
365 struct scene_txt_generic gen;
366};
367
368/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600369 * struct scene_obj_menu - information about a menu object in a scene
370 *
371 * A menu has a number of items which can be selected by the user
372 *
373 * It also has:
374 *
375 * - a text/image object (@pointer_id) which points to the current item
376 * (@cur_item_id)
377 *
378 * - a preview object which shows an image related to the current item
379 *
380 * @obj: Basic object information
381 * @title_id: ID of the title text, or 0 if none
382 * @cur_item_id: ID of the current menu item, or 0 if none
383 * @pointer_id: ID of the object pointing to the current selection
384 * @item_head: List of items in the menu
385 */
386struct scene_obj_menu {
387 struct scene_obj obj;
388 uint title_id;
389 uint cur_item_id;
390 uint pointer_id;
391 struct list_head item_head;
392};
393
394/**
395 * enum scene_menuitem_flags_t - flags for menu items
396 *
397 * @SCENEMIF_GAP_BEFORE: Add a gap before this item
398 */
399enum scene_menuitem_flags_t {
400 SCENEMIF_GAP_BEFORE = 1 << 0,
401};
402
403/**
404 * struct scene_menitem - a menu item in a menu
405 *
406 * A menu item has:
407 *
408 * - text object holding the name (short) and description (can be longer)
409 * - a text object holding the keypress
410 *
411 * @name: Name of the item (this is allocated by this call)
412 * @id: ID number of the object
413 * @key_id: ID of text object to use as the keypress to show
414 * @label_id: ID of text object to use as the label text
415 * @desc_id: ID of text object to use as the description text
416 * @preview_id: ID of the preview object, or 0 if none
417 * @flags: Flags for this item
Simon Glass100389f2024-10-14 16:31:58 -0600418 * @value: Value for this item, or INT_MAX to use sequence
Simon Glassd8adbe92023-01-06 08:52:36 -0600419 * @sibling: Node to link this item to its siblings
420 */
421struct scene_menitem {
422 char *name;
423 uint id;
424 uint key_id;
425 uint label_id;
426 uint desc_id;
427 uint preview_id;
428 uint flags;
Simon Glass100389f2024-10-14 16:31:58 -0600429 int value;
Simon Glassd8adbe92023-01-06 08:52:36 -0600430 struct list_head sibling;
431};
432
433/**
Simon Glass6116e762023-10-01 19:13:32 -0600434 * struct scene_obj_textline - information about a textline in a scene
435 *
436 * A textline has a prompt and a line of editable text
437 *
438 * @obj: Basic object information
439 * @label_id: ID of the label text, or 0 if none
440 * @edit_id: ID of the editable text
441 * @max_chars: Maximum number of characters allowed
442 * @buf: Text buffer containing current text
443 * @pos: Cursor position
444 */
445struct scene_obj_textline {
446 struct scene_obj obj;
447 uint label_id;
448 uint edit_id;
449 uint max_chars;
450 struct abuf buf;
451 uint pos;
452};
453
454/**
Simon Glass138a3972025-05-02 08:46:44 -0600455 * struct scene_obj_box - information about a box in a scene
456 *
457 * A box surrounds a part of the screen with a border
458 *
459 * @obj: Basic object information
460 * @width: Line-width in pixels
461 */
462struct scene_obj_box {
463 struct scene_obj obj;
464 uint width;
465};
466
467/**
Simon Glass377f18e2024-10-14 16:31:55 -0600468 * struct expo_arrange_info - Information used when arranging a scene
469 *
470 * @label_width: Maximum width of labels in scene
471 */
472struct expo_arrange_info {
473 int label_width;
474};
475
476/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600477 * expo_new() - create a new expo
478 *
479 * Allocates a new expo
480 *
481 * @name: Name of expo (this is allocated by this call)
482 * @priv: Private data for the controller
483 * @expp: Returns a pointer to the new expo on success
484 * Returns: 0 if OK, -ENOMEM if out of memory
485 */
486int expo_new(const char *name, void *priv, struct expo **expp);
487
488/**
489 * expo_destroy() - Destroy an expo and free all its memory
490 *
491 * @exp: Expo to destroy
492 */
493void expo_destroy(struct expo *exp);
494
495/**
Simon Glass6e9e4152023-06-01 10:22:47 -0600496 * expo_set_dynamic_start() - Set the start of the 'dynamic' IDs
497 *
498 * It is common for a set of 'static' IDs to be used to refer to objects in the
499 * expo. These typically use an enum so that they are defined in sequential
500 * order.
501 *
502 * Dynamic IDs (for objects not in the enum) are intended to be used for
503 * objects to which the code does not need to refer. These are ideally located
504 * above the static IDs.
505 *
506 * Use this function to set the start of the dynamic range, making sure that the
507 * value is higher than all the statically allocated IDs.
508 *
509 * @exp: Expo to update
510 * @dyn_start: Start ID that expo should use for dynamic allocation
511 */
512void expo_set_dynamic_start(struct expo *exp, uint dyn_start);
513
514/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600515 * expo_str() - add a new string to an expo
516 *
517 * @exp: Expo to update
518 * @name: Name to use (this is allocated by this call)
519 * @id: ID to use for the new object (0 to allocate one)
520 * @str: Pointer to text to display (allocated by caller)
521 * Returns: ID number for the object (typically @id), or -ve on error
522 */
523int expo_str(struct expo *exp, const char *name, uint id, const char *str);
524
525/**
526 * expo_get_str() - Get a string by ID
527 *
528 * @exp: Expo to use
529 * @id: String ID to look up
530 * @returns string, or NULL if not found
531 */
532const char *expo_get_str(struct expo *exp, uint id);
533
534/**
Simon Glassc5ae5b12025-05-02 08:46:40 -0600535 * expo_edit_str() - Make a string writeable
536 *
537 * This allows a string to be updated under the control of the caller. The
538 * buffer must remain valid while the expo is active.
539 *
540 * @exp: Expo to use
541 * @id: String ID to look up
542 * @orig: If non-NULL, returns the original buffer, which can be used by the
543 * caller. It is no-longer used by expo so must be uninited by the caller.
544 * It contains a snapshot of the string contents
545 * @copyp: Returns a pointer to the new, writeable buffer
546 * Return: 0 if OK, -ENOENT if the id was not found, -ENOMEM if out of memory
547 */
548int expo_edit_str(struct expo *exp, uint id, struct abuf *orig,
549 struct abuf **copyp);
550
551/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600552 * expo_set_display() - set the display to use for a expo
553 *
554 * @exp: Expo to update
555 * @dev: Display to use (`UCLASS_VIDEO`), NULL to use text mode
556 * Returns: 0 (always)
557 */
558int expo_set_display(struct expo *exp, struct udevice *dev);
559
560/**
Simon Glass7a960052023-06-01 10:22:52 -0600561 * expo_calc_dims() - Calculate the dimensions of the objects
562 *
563 * Updates the width and height of all objects based on their contents
564 *
565 * @exp: Expo to update
566 * Returns 0 if OK, -ENOTSUPP if there is no graphical console
567 */
568int expo_calc_dims(struct expo *exp);
569
570/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600571 * expo_set_scene_id() - Set the current scene ID
572 *
573 * @exp: Expo to update
574 * @scene_id: New scene ID to use (0 to select no scene)
575 * Returns: 0 if OK, -ENOENT if there is no scene with that ID
576 */
577int expo_set_scene_id(struct expo *exp, uint scene_id);
578
579/**
Simon Glassc8925112023-06-01 10:23:02 -0600580 * expo_first_scene_id() - Get the ID of the first scene
581 *
582 * @exp: Expo to check
583 * Returns: Scene ID of first scene, or -ENOENT if there are no scenes
584 */
585int expo_first_scene_id(struct expo *exp);
586
587/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600588 * expo_render() - render the expo on the display / console
589 *
590 * @exp: Expo to render
591 *
592 * Returns: 0 if OK, -ECHILD if there is no current scene, -ENOENT if the
593 * current scene is not found, other error if something else goes wrong
594 */
595int expo_render(struct expo *exp);
596
597/**
Simon Glassb2c40342023-06-01 10:22:37 -0600598 * expo_set_text_mode() - Controls whether the expo renders in text mode
Simon Glassd8adbe92023-01-06 08:52:36 -0600599 *
600 * @exp: Expo to update
601 * @text_mode: true to use text mode, false to use the console
602 */
Simon Glassb2c40342023-06-01 10:22:37 -0600603void expo_set_text_mode(struct expo *exp, bool text_mode);
Simon Glassd8adbe92023-01-06 08:52:36 -0600604
605/**
606 * scene_new() - create a new scene in a expo
607 *
608 * The scene is given the ID @id which must be unique across all scenes, objects
609 * and items. The expo's @next_id is updated to at least @id + 1
610 *
611 * @exp: Expo to update
612 * @name: Name to use (this is allocated by this call)
613 * @id: ID to use for the new scene (0 to allocate one)
614 * @scnp: Returns a pointer to the new scene on success
615 * Returns: ID number for the scene (typically @id), or -ve on error
616 */
617int scene_new(struct expo *exp, const char *name, uint id, struct scene **scnp);
618
619/**
620 * expo_lookup_scene_id() - Look up a scene by ID
621 *
622 * @exp: Expo to check
623 * @scene_id: Scene ID to look up
624 * @returns pointer to scene if found, else NULL
625 */
626struct scene *expo_lookup_scene_id(struct expo *exp, uint scene_id);
627
628/**
Simon Glass01922ec2023-06-01 10:22:57 -0600629 * scene_highlight_first() - Highlight the first item in a scene
630 *
631 * This highlights the first item, so that the user can see that it is pointed
632 * to
633 *
634 * @scn: Scene to update
635 */
636void scene_highlight_first(struct scene *scn);
637
638/**
639 * scene_set_highlight_id() - Set the object which is highlighted
640 *
641 * Sets a new object to highlight in the scene
642 *
643 * @scn: Scene to update
644 * @id: ID of object to highlight
645 */
646void scene_set_highlight_id(struct scene *scn, uint id);
647
648/**
649 * scene_set_open() - Set whether an item is open or not
650 *
651 * @scn: Scene to update
652 * @id: ID of object to update
653 * @open: true to open the object, false to close it
654 * Returns: 0 if OK, -ENOENT if @id is invalid
655 */
656int scene_set_open(struct scene *scn, uint id, bool open);
657
658/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600659 * scene_obj_count() - Count the number of objects in a scene
660 *
661 * @scn: Scene to check
662 * Returns: number of objects in the scene, 0 if none
663 */
664int scene_obj_count(struct scene *scn);
665
666/**
667 * scene_img() - add a new image to a scene
668 *
669 * @scn: Scene to update
670 * @name: Name to use (this is allocated by this call)
671 * @id: ID to use for the new object (0 to allocate one)
672 * @data: Pointer to image data
673 * @imgp: If non-NULL, returns the new object
674 * Returns: ID number for the object (typically @id), or -ve on error
675 */
676int scene_img(struct scene *scn, const char *name, uint id, char *data,
677 struct scene_obj_img **imgp);
678
679/**
680 * scene_txt() - add a new text object to a scene
681 *
682 * @scn: Scene to update
683 * @name: Name to use (this is allocated by this call)
684 * @id: ID to use for the new object (0 to allocate one)
685 * @str_id: ID of the string to use
686 * @txtp: If non-NULL, returns the new object
687 * Returns: ID number for the object (typically @id), or -ve on error
688 */
689int scene_txt(struct scene *scn, const char *name, uint id, uint str_id,
690 struct scene_obj_txt **txtp);
691
692/**
Simon Glassdb6a0512023-10-01 19:13:23 -0600693 * scene_txt_str() - add a new string to expo and text object to a scene
Simon Glassd8adbe92023-01-06 08:52:36 -0600694 *
695 * @scn: Scene to update
696 * @name: Name to use (this is allocated by this call)
697 * @id: ID to use for the new object (0 to allocate one)
698 * @str_id: ID of the string to use
699 * @str: Pointer to text to display (allocated by caller)
700 * @txtp: If non-NULL, returns the new object
701 * Returns: ID number for the object (typically @id), or -ve on error
702 */
703int scene_txt_str(struct scene *scn, const char *name, uint id, uint str_id,
704 const char *str, struct scene_obj_txt **txtp);
705
706/**
707 * scene_menu() - create a menu
708 *
709 * @scn: Scene to update
710 * @name: Name to use (this is allocated by this call)
711 * @id: ID to use for the new object (0 to allocate one)
712 * @menup: If non-NULL, returns the new object
713 * Returns: ID number for the object (typically @id), or -ve on error
714 */
715int scene_menu(struct scene *scn, const char *name, uint id,
716 struct scene_obj_menu **menup);
717
718/**
Simon Glass6116e762023-10-01 19:13:32 -0600719 * scene_textline() - create a textline
720 *
721 * @scn: Scene to update
722 * @name: Name to use (this is allocated by this call)
723 * @id: ID to use for the new object (0 to allocate one)
724 * @max_chars: Maximum length of the textline in characters
725 * @tlinep: If non-NULL, returns the new object
726 * Returns: ID number for the object (typically @id), or -ve on error
727 */
728int scene_textline(struct scene *scn, const char *name, uint id, uint max_chars,
729 struct scene_obj_textline **tlinep);
730
731/**
Simon Glass138a3972025-05-02 08:46:44 -0600732 * scene_box() - create a box
733 *
734 * @scn: Scene to update
735 * @name: Name to use (this is allocated by this call)
736 * @id: ID to use for the new object (0 to allocate one)
737 * @width: Line-width in pixels
738 * @boxp: If non-NULL, returns the new object
739 * Returns: ID number for the object (typically @id), or -ve on error
740 */
741int scene_box(struct scene *scn, const char *name, uint id, uint width,
742 struct scene_obj_box **boxp);
743
744/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600745 * scene_txt_set_font() - Set the font for an object
746 *
747 * @scn: Scene to update
748 * @id: ID of object to update
749 * @font_name: Font name to use (allocated by caller)
750 * @font_size: Font size to use (nominal height in pixels)
751 */
752int scene_txt_set_font(struct scene *scn, uint id, const char *font_name,
753 uint font_size);
754
755/**
756 * scene_obj_set_pos() - Set the postion of an object
757 *
758 * @scn: Scene to update
759 * @id: ID of object to update
760 * @x: x position, in pixels from left side
761 * @y: y position, in pixels from top
762 * Returns: 0 if OK, -ENOENT if @id is invalid
763 */
764int scene_obj_set_pos(struct scene *scn, uint id, int x, int y);
765
766/**
Simon Glass7a960052023-06-01 10:22:52 -0600767 * scene_obj_set_size() - Set the size of an object
768 *
769 * @scn: Scene to update
770 * @id: ID of object to update
771 * @w: width in pixels
772 * @h: height in pixels
773 * Returns: 0 if OK, -ENOENT if @id is invalid
774 */
775int scene_obj_set_size(struct scene *scn, uint id, int w, int h);
776
777/**
Simon Glassc6143dc2025-05-02 08:46:35 -0600778 * scene_obj_set_width() - Set the width of an object
779 *
780 * @scn: Scene to update
781 * @id: ID of object to update
782 * @w: width in pixels
783 * Returns: 0 if OK, -ENOENT if @id is invalid
784 */
785int scene_obj_set_width(struct scene *scn, uint id, int w);
786
787/**
788 * scene_obj_set_bbox() - Set the bounding box of an object
789 *
790 * @scn: Scene to update
791 * @id: ID of object to update
792 * @x0: x position, in pixels from left side
793 * @y0: y position, in pixels from top
794 * @x1: ending x position (right side)
795 * @y1: ending y position (botton side)
796 * Returns: 0 if OK, -ENOENT if @id is invalid
797 */
798int scene_obj_set_bbox(struct scene *scn, uint id, int x0, int y0, int x1,
799 int y1);
800
801/**
Simon Glass5beb0572025-05-02 08:46:45 -0600802 * scene_obj_set_halign() - Set the horizontal alignment of an object
803 *
804 * @scn: Scene to update
805 * @id: ID of object to update
806 * @aln: Horizontal alignment to use
807 * Returns: 0 if OK, -ENOENT if @id is invalid
808 */
809int scene_obj_set_halign(struct scene *scn, uint id, enum scene_obj_align aln);
810
811/**
812 * scene_obj_set_valign() - Set the vertical alignment of an object
813 *
814 * @scn: Scene to update
815 * @id: ID of object to update
816 * @aln: Vertical alignment to use
817 * Returns: 0 if OK, -ENOENT if @id is invalid
818 */
819int scene_obj_set_valign(struct scene *scn, uint id, enum scene_obj_align aln);
820
821/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600822 * scene_obj_set_hide() - Set whether an object is hidden
823 *
824 * The update happens when the expo is next rendered.
825 *
826 * @scn: Scene to update
827 * @id: ID of object to update
828 * @hide: true to hide the object, false to show it
829 * Returns: 0 if OK, -ENOENT if @id is invalid
830 */
831int scene_obj_set_hide(struct scene *scn, uint id, bool hide);
832
833/**
834 * scene_menu_set_title() - Set the title of a menu
835 *
836 * @scn: Scene to update
837 * @id: ID of menu object to update
838 * @title_id: ID of text object to use as the title
839 * Returns: 0 if OK, -ENOENT if @id is invalid, -EINVAL if @title_id is invalid
840 */
841int scene_menu_set_title(struct scene *scn, uint id, uint title_id);
842
843/**
844 * scene_menu_set_pointer() - Set the item pointer for a menu
845 *
846 * This is a visual indicator of the current item, typically a ">" character
847 * which sits next to the current item and moves when the user presses the
848 * up/down arrow keys
849 *
850 * @scn: Scene to update
851 * @id: ID of menu object to update
852 * @cur_item_id: ID of text or image object to use as a pointer to the current
853 * item
854 * Returns: 0 if OK, -ENOENT if @id is invalid, -EINVAL if @cur_item_id is invalid
855 */
856int scene_menu_set_pointer(struct scene *scn, uint id, uint cur_item_id);
857
858/**
Simon Glassbe04b962025-05-02 08:46:24 -0600859 * scene_menu_select_item() - move the pointer/highlight to an item
860 *
861 * @scn: Scene to update
862 * @id: ID of menu object to update
863 * @sel_id: ID of the menuitem to select
864 * Return 0 on success, -ENOENT if there was no such item
865 */
866int scene_menu_select_item(struct scene *scn, uint id, uint sel_id);
867
868/**
869 * scene_menu_get_cur_item() - get the currently pointed-to item
870 *
871 * @scn: Scene to update
872 * @id: ID of menu object to update
873 * Return ID of the current item the menu is pointing to, -ENOENT if @id is not
874 * valid, 0 if no item is pointed to
875 */
876int scene_menu_get_cur_item(struct scene *scn, uint id);
877
878/**
Simon Glassd8adbe92023-01-06 08:52:36 -0600879 * scene_obj_get_hw() - Get width and height of an object in a scene
880 *
881 * @scn: Scene to check
882 * @id: ID of menu object to check
883 * @widthp: If non-NULL, returns width of object in pixels
884 * Returns: Height of object in pixels
885 */
886int scene_obj_get_hw(struct scene *scn, uint id, int *widthp);
887
888/**
889 * scene_menuitem() - Add an item to a menu
890 *
891 * @scn: Scene to update
892 * @menu_id: ID of menu object to update
893 * @name: Name to use (this is allocated by this call)
894 * @id: ID to use for the new object (0 to allocate one)
895 * @key_id: ID of text object to use as the keypress to show
896 * @label_id: ID of text object to use as the label text
897 * @desc_id: ID of text object to use as the description text
898 * @preview_id: ID of object to use as the preview (text or image)
899 * @flags: Flags for this item (enum scene_menuitem_flags_t)
900 * @itemp: If non-NULL, returns the new object
901 * Returns: ID number for the item (typically @id), or -ve on error
902 */
903int scene_menuitem(struct scene *scn, uint menu_id, const char *name, uint id,
904 uint key_id, uint label_id, uint desc_id, uint preview_id,
905 uint flags, struct scene_menitem **itemp);
906
907/**
908 * scene_arrange() - Arrange the scene to deal with object sizes
909 *
910 * Updates any menus in the scene so that their objects are in the right place.
911 *
912 * @scn: Scene to arrange
913 * Returns: 0 if OK, -ve on error
914 */
915int scene_arrange(struct scene *scn);
916
917/**
918 * expo_send_key() - set a keypress to the expo
919 *
920 * @exp: Expo to receive the key
921 * @key: Key to send (ASCII or enum bootmenu_key)
922 * Returns: 0 if OK, -ECHILD if there is no current scene
923 */
924int expo_send_key(struct expo *exp, int key);
925
926/**
927 * expo_action_get() - read user input from the expo
928 *
929 * @exp: Expo to check
930 * @act: Returns action
931 * Returns: 0 if OK, -EAGAIN if there was no action to return
932 */
933int expo_action_get(struct expo *exp, struct expo_action *act);
934
Simon Glassc999e172023-06-01 10:22:53 -0600935/**
936 * expo_apply_theme() - Apply a theme to an expo
937 *
938 * @exp: Expo to update
939 * @node: Node containing the theme
940 */
941int expo_apply_theme(struct expo *exp, ofnode node);
942
Simon Glass61300722023-06-01 10:23:01 -0600943/**
944 * expo_build() - Build an expo from an FDT description
945 *
946 * Build a complete expo from a description in the provided devicetree.
947 *
Massimo Pegorerc8c70022023-09-09 12:32:28 +0200948 * See doc/develop/expo.rst for a description of the format
Simon Glass61300722023-06-01 10:23:01 -0600949 *
950 * @root: Root node for expo description
951 * @expp: Returns the new expo
952 * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
953 * error, -ENOENT if there is a references to a non-existent string
954 */
955int expo_build(ofnode root, struct expo **expp);
956
Simon Glass34344202024-10-14 16:32:11 -0600957/**
958 * cb_expo_build() - Build an expo for coreboot CMOS RAM
959 *
960 * @expp: Returns the expo created
961 * Return: 0 if OK, -ve on error
962 */
963int cb_expo_build(struct expo **expp);
964
Simon Glass137b4422025-05-02 08:46:16 -0600965/**
966 * expo_poll() - render an expo and see if the user takes an action
967 *
968 * Thsi calls expo_render() and then checks for a keypress. If there is one, it
969 * is processed and the resulting action returned, if any
970 *
971 * @exp: Expo to poll
972 * @act: Returns action on success
973 * Return: 0 if an action was obtained, -EAGAIN if not, other error if something
974 * went wrong
975 */
976int expo_poll(struct expo *exp, struct expo_action *act);
977
Simon Glass8df4a4e2023-08-14 16:40:25 -0600978#endif /*__EXPO_H */