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.


Ported palacios to Kbuild
[palacios.git] / scripts / 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, const char *item, int status, int choice,
32                        int selected)
33 {
34         int i;
35
36         /* Clear 'residue' of last item */
37         wattrset(win, menubox_attr);
38         wmove(win, choice, 0);
39         for (i = 0; i < list_width; i++)
40                 waddch(win, ' ');
41
42         wmove(win, choice, check_x);
43         wattrset(win, selected ? check_selected_attr : check_attr);
44         wprintw(win, "(%c)", status ? 'X' : ' ');
45
46         wattrset(win, selected ? tag_selected_attr : tag_attr);
47         mvwaddch(win, choice, item_x, item[0]);
48         wattrset(win, selected ? item_selected_attr : item_attr);
49         waddstr(win, (char *)item + 1);
50         if (selected) {
51                 wmove(win, choice, check_x + 1);
52                 wrefresh(win);
53         }
54 }
55
56 /*
57  * Print the scroll indicators.
58  */
59 static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
60              int y, int x, int height)
61 {
62         wmove(win, y, x);
63
64         if (scroll > 0) {
65                 wattrset(win, uarrow_attr);
66                 waddch(win, ACS_UARROW);
67                 waddstr(win, "(-)");
68         } else {
69                 wattrset(win, menubox_attr);
70                 waddch(win, ACS_HLINE);
71                 waddch(win, ACS_HLINE);
72                 waddch(win, ACS_HLINE);
73                 waddch(win, ACS_HLINE);
74         }
75
76         y = y + height + 1;
77         wmove(win, y, x);
78
79         if ((height < item_no) && (scroll + choice < item_no - 1)) {
80                 wattrset(win, darrow_attr);
81                 waddch(win, ACS_DARROW);
82                 waddstr(win, "(+)");
83         } else {
84                 wattrset(win, menubox_border_attr);
85                 waddch(win, ACS_HLINE);
86                 waddch(win, ACS_HLINE);
87                 waddch(win, ACS_HLINE);
88                 waddch(win, ACS_HLINE);
89         }
90 }
91
92 /*
93  *  Display the termination buttons
94  */
95 static void print_buttons(WINDOW * dialog, int height, int width, int selected)
96 {
97         int x = width / 2 - 11;
98         int y = height - 2;
99
100         print_button(dialog, "Select", y, x, selected == 0);
101         print_button(dialog, " Help ", y, x + 14, selected == 1);
102
103         wmove(dialog, y, x + 1 + 14 * selected);
104         wrefresh(dialog);
105 }
106
107 /*
108  * Display a dialog box with a list of options that can be turned on or off
109  * in the style of radiolist (only one option turned on at a time).
110  */
111 int dialog_checklist(const char *title, const char *prompt, int height,
112                      int width, int list_height, int item_no,
113                      const char *const *items)
114 {
115         int i, x, y, box_x, box_y;
116         int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
117         WINDOW *dialog, *list;
118
119         /* Allocate space for storing item on/off status */
120         if ((status = malloc(sizeof(int) * item_no)) == NULL) {
121                 endwin();
122                 fprintf(stderr,
123                         "\nCan't allocate memory in dialog_checklist().\n");
124                 exit(-1);
125         }
126
127         /* Initializes status */
128         for (i = 0; i < item_no; i++) {
129                 status[i] = !strcasecmp(items[i * 3 + 2], "on");
130                 if ((!choice && status[i])
131                     || !strcasecmp(items[i * 3 + 2], "selected"))
132                         choice = i + 1;
133         }
134         if (choice)
135                 choice--;
136
137         max_choice = MIN(list_height, item_no);
138
139         /* center dialog box on screen */
140         x = (COLS - width) / 2;
141         y = (LINES - height) / 2;
142
143         draw_shadow(stdscr, y, x, height, width);
144
145         dialog = newwin(height, width, y, x);
146         keypad(dialog, TRUE);
147
148         draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
149         wattrset(dialog, border_attr);
150         mvwaddch(dialog, height - 3, 0, ACS_LTEE);
151         for (i = 0; i < width - 2; i++)
152                 waddch(dialog, ACS_HLINE);
153         wattrset(dialog, dialog_attr);
154         waddch(dialog, ACS_RTEE);
155
156         print_title(dialog, title, width);
157
158         wattrset(dialog, dialog_attr);
159         print_autowrap(dialog, prompt, width - 2, 1, 3);
160
161         list_width = width - 6;
162         box_y = height - list_height - 5;
163         box_x = (width - list_width) / 2 - 1;
164
165         /* create new window for the list */
166         list = subwin(dialog, list_height, list_width, y + box_y + 1,
167                       x + box_x + 1);
168
169         keypad(list, TRUE);
170
171         /* draw a box around the list items */
172         draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
173                  menubox_border_attr, menubox_attr);
174
175         /* Find length of longest item in order to center checklist */
176         check_x = 0;
177         for (i = 0; i < item_no; i++)
178                 check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
179
180         check_x = (list_width - check_x) / 2;
181         item_x = check_x + 4;
182
183         if (choice >= list_height) {
184                 scroll = choice - list_height + 1;
185                 choice -= scroll;
186         }
187
188         /* Print the list */
189         for (i = 0; i < max_choice; i++) {
190                 print_item(list, items[(scroll + i) * 3 + 1],
191                            status[i + scroll], i, i == choice);
192         }
193
194         print_arrows(dialog, choice, item_no, scroll,
195                      box_y, box_x + check_x + 5, list_height);
196
197         print_buttons(dialog, height, width, 0);
198
199         wnoutrefresh(dialog);
200         wnoutrefresh(list);
201         doupdate();
202
203         while (key != ESC) {
204                 key = wgetch(dialog);
205
206                 for (i = 0; i < max_choice; i++)
207                         if (toupper(key) ==
208                             toupper(items[(scroll + i) * 3 + 1][0]))
209                                 break;
210
211                 if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
212                     key == '+' || key == '-') {
213                         if (key == KEY_UP || key == '-') {
214                                 if (!choice) {
215                                         if (!scroll)
216                                                 continue;
217                                         /* Scroll list down */
218                                         if (list_height > 1) {
219                                                 /* De-highlight current first item */
220                                                 print_item(list, items[scroll * 3 + 1],
221                                                            status[scroll], 0, FALSE);
222                                                 scrollok(list, TRUE);
223                                                 wscrl(list, -1);
224                                                 scrollok(list, FALSE);
225                                         }
226                                         scroll--;
227                                         print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
228                                         print_arrows(dialog, choice, item_no,
229                                                      scroll, box_y, box_x + check_x + 5, list_height);
230
231                                         wnoutrefresh(dialog);
232                                         wrefresh(list);
233
234                                         continue;       /* wait for another key press */
235                                 } else
236                                         i = choice - 1;
237                         } else if (key == KEY_DOWN || key == '+') {
238                                 if (choice == max_choice - 1) {
239                                         if (scroll + choice >= item_no - 1)
240                                                 continue;
241                                         /* Scroll list up */
242                                         if (list_height > 1) {
243                                                 /* De-highlight current last item before scrolling up */
244                                                 print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
245                                                            status[scroll + max_choice - 1],
246                                                            max_choice - 1, FALSE);
247                                                 scrollok(list, TRUE);
248                                                 wscrl(list, 1);
249                                                 scrollok(list, FALSE);
250                                         }
251                                         scroll++;
252                                         print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
253                                                    status[scroll + max_choice - 1], max_choice - 1, TRUE);
254
255                                         print_arrows(dialog, choice, item_no,
256                                                      scroll, box_y, box_x + check_x + 5, list_height);
257
258                                         wnoutrefresh(dialog);
259                                         wrefresh(list);
260
261                                         continue;       /* wait for another key press */
262                                 } else
263                                         i = choice + 1;
264                         }
265                         if (i != choice) {
266                                 /* De-highlight current item */
267                                 print_item(list, items[(scroll + choice) * 3 + 1],
268                                            status[scroll + choice], choice, FALSE);
269                                 /* Highlight new item */
270                                 choice = i;
271                                 print_item(list, items[(scroll + choice) * 3 + 1],
272                                            status[scroll + choice], choice, TRUE);
273                                 wnoutrefresh(dialog);
274                                 wrefresh(list);
275                         }
276                         continue;       /* wait for another key press */
277                 }
278                 switch (key) {
279                 case 'H':
280                 case 'h':
281                 case '?':
282                         fprintf(stderr, "%s", items[(scroll + choice) * 3]);
283                         delwin(dialog);
284                         free(status);
285                         return 1;
286                 case TAB:
287                 case KEY_LEFT:
288                 case KEY_RIGHT:
289                         button = ((key == KEY_LEFT ? --button : ++button) < 0)
290                             ? 1 : (button > 1 ? 0 : button);
291
292                         print_buttons(dialog, height, width, button);
293                         wrefresh(dialog);
294                         break;
295                 case 'S':
296                 case 's':
297                 case ' ':
298                 case '\n':
299                         if (!button) {
300                                 if (!status[scroll + choice]) {
301                                         for (i = 0; i < item_no; i++)
302                                                 status[i] = 0;
303                                         status[scroll + choice] = 1;
304                                         for (i = 0; i < max_choice; i++)
305                                                 print_item(list, items[(scroll + i) * 3 + 1],
306                                                            status[scroll + i], i, i == choice);
307                                 }
308                                 wnoutrefresh(dialog);
309                                 wrefresh(list);
310
311                                 for (i = 0; i < item_no; i++)
312                                         if (status[i])
313                                                 fprintf(stderr, "%s", items[i * 3]);
314                         } else
315                                 fprintf(stderr, "%s", items[(scroll + choice) * 3]);
316                         delwin(dialog);
317                         free(status);
318                         return button;
319                 case 'X':
320                 case 'x':
321                         key = ESC;
322                 case ESC:
323                         break;
324                 }
325
326                 /* Now, update everything... */
327                 doupdate();
328         }
329
330         delwin(dialog);
331         free(status);
332         return -1;              /* ESC pressed */
333 }