]> git.ozlabs.org Git - petitboot/blob - ui/ncurses/nc-boot-editor.c
ui/ncurses: Add descriptive text for configuration editor
[petitboot] / ui / ncurses / nc-boot-editor.c
1 /*
2  *  Copyright (C) 2009 Sony Computer Entertainment Inc.
3  *  Copyright 2009 Sony Corp.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; version 2 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include "config.h"
20
21 #define _GNU_SOURCE
22
23 #include <assert.h>
24 #include <string.h>
25
26 #include "log/log.h"
27 #include "talloc/talloc.h"
28 #include "nc-boot-editor.h"
29 #include "nc-widgets.h"
30
31 static struct boot_editor *boot_editor_from_scr(struct nc_scr *scr)
32 {
33         struct boot_editor *boot_editor;
34
35         assert(scr->sig == pb_boot_editor_sig);
36         boot_editor = (struct boot_editor *)
37                 ((char *)scr - (size_t)&((struct boot_editor *)0)->scr);
38         assert(boot_editor->scr.sig == pb_boot_editor_sig);
39         return boot_editor;
40 }
41
42 static struct boot_editor *boot_editor_from_arg(void *arg)
43 {
44         struct boot_editor *boot_editor = arg;
45
46         assert(boot_editor->scr.sig == pb_boot_editor_sig);
47         return boot_editor;
48 }
49
50 static int boot_editor_post(struct nc_scr *scr)
51 {
52         struct boot_editor *boot_editor = boot_editor_from_scr(scr);
53
54         widgetset_post(boot_editor->widgetset);
55         nc_scr_frame_draw(scr);
56         redrawwin(boot_editor->scr.main_ncw);
57         wrefresh(boot_editor->scr.main_ncw);
58
59         return 0;
60 }
61
62 static int boot_editor_unpost(struct nc_scr *scr)
63 {
64         widgetset_unpost(boot_editor_from_scr(scr)->widgetset);
65         return 0;
66 }
67
68 static void boot_editor_resize(struct nc_scr *scr)
69 {
70         /* FIXME: forms can't be resized, need to recreate here */
71         boot_editor_unpost(scr);
72         boot_editor_post(scr);
73 }
74
75 static struct pb_boot_data *boot_editor_prepare_data(
76                 struct boot_editor *boot_editor)
77 {
78         struct pb_boot_data *bd;
79         char *s;
80
81         bd = talloc(boot_editor, struct pb_boot_data);
82
83         if (!bd)
84                 return NULL;
85
86         s = widget_textbox_get_value(boot_editor->widgets.image_f);
87         bd->image = *s ? talloc_strdup(bd, s) : NULL;
88
89         s = widget_textbox_get_value(boot_editor->widgets.initrd_f);
90         bd->initrd = *s ? talloc_strdup(bd, s) : NULL;
91
92         s = widget_textbox_get_value(boot_editor->widgets.dtb_f);
93         bd->dtb = *s ? talloc_strdup(bd, s) : NULL;
94
95         s = widget_textbox_get_value(boot_editor->widgets.args_f);
96         bd->args = *s ? talloc_strdup(bd, s) : NULL;
97
98         return bd;
99 }
100
101 /**
102  * boot_editor_process_key - Process a user keystroke.
103  *
104  * Called from the cui via the scr:process_key method.
105  */
106
107 static void boot_editor_process_key(struct nc_scr *scr, int key)
108 {
109         struct boot_editor *boot_editor = boot_editor_from_scr(scr);
110         bool handled;
111
112         handled = widgetset_process_key(boot_editor->widgetset, key);
113         if (handled) {
114                 wrefresh(boot_editor->scr.main_ncw);
115                 return;
116         }
117
118         switch (key) {
119         case 'x':
120         case 27: /* ESC */
121                 boot_editor->on_exit(boot_editor, boot_editor_cancel, NULL);
122                 nc_flush_keys();
123         }
124 }
125
126 /**
127  * boot_editor_destructor - The talloc destructor for a boot_editor.
128  */
129
130 static int boot_editor_destructor(void *arg)
131 {
132         struct boot_editor *boot_editor = boot_editor_from_arg(arg);
133         boot_editor->scr.sig = pb_removed_sig;
134         return 0;
135 }
136
137 static void ok_click(void *arg)
138 {
139         struct boot_editor *boot_editor = arg;
140         struct pb_boot_data *bd;
141
142         bd = boot_editor_prepare_data(boot_editor);
143         boot_editor->on_exit(boot_editor, boot_editor_update, bd);
144 }
145
146 static void cancel_click(void *arg)
147 {
148         struct boot_editor *boot_editor = arg;
149         boot_editor->on_exit(boot_editor, boot_editor_cancel, NULL);
150 }
151
152 struct boot_editor *boot_editor_init(struct pmenu *menu,
153                 const struct pb_boot_data *bd,
154                 void (*on_exit)(struct boot_editor *,
155                                 enum boot_editor_result,
156                                 struct pb_boot_data *))
157 {
158         int y, field_size, label_x = 1, field_x = 9;
159         char *image, *initrd, *dtb, *args;
160         struct boot_editor *boot_editor;
161         struct nc_widgetset *set;
162
163         assert(on_exit);
164
165         boot_editor = talloc_zero(menu, struct boot_editor);
166
167         if (!boot_editor)
168                 return NULL;
169
170         talloc_set_destructor(boot_editor, boot_editor_destructor);
171         boot_editor->original_pmenu = menu;
172
173         nc_scr_init(&boot_editor->scr, pb_boot_editor_sig, 0,
174                         menu, boot_editor_process_key,
175                 boot_editor_post, boot_editor_unpost, boot_editor_resize);
176
177         boot_editor->scr.frame.ltitle = talloc_strdup(boot_editor,
178                         "Petitboot Option Editor");
179         boot_editor->scr.frame.rtitle = NULL;
180         boot_editor->scr.frame.help = talloc_strdup(boot_editor,
181                         "Enter=accept");
182
183         boot_editor->on_exit = on_exit;
184
185         if (bd) {
186                 image = bd->image;
187                 initrd = bd->initrd;
188                 dtb = bd->dtb;
189                 args = bd->args;
190         } else {
191                 image = initrd = dtb = args = "";
192         }
193
194         y = 0;
195         field_size = COLS - 1 - field_x;
196
197         boot_editor->widgetset = set = widgetset_create(boot_editor,
198                         boot_editor->scr.main_ncw,
199                         boot_editor->scr.sub_ncw);
200
201         boot_editor->widgets.image_l = widget_new_label(set, y,
202                                         label_x, "image:");
203         boot_editor->widgets.image_f = widget_new_textbox(set, y,
204                                         field_x, field_size, image);
205
206         y++;
207         boot_editor->widgets.initrd_l = widget_new_label(set, y,
208                                         label_x, "initrd:");
209         boot_editor->widgets.initrd_f = widget_new_textbox(set, y,
210                                         field_x, field_size, initrd);
211
212         y++;
213         boot_editor->widgets.dtb_l = widget_new_label(set, y,
214                                         label_x, "dtb:");
215         boot_editor->widgets.dtb_f = widget_new_textbox(set, y,
216                                         field_x, field_size, dtb);
217
218         y++;
219         boot_editor->widgets.args_l = widget_new_label(set, y,
220                                         label_x, "args:");
221         boot_editor->widgets.args_f = widget_new_textbox(set, y,
222                                         field_x, field_size, args);
223
224         y++;
225         y++;
226         boot_editor->widgets.ok_b = widget_new_button(set, y,
227                                         9, 6, "OK", ok_click, boot_editor);
228         boot_editor->widgets.cancel_b = widget_new_button(set, y,
229                                         19, 6, "Cancel", cancel_click,
230                                         boot_editor);
231
232         return boot_editor;
233 }