blob: ee24658917bc123c6eec97a89917905c08f42958 [file] [log] [blame]
Simon Glassa0874dc2023-06-01 10:23:02 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Implementation of configuration editor
4 *
5 * Copyright 2023 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
9#include <common.h>
10#include <cli.h>
11#include <dm.h>
12#include <expo.h>
13#include <menu.h>
14#include <video.h>
15#include <linux/delay.h>
16#include "scene_internal.h"
17
18int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id)
19{
20 struct scene_obj_txt *txt;
21 struct scene_obj *obj;
22 struct scene *scn;
23 int y;
24
25 scn = expo_lookup_scene_id(exp, scene_id);
26 if (!scn)
27 return log_msg_ret("scn", -ENOENT);
28
29 txt = scene_obj_find_by_name(scn, "prompt");
30 if (txt)
31 scene_obj_set_pos(scn, txt->obj.id, 0, vpriv->ysize - 50);
32
33 txt = scene_obj_find_by_name(scn, "title");
34 if (txt)
35 scene_obj_set_pos(scn, txt->obj.id, 200, 10);
36
37 y = 100;
38 list_for_each_entry(obj, &scn->obj_head, sibling) {
39 if (obj->type == SCENEOBJT_MENU) {
40 scene_obj_set_pos(scn, obj->id, 50, y);
41 scene_menu_arrange(scn, (struct scene_obj_menu *)obj);
42 y += 50;
43 }
44 }
45
46 return 0;
47}
48
49int cedit_run(struct expo *exp)
50{
51 struct cli_ch_state s_cch, *cch = &s_cch;
52 struct video_priv *vid_priv;
53 uint scene_id;
54 struct udevice *dev;
55 struct scene *scn;
56 bool done;
57 int ret;
58
59 cli_ch_init(cch);
60
61 /* For now we only support a video console */
62 ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
63 if (ret)
64 return log_msg_ret("vid", ret);
65 ret = expo_set_display(exp, dev);
66 if (ret)
67 return log_msg_ret("dis", ret);
68
69 ret = expo_first_scene_id(exp);
70 if (ret < 0)
71 return log_msg_ret("scn", ret);
72 scene_id = ret;
73
74 ret = expo_set_scene_id(exp, scene_id);
75 if (ret)
76 return log_msg_ret("sid", ret);
77
78 exp->popup = true;
79
80 /* This is not supported for now */
81 if (0)
82 expo_set_text_mode(exp, true);
83
84 vid_priv = dev_get_uclass_priv(dev);
85
86 scn = expo_lookup_scene_id(exp, scene_id);
87 scene_highlight_first(scn);
88
89 cedit_arange(exp, vid_priv, scene_id);
90
91 ret = expo_calc_dims(exp);
92 if (ret)
93 return log_msg_ret("dim", ret);
94
95 done = false;
96 do {
97 struct expo_action act;
98 int ichar, key;
99
100 ret = expo_render(exp);
101 if (ret)
102 break;
103
104 ichar = cli_ch_process(cch, 0);
105 if (!ichar) {
106 while (!ichar && !tstc()) {
107 schedule();
108 mdelay(2);
109 ichar = cli_ch_process(cch, -ETIMEDOUT);
110 }
111 if (!ichar) {
112 ichar = getchar();
113 ichar = cli_ch_process(cch, ichar);
114 }
115 }
116
117 key = 0;
118 if (ichar) {
119 key = bootmenu_conv_key(ichar);
120 if (key == BKEY_NONE)
121 key = ichar;
122 }
123 if (!key)
124 continue;
125
126 ret = expo_send_key(exp, key);
127 if (ret)
128 break;
129
130 ret = expo_action_get(exp, &act);
131 if (!ret) {
132 switch (act.type) {
133 case EXPOACT_POINT_OBJ:
134 scene_set_highlight_id(scn, act.select.id);
135 cedit_arange(exp, vid_priv, scene_id);
136 break;
137 case EXPOACT_OPEN:
138 scene_set_open(scn, act.select.id, true);
139 cedit_arange(exp, vid_priv, scene_id);
140 break;
141 case EXPOACT_CLOSE:
142 scene_set_open(scn, act.select.id, false);
143 cedit_arange(exp, vid_priv, scene_id);
144 break;
145 case EXPOACT_SELECT:
146 scene_set_open(scn, scn->highlight_id, false);
147 cedit_arange(exp, vid_priv, scene_id);
148 break;
149 case EXPOACT_QUIT:
150 log_debug("quitting\n");
151 done = true;
152 break;
153 default:
154 break;
155 }
156 }
157 } while (!done);
158
159 if (ret)
160 return log_msg_ret("end", ret);
161
162 return 0;
163}