Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


imported SEABIOS source tree
[palacios.git] / bios / seabios / tools / kconfig / lxdialog / checklist.c
1 /*
2  *  checklist.c -- implements the checklist box
3  *
4  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5  *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
6  *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
7  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
8  *
9  *  This program is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU General Public License
11  *  as published by the Free Software Foundation; either version 2
12  *  of the License, or (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "dialog.h"
25
26 static int list_width, check_x, item_x;
27
28 /*
29  * Print list item
30  */
31 static void print_item(WINDOW * win, int choice, int selected)
32 {
33         int i;
34         char *list_item = malloc(list_width + 1);
35
36         strncpy(list_item, item_str(), list_width - item_x);
37         list_item[list_width - item_x] = '\0';
38
39         /* Clear 'residue' of last item */
40         wattrset(win, dlg.menubox.atr);
41         wmove(win, choice, 0);
42         for (i = 0; i < list_width; i++)
43                 waddch(win, ' ');
44
45         wmove(win, choice, check_x);
46         wattrset(win, selected ? dlg.check_selected.atr
47                  : dlg.check.atr);
48         if (!item_is_tag(':'))
49                 wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
50
51         wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
52         mvwaddch(win, choice, item_x, list_item[0]);
53         wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
54         waddstr(win, list_item + 1);
55         if (selected) {
56                 wmove(win, choice, check_x + 1);
57                 wrefresh(win);
58         }
59         free(list_item);
60 }
61
62 /*
63  * Print the scroll indicators.
64  */
65 static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
66              int y, int x, int height)
67 {
68         wmove(win, y, x);
69
70         if (scroll > 0) {
71                 wattrset(win, dlg.uarrow.atr);
72                 waddch(win, ACS_UARROW);
73                 waddstr(win, "(-)");
74         } else {
75                 wattrset(win, dlg.menubox.atr);
76                 waddch(win, ACS_HLINE);
77                 waddch(win, ACS_HLINE);
78                 waddch(win, ACS_HLINE);
79                 waddch(win, ACS_HLINE);
80         }
81
82         y = y + height + 1;
83         wmove(win, y, x);
84
85         if ((height < item_no) && (scroll + choice < item_no - 1)) {
86                 wattrset(win, dlg.darrow.atr);
87                 waddch(win, ACS_DARROW);
88                 waddstr(win, "(+)");
89         } else {
90                 wattrset(win, dlg.menubox_border.atr);
91                 waddch(win, ACS_HLINE);
92                 waddch(win, ACS_HLINE);
93                 waddch(win, ACS_HLINE);
94                 waddch(win, ACS_HLINE);
95         }
96 }
97
98 /*
99  *  Display the termination buttons
100  */
101 static void print_buttons(WINDOW * dialog, int height, int width, int selected)
102 {
103         int x = width / 2 - 11;
104         int y = height - 2;
105
106         print_button(dialog, gettext("Select"), y, x, selected == 0);
107         print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
108
109         wmove(dialog, y, x + 1 + 14 * selected);
110         wrefresh(dialog);
111 }
112
113 /*
114  * Display a dialog box with a list of options that can be turned on or off
115  * in the style of radiolist (only one option turned on at a time).
116  */
117 int dialog_checklist(const char *title, const char *prompt, int height,
118                      int width, int list_height)
119 {
120         int i, x, y, box_x, box_y;
121         int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
122         WINDOW *dialog, *list;
123
124         /* which item to highlight */
125         item_foreach() {
126                 if (item_is_tag('X'))
127                         choice = item_n();
128                 if (item_is_selected()) {
129                         choice = item_n();
130                         break;
131                 }
132         }
133
134 do_resize:
135         if (getmaxy(stdscr) < (height + 6))
136                 return -ERRDISPLAYTOOSMALL;
137         if (getmaxx(stdscr) < (width + 6))
138                 return -ERRDISPLAYTOOSMALL;
139
140         max_choice = MIN(list_height, item_count());
141
142         /* center dialog box on screen */
143         x = (COLS - width) / 2;
144         y = (LINES - height) / 2;
145
146         draw_shadow(stdscr, y, x, height, width);
147
148         dialog = newwin(height, width, y, x);
149         keypad(dialog, TRUE);
150
151         draw_box(dialog, 0, 0, height, width,
152                  dlg.dialog.atr, dlg.border.atr);
153         wattrset(dialog, dlg.border.atr);
154         mvwaddch(dialog, height - 3, 0, ACS_LTEE);
155         for (i = 0; i < width - 2; i++)
156                 waddch(dialog, ACS_HLINE);
157         wattrset(dialog, dlg.dialog.atr);
158         waddch(dialog, ACS_RTEE);
159
160         print_title(dialog, title, width);
161
162         wattrset(dialog, dlg.dialog.atr);
163         print_autowrap(dialog, prompt, width - 2, 1, 3);
164
165         list_width = width - 6;
166         box_y = height - list_height - 5;
167         box_x = (width - list_width) / 2 - 1;
168
169         /* create new window for the list */
170         list = subwin(dialog, list_height, list_width, y + box_y + 1,
171                       x + box_x + 1);
172
173         keypad(list, TRUE);
174
175         /* draw a box around the list items */
176         draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
177                  dlg.menubox_border.atr, dlg.menubox.atr);
178
179         /* Find length of longest item in order to center checklist */
180         check_x = 0;
181         item_foreach()
182                 check_x = MAX(check_x, strlen(item_str()) + 4);
183         check_x = MIN(check_x, list_width);
184
185         check_x = (list_width - check_x) / 2;
186         item_x = check_x + 4;
187
188         if (choice >= list_height) {
189                 scroll = choice - list_height + 1;
190                 choice -= scroll;
191         }
192
193         /* Print the list */
194         for (i = 0; i < max_choice; i++) {
195                 item_set(scroll + i);
196                 print_item(list, i, i == choice);
197         }
198
199         print_arrows(dialog, choice, item_count(), scroll,
200                      box_y, box_x + check_x + 5, list_height);
201
202         print_buttons(dialog, height, width, 0);
203
204         wnoutrefresh(dialog);
205         wnoutrefresh(list);
206         doupdate();
207
208         while (key != KEY_ESC) {
209                 key = wgetch(dialog);
210
211                 for (i = 0; i < max_choice; i++) {
212                         item_set(i + scroll);
213                         if (toupper(key) == toupper(item_str()[0]))
214                                 break;
215                 }
216
217                 if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
218                     key == '+' || key == '-') {
219                         if (key == KEY_UP || key == '-') {
220                                 if (!choice) {
221                                         if (!scroll)
222                                                 continue;
223                                         /* Scroll list down */
224                                         if (list_height > 1) {
225                                                 /* De-highlight current first item */
226                                                 item_set(scroll);
227                                                 print_item(list, 0, FALSE);
228                                                 scrollok(list, TRUE);
229                                                 wscrl(list, -1);
230                                                 scrollok(list, FALSE);
231                                         }
232                                         scroll--;
233                                         item_set(scroll);
234                                         print_item(list, 0, TRUE);
235                                         print_arrows(dialog, choice, item_count(),
236                                                      scroll, box_y, box_x + check_x + 5, list_height);
237
238                                         wnoutrefresh(dialog);
239                                         wrefresh(list);
240
241                                         continue;       /* wait for another key press */
242                                 } else
243                                         i = choice - 1;
244                         } else if (key == KEY_DOWN || key == '+') {
245                                 if (choice == max_choice - 1) {
246                                         if (scroll + choice >= item_count() - 1)
247                                                 continue;
248                                         /* Scroll list up */
249                                         if (list_height > 1) {
250                                                 /* De-highlight current last item before scrolling up */
251                                                 item_set(scroll + max_choice - 1);
252                                                 print_item(list,
253                                                             max_choice - 1,
254                                                             FALSE);
255                                                 scrollok(list, TRUE);
256                                                 wscrl(list, 1);
257                                                 scrollok(list, FALSE);
258                                         }
259                                         scroll++;
260                                         item_set(scroll + max_choice - 1);
261                                         print_item(list, max_choice - 1, TRUE);
262
263                                         print_arrows(dialog, choice, item_count(),
264                                                      scroll, box_y, box_x + check_x + 5, list_height);
265
266                                         wnoutrefresh(dialog);
267                                         wrefresh(list);
268
269                                         continue;       /* wait for another key press */
270                                 } else
271                                         i = choice + 1;
272                         }
273                         if (i != choice) {
274                                 /* De-highlight current item */
275                                 item_set(scroll + choice);
276                                 print_item(list, choice, FALSE);
277                                 /* Highlight new item */
278                                 choice = i;
279                                 item_set(scroll + choice);
280                                 print_item(list, choice, TRUE);
281                                 wnoutrefresh(dialog);
282                                 wrefresh(list);
283                         }
284                         continue;       /* wait for another key press */
285                 }
286                 switch (key) {
287                 case 'H':
288                 case 'h':
289                 case '?':
290                         button = 1;
291                         /* fall-through */
292                 case 'S':
293                 case 's':
294                 case ' ':
295                 case '\n':
296                         item_foreach()
297                                 item_set_selected(0);
298                         item_set(scroll + choice);
299                         item_set_selected(1);
300                         delwin(list);
301                         delwin(dialog);
302                         return button;
303                 case TAB:
304                 case KEY_LEFT:
305                 case KEY_RIGHT:
306                         button = ((key == KEY_LEFT ? --button : ++button) < 0)
307                             ? 1 : (button > 1 ? 0 : button);
308
309                         print_buttons(dialog, height, width, button);
310                         wrefresh(dialog);
311                         break;
312                 case 'X':
313                 case 'x':
314                         key = KEY_ESC;
315                         break;
316                 case KEY_ESC:
317                         key = on_key_esc(dialog);
318                         break;
319                 case KEY_RESIZE:
320                         delwin(list);
321                         delwin(dialog);
322                         on_key_resize();
323                         goto do_resize;
324                 }
325
326                 /* Now, update everything... */
327                 doupdate();
328         }
329         delwin(list);
330         delwin(dialog);
331         return key;             /* ESC pressed */
332 }