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