1 |
/* |
/* |
2 |
* GRUB -- GRand Unified Bootloader |
* GRUB -- GRand Unified Bootloader |
3 |
* Copyright (C) 2003 Free Software Foundation, Inc. |
* Copyright (C) 2003,2004 Free Software Foundation, Inc. |
4 |
* |
* |
5 |
* This program is free software; you can redistribute it and/or modify |
* 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 |
* it under the terms of the GNU General Public License as published by |
20 |
#include <grub/normal.h> |
#include <grub/normal.h> |
21 |
#include <grub/term.h> |
#include <grub/term.h> |
22 |
#include <grub/misc.h> |
#include <grub/misc.h> |
23 |
|
#include <grub/loader.h> |
24 |
|
#include <grub/machine/time.h> |
25 |
|
|
26 |
/* FIXME: These below are all runaround. */ |
/* FIXME: These below are all runaround. */ |
27 |
|
|
82 |
Press enter to boot the selected OS, \'e\' to edit the\n\ |
Press enter to boot the selected OS, \'e\' to edit the\n\ |
83 |
commands before booting, or \'c\' for a command-line."); |
commands before booting, or \'c\' for a command-line."); |
84 |
if (nested) |
if (nested) |
85 |
grub_printf ("\ |
grub_printf ("\n\ |
86 |
ESC to return previous menu."); |
ESC to return previous menu."); |
87 |
} |
} |
88 |
|
|
172 |
run_menu (grub_menu_t menu, int nested) |
run_menu (grub_menu_t menu, int nested) |
173 |
{ |
{ |
174 |
int first, offset; |
int first, offset; |
175 |
|
unsigned long saved_time; |
176 |
|
|
177 |
grub_setcursor (0); |
grub_setcursor (0); |
178 |
|
|
187 |
init_page (nested); |
init_page (nested); |
188 |
print_entries (menu, first, offset); |
print_entries (menu, first, offset); |
189 |
grub_refresh (); |
grub_refresh (); |
190 |
|
|
191 |
|
/* Initialize the time. */ |
192 |
|
saved_time = grub_get_rtc (); |
193 |
|
|
194 |
while (1) |
while (1) |
195 |
{ |
{ |
196 |
int c; |
int c; |
197 |
|
|
198 |
c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); |
if (menu->timeout > 0) |
|
switch (c) |
|
199 |
{ |
{ |
200 |
case 16: |
unsigned long current_time; |
201 |
case '^': |
|
202 |
if (offset > 0) |
current_time = grub_get_rtc (); |
203 |
|
if (current_time - saved_time >= GRUB_TICKS_PER_SECOND) |
204 |
{ |
{ |
205 |
print_entry (4 + offset, 0, get_entry (menu, first + offset)); |
menu->timeout--; |
206 |
offset--; |
saved_time = current_time; |
|
print_entry (4 + offset, 1, get_entry (menu, first + offset)); |
|
207 |
} |
} |
208 |
else if (first > 0) |
|
209 |
|
grub_gotoxy (3, 22); |
210 |
|
grub_printf ("The highlighted entry will be booted automatically in %d seconds. ", |
211 |
|
menu->timeout); |
212 |
|
grub_gotoxy (74, 4 + offset); |
213 |
|
grub_refresh (); |
214 |
|
} |
215 |
|
|
216 |
|
if (menu->timeout == 0) |
217 |
|
return menu->default_entry; |
218 |
|
|
219 |
|
if (grub_checkkey () >= 0 || menu->timeout < 0) |
220 |
|
{ |
221 |
|
c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); |
222 |
|
|
223 |
|
if (menu->timeout >= 0) |
224 |
{ |
{ |
225 |
first--; |
grub_gotoxy (3, 22); |
226 |
print_entries (menu, first, offset); |
grub_printf (" "); |
227 |
|
menu->timeout = -1; |
228 |
|
menu->fallback_entry = -1; |
229 |
|
grub_gotoxy (74, 4 + offset); |
230 |
} |
} |
231 |
break; |
|
232 |
|
switch (c) |
|
case 14: |
|
|
case 'v': |
|
|
if (menu->size > first + offset + 1) |
|
233 |
{ |
{ |
234 |
if (offset < 11) |
case 16: |
235 |
|
case '^': |
236 |
|
if (offset > 0) |
237 |
{ |
{ |
238 |
print_entry (4 + offset, 0, |
print_entry (4 + offset, 0, |
239 |
get_entry (menu, first + offset)); |
get_entry (menu, first + offset)); |
240 |
offset++; |
offset--; |
241 |
print_entry (4 + offset, 1, |
print_entry (4 + offset, 1, |
242 |
get_entry (menu, first + offset)); |
get_entry (menu, first + offset)); |
243 |
} |
} |
244 |
else |
else if (first > 0) |
245 |
{ |
{ |
246 |
first++; |
first--; |
247 |
print_entries (menu, first, offset); |
print_entries (menu, first, offset); |
248 |
} |
} |
249 |
} |
break; |
250 |
break; |
|
251 |
|
case 14: |
252 |
case '\n': |
case 'v': |
253 |
case '\r': |
if (menu->size > first + offset + 1) |
254 |
case 6: |
{ |
255 |
grub_setcursor (1); |
if (offset < 11) |
256 |
return first + offset; |
{ |
257 |
|
print_entry (4 + offset, 0, |
258 |
case '\e': |
get_entry (menu, first + offset)); |
259 |
if (nested) |
offset++; |
260 |
{ |
print_entry (4 + offset, 1, |
261 |
|
get_entry (menu, first + offset)); |
262 |
|
} |
263 |
|
else |
264 |
|
{ |
265 |
|
first++; |
266 |
|
print_entries (menu, first, offset); |
267 |
|
} |
268 |
|
} |
269 |
|
break; |
270 |
|
|
271 |
|
case '\n': |
272 |
|
case '\r': |
273 |
|
case 6: |
274 |
|
grub_setcursor (1); |
275 |
|
return first + offset; |
276 |
|
|
277 |
|
case '\e': |
278 |
|
if (nested) |
279 |
|
{ |
280 |
|
grub_setcursor (1); |
281 |
|
return -1; |
282 |
|
} |
283 |
|
break; |
284 |
|
|
285 |
|
case 'c': |
286 |
grub_setcursor (1); |
grub_setcursor (1); |
287 |
return -1; |
grub_cmdline_run (1); |
288 |
|
grub_setcursor (0); |
289 |
|
init_page (nested); |
290 |
|
print_entries (menu, first, offset); |
291 |
|
break; |
292 |
|
|
293 |
|
default: |
294 |
|
break; |
295 |
} |
} |
296 |
break; |
|
297 |
|
grub_refresh (); |
298 |
|
} |
299 |
|
} |
300 |
|
|
301 |
case 'c': |
/* Never reach here. */ |
302 |
grub_setcursor (1); |
return -1; |
303 |
grub_cmdline_run (1); |
} |
|
grub_setcursor (0); |
|
|
init_page (nested); |
|
|
print_entries (menu, first, offset); |
|
|
break; |
|
304 |
|
|
305 |
default: |
/* Run a menu entry. */ |
306 |
|
static void |
307 |
|
run_menu_entry (grub_menu_entry_t entry) |
308 |
|
{ |
309 |
|
grub_command_list_t cl; |
310 |
|
|
311 |
|
for (cl = entry->command_list; cl != 0; cl = cl->next) |
312 |
|
{ |
313 |
|
grub_command_t c; |
314 |
|
|
315 |
|
c = grub_command_find (cl->command); |
316 |
|
if (! c) |
317 |
|
break; |
318 |
|
|
319 |
|
if (! (c->flags & GRUB_COMMAND_FLAG_CMDLINE)) |
320 |
|
{ |
321 |
|
grub_error (GRUB_ERR_INVALID_COMMAND, |
322 |
|
"invalid command `%s'", |
323 |
|
cl->command); |
324 |
break; |
break; |
325 |
} |
} |
326 |
|
|
327 |
grub_refresh (); |
if (! (c->flags & GRUB_COMMAND_FLAG_NO_ECHO)) |
328 |
|
grub_printf ("%s\n", cl->command); |
329 |
|
|
330 |
|
if (grub_command_execute (cl->command) != 0) |
331 |
|
break; |
332 |
} |
} |
333 |
|
|
334 |
/* Never reach here. */ |
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) |
335 |
return -1; |
/* Implicit execution of boot, only if something is loaded. */ |
336 |
|
grub_command_execute ("boot"); |
337 |
} |
} |
338 |
|
|
339 |
void |
void |
342 |
while (1) |
while (1) |
343 |
{ |
{ |
344 |
int boot_entry; |
int boot_entry; |
345 |
|
grub_menu_entry_t e; |
346 |
|
|
347 |
boot_entry = run_menu (menu, nested); |
boot_entry = run_menu (menu, nested); |
348 |
if (boot_entry < 0) |
if (boot_entry < 0) |
349 |
break; |
break; |
350 |
|
|
351 |
/* FIXME: Boot the entry. */ |
grub_cls (); |
352 |
|
grub_setcursor (1); |
353 |
|
|
354 |
|
e = get_entry (menu, boot_entry); |
355 |
|
grub_printf (" Booting \'%s\'\n\n", e->title); |
356 |
|
|
357 |
|
run_menu_entry (e); |
358 |
|
|
359 |
|
/* Deal with a fallback entry. */ |
360 |
|
/* FIXME: Mutiple fallback entries like GRUB Legacy. */ |
361 |
|
if (menu->fallback_entry >= 0) |
362 |
|
{ |
363 |
|
grub_print_error (); |
364 |
|
grub_errno = GRUB_ERR_NONE; |
365 |
|
|
366 |
|
e = get_entry (menu, menu->fallback_entry); |
367 |
|
menu->fallback_entry = -1; |
368 |
|
grub_printf ("\n Falling back to \'%s\'\n\n", e->title); |
369 |
|
run_menu_entry (e); |
370 |
|
} |
371 |
|
|
372 |
|
if (grub_errno != GRUB_ERR_NONE) |
373 |
|
{ |
374 |
|
grub_print_error (); |
375 |
|
grub_errno = GRUB_ERR_NONE; |
376 |
|
|
377 |
|
/* Wait until the user pushes any key so that the user |
378 |
|
can see what happened. */ |
379 |
|
grub_printf ("\nPress any key to continue..."); |
380 |
|
(void) grub_getkey (); |
381 |
|
} |
382 |
} |
} |
383 |
} |
} |