24 |
#include <grub/mm.h> |
#include <grub/mm.h> |
25 |
#include <grub/machine/time.h> |
#include <grub/machine/time.h> |
26 |
|
|
|
/* FIXME: These below are all runaround. */ |
|
|
|
|
|
#define DISP_LEFT 0x2190 |
|
|
#define DISP_UP 0x2191 |
|
|
#define DISP_RIGHT 0x2192 |
|
|
#define DISP_DOWN 0x2193 |
|
|
#define DISP_HLINE 0x2501 |
|
|
#define DISP_VLINE 0x2503 |
|
|
#define DISP_UL 0x250F |
|
|
#define DISP_UR 0x2513 |
|
|
#define DISP_LL 0x2517 |
|
|
#define DISP_LR 0x251B |
|
|
|
|
|
/* FIXME: These should be dynamically obtained from a terminal. */ |
|
|
#define TERM_WIDTH 80 |
|
|
#define TERM_HEIGHT 25 |
|
|
|
|
|
/* The number of lines of "GRUB version..." at the top. */ |
|
|
#define TERM_INFO_HEIGHT 1 |
|
|
|
|
|
/* The number of columns/lines between messages/borders/etc. */ |
|
|
#define TERM_MARGIN 1 |
|
|
|
|
|
/* The number of columns of scroll information. */ |
|
|
#define TERM_SCROLL_WIDTH 1 |
|
|
|
|
|
/* The Y position of the top border. */ |
|
|
#define TERM_TOP_BORDER_Y (TERM_MARGIN + TERM_INFO_HEIGHT + TERM_MARGIN) |
|
|
|
|
|
/* The X position of the left border. */ |
|
|
#define TERM_LEFT_BORDER_X TERM_MARGIN |
|
|
|
|
|
/* The width of the border. */ |
|
|
#define TERM_BORDER_WIDTH (TERM_WIDTH \ |
|
|
- TERM_MARGIN * 3 \ |
|
|
- TERM_SCROLL_WIDTH) |
|
|
|
|
|
/* The number of lines of messages at the bottom. */ |
|
|
#define TERM_MESSAGE_HEIGHT 8 |
|
|
|
|
|
/* The height of the border. */ |
|
|
#define TERM_BORDER_HEIGHT (TERM_HEIGHT \ |
|
|
- TERM_TOP_BORDER_Y \ |
|
|
- TERM_MESSAGE_HEIGHT) |
|
|
|
|
|
/* The number of entries shown at a time. */ |
|
|
#define TERM_NUM_ENTRIES (TERM_BORDER_HEIGHT - 2) |
|
|
|
|
|
/* The Y position of the first entry. */ |
|
|
#define TERM_FIRST_ENTRY_Y (TERM_TOP_BORDER_Y + 1) |
|
|
|
|
|
/* The max column number of an entry. The last "-1" is for a |
|
|
continuation marker. */ |
|
|
#define TERM_ENTRY_WIDTH (TERM_BORDER_WIDTH - 2 - TERM_MARGIN * 2 - 1) |
|
|
|
|
|
/* The standard X position of the cursor. */ |
|
|
#define TERM_CURSOR_X (TERM_LEFT_BORDER_X \ |
|
|
+ TERM_BORDER_WIDTH \ |
|
|
- TERM_MARGIN \ |
|
|
- 1) |
|
|
|
|
27 |
static void |
static void |
28 |
draw_border (void) |
draw_border (void) |
29 |
{ |
{ |
31 |
|
|
32 |
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); |
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); |
33 |
|
|
34 |
grub_gotoxy (TERM_MARGIN, TERM_TOP_BORDER_Y); |
grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y); |
35 |
grub_putcode (DISP_UL); |
grub_putcode (GRUB_TERM_DISP_UL); |
36 |
for (i = 0; i < TERM_BORDER_WIDTH - 2; i++) |
for (i = 0; i < GRUB_TERM_BORDER_WIDTH - 2; i++) |
37 |
grub_putcode (DISP_HLINE); |
grub_putcode (GRUB_TERM_DISP_HLINE); |
38 |
grub_putcode (DISP_UR); |
grub_putcode (GRUB_TERM_DISP_UR); |
39 |
|
|
40 |
for (i = 0; i < (unsigned) TERM_NUM_ENTRIES; i++) |
for (i = 0; i < (unsigned) GRUB_TERM_NUM_ENTRIES; i++) |
41 |
{ |
{ |
42 |
grub_gotoxy (TERM_MARGIN, TERM_TOP_BORDER_Y + i + 1); |
grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1); |
43 |
grub_putcode (DISP_VLINE); |
grub_putcode (GRUB_TERM_DISP_VLINE); |
44 |
grub_gotoxy (TERM_MARGIN + TERM_BORDER_WIDTH - 1, TERM_TOP_BORDER_Y + i + 1); |
grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1, GRUB_TERM_TOP_BORDER_Y + i + 1); |
45 |
grub_putcode (DISP_VLINE); |
grub_putcode (GRUB_TERM_DISP_VLINE); |
46 |
} |
} |
47 |
|
|
48 |
grub_gotoxy (TERM_MARGIN, TERM_TOP_BORDER_Y + TERM_NUM_ENTRIES + 1); |
grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1); |
49 |
grub_putcode (DISP_LL); |
grub_putcode (GRUB_TERM_DISP_LL); |
50 |
for (i = 0; i < TERM_BORDER_WIDTH - 2; i++) |
for (i = 0; i < GRUB_TERM_BORDER_WIDTH - 2; i++) |
51 |
grub_putcode (DISP_HLINE); |
grub_putcode (GRUB_TERM_DISP_HLINE); |
52 |
grub_putcode (DISP_LR); |
grub_putcode (GRUB_TERM_DISP_LR); |
53 |
|
|
54 |
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); |
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); |
55 |
|
|
56 |
grub_gotoxy (TERM_MARGIN, TERM_TOP_BORDER_Y + TERM_NUM_ENTRIES + TERM_MARGIN + 1); |
grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + GRUB_TERM_MARGIN + 1); |
57 |
} |
} |
58 |
|
|
59 |
static void |
static void |
70 |
{ |
{ |
71 |
grub_printf ("\n\ |
grub_printf ("\n\ |
72 |
Use the %C and %C keys to select which entry is highlighted.\n", |
Use the %C and %C keys to select which entry is highlighted.\n", |
73 |
(grub_uint32_t) DISP_UP, (grub_uint32_t) DISP_DOWN); |
(grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t) GRUB_TERM_DISP_DOWN); |
74 |
grub_printf ("\ |
grub_printf ("\ |
75 |
Press enter to boot the selected OS, \'e\' to edit the\n\ |
Press enter to boot the selected OS, \'e\' to edit the\n\ |
76 |
commands before booting or \'c\' for a command-line."); |
commands before booting or \'c\' for a command-line."); |
104 |
? GRUB_TERM_COLOR_HIGHLIGHT |
? GRUB_TERM_COLOR_HIGHLIGHT |
105 |
: GRUB_TERM_COLOR_NORMAL); |
: GRUB_TERM_COLOR_NORMAL); |
106 |
|
|
107 |
grub_gotoxy (TERM_LEFT_BORDER_X + TERM_MARGIN, y); |
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y); |
108 |
grub_putchar (' '); |
|
109 |
for (x = TERM_LEFT_BORDER_X + TERM_MARGIN + 1; |
for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1; |
110 |
x < TERM_LEFT_BORDER_X + TERM_BORDER_WIDTH - TERM_MARGIN; |
x < GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN; |
111 |
x++) |
x++) |
112 |
{ |
{ |
113 |
if (*title && x <= TERM_LEFT_BORDER_X + TERM_BORDER_WIDTH - TERM_MARGIN - 1) |
if (*title && x <= GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN - 1) |
114 |
{ |
{ |
115 |
if (x == TERM_LEFT_BORDER_X + TERM_BORDER_WIDTH - TERM_MARGIN - 1) |
if (x == GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN - 1) |
116 |
grub_putcode (DISP_RIGHT); |
grub_putcode (GRUB_TERM_DISP_RIGHT); |
117 |
else |
else |
118 |
grub_putchar (*title++); |
grub_putchar (*title++); |
119 |
} |
} |
120 |
else |
else |
121 |
grub_putchar (' '); |
grub_putchar (' '); |
122 |
} |
} |
123 |
grub_gotoxy (TERM_CURSOR_X, y); |
grub_gotoxy (GRUB_TERM_CURSOR_X, y); |
124 |
|
|
125 |
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); |
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); |
126 |
} |
} |
131 |
grub_menu_entry_t e; |
grub_menu_entry_t e; |
132 |
int i; |
int i; |
133 |
|
|
134 |
grub_gotoxy (TERM_LEFT_BORDER_X + TERM_BORDER_WIDTH, |
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, |
135 |
TERM_FIRST_ENTRY_Y); |
GRUB_TERM_FIRST_ENTRY_Y); |
136 |
|
|
137 |
if (first) |
if (first) |
138 |
grub_putcode (DISP_UP); |
grub_putcode (GRUB_TERM_DISP_UP); |
139 |
else |
else |
140 |
grub_putchar (' '); |
grub_putchar (' '); |
141 |
|
|
142 |
e = get_entry (menu, first); |
e = get_entry (menu, first); |
143 |
|
|
144 |
for (i = 0; i < TERM_NUM_ENTRIES; i++) |
for (i = 0; i < GRUB_TERM_NUM_ENTRIES; i++) |
145 |
{ |
{ |
146 |
print_entry (TERM_FIRST_ENTRY_Y + i, offset == i, e); |
print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e); |
147 |
if (e) |
if (e) |
148 |
e = e->next; |
e = e->next; |
149 |
} |
} |
150 |
|
|
151 |
grub_gotoxy (TERM_LEFT_BORDER_X + TERM_BORDER_WIDTH, |
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, |
152 |
TERM_TOP_BORDER_Y + TERM_NUM_ENTRIES); |
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES); |
153 |
|
|
154 |
if (e) |
if (e) |
155 |
grub_putcode (DISP_DOWN); |
grub_putcode (GRUB_TERM_DISP_DOWN); |
156 |
else |
else |
157 |
grub_putchar (' '); |
grub_putchar (' '); |
158 |
|
|
159 |
grub_gotoxy (TERM_CURSOR_X, TERM_FIRST_ENTRY_Y + offset); |
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); |
160 |
} |
} |
161 |
|
|
162 |
static void |
/* Initialize the screen. If NESTED is non-zero, assume that this menu |
163 |
init_page (int nested, int edit) |
is run from another menu or a command-line. If EDIT is non-zero, show |
164 |
|
a message for the menu entry editor. */ |
165 |
|
void |
166 |
|
grub_menu_init_page (int nested, int edit) |
167 |
{ |
{ |
168 |
grub_normal_init_page (); |
grub_normal_init_page (); |
169 |
draw_border (); |
draw_border (); |
170 |
print_message (nested, edit); |
print_message (nested, edit); |
171 |
} |
} |
172 |
|
|
|
/* Edit a menu entry with an Emacs-like interface. */ |
|
|
static void |
|
|
edit_menu_entry (grub_menu_entry_t entry) |
|
|
{ |
|
|
/* Not yet implemented. */ |
|
|
} |
|
|
|
|
173 |
static int |
static int |
174 |
run_menu (grub_menu_t menu, int nested) |
run_menu (grub_menu_t menu, int nested) |
175 |
{ |
{ |
178 |
|
|
179 |
first = 0; |
first = 0; |
180 |
offset = menu->default_entry; |
offset = menu->default_entry; |
181 |
if (offset > TERM_NUM_ENTRIES - 1) |
if (offset > GRUB_TERM_NUM_ENTRIES - 1) |
182 |
{ |
{ |
183 |
first = offset - (TERM_NUM_ENTRIES - 1); |
first = offset - (GRUB_TERM_NUM_ENTRIES - 1); |
184 |
offset = TERM_NUM_ENTRIES - 1; |
offset = GRUB_TERM_NUM_ENTRIES - 1; |
185 |
} |
} |
186 |
|
|
187 |
/* Initialize the time. */ |
/* Initialize the time. */ |
189 |
|
|
190 |
refresh: |
refresh: |
191 |
grub_setcursor (0); |
grub_setcursor (0); |
192 |
init_page (nested, 0); |
grub_menu_init_page (nested, 0); |
193 |
print_entries (menu, first, offset); |
print_entries (menu, first, offset); |
194 |
grub_refresh (); |
grub_refresh (); |
195 |
|
|
208 |
saved_time = current_time; |
saved_time = current_time; |
209 |
} |
} |
210 |
|
|
211 |
grub_gotoxy (0, TERM_HEIGHT - 3); |
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); |
212 |
/* NOTE: Do not remove the trailing space characters. |
/* NOTE: Do not remove the trailing space characters. |
213 |
They are required to clear the line. */ |
They are required to clear the line. */ |
214 |
grub_printf ("\ |
grub_printf ("\ |
215 |
The highlighted entry will be booted automatically in %d seconds. ", |
The highlighted entry will be booted automatically in %d seconds. ", |
216 |
menu->timeout); |
menu->timeout); |
217 |
grub_gotoxy (TERM_CURSOR_X, TERM_FIRST_ENTRY_Y + offset); |
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); |
218 |
grub_refresh (); |
grub_refresh (); |
219 |
} |
} |
220 |
|
|
227 |
|
|
228 |
if (menu->timeout >= 0) |
if (menu->timeout >= 0) |
229 |
{ |
{ |
230 |
grub_gotoxy (0, TERM_HEIGHT - 3); |
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); |
231 |
grub_printf ("\ |
grub_printf ("\ |
232 |
"); |
"); |
233 |
menu->timeout = -1; |
menu->timeout = -1; |
234 |
menu->fallback_entry = -1; |
menu->fallback_entry = -1; |
235 |
grub_gotoxy (TERM_CURSOR_X, TERM_FIRST_ENTRY_Y + offset); |
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); |
236 |
} |
} |
237 |
|
|
238 |
switch (c) |
switch (c) |
241 |
case '^': |
case '^': |
242 |
if (offset > 0) |
if (offset > 0) |
243 |
{ |
{ |
244 |
print_entry (TERM_FIRST_ENTRY_Y + offset, 0, |
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0, |
245 |
get_entry (menu, first + offset)); |
get_entry (menu, first + offset)); |
246 |
offset--; |
offset--; |
247 |
print_entry (TERM_FIRST_ENTRY_Y + offset, 1, |
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1, |
248 |
get_entry (menu, first + offset)); |
get_entry (menu, first + offset)); |
249 |
} |
} |
250 |
else if (first > 0) |
else if (first > 0) |
258 |
case 'v': |
case 'v': |
259 |
if (menu->size > first + offset + 1) |
if (menu->size > first + offset + 1) |
260 |
{ |
{ |
261 |
if (offset < TERM_NUM_ENTRIES - 1) |
if (offset < GRUB_TERM_NUM_ENTRIES - 1) |
262 |
{ |
{ |
263 |
print_entry (TERM_FIRST_ENTRY_Y + offset, 0, |
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0, |
264 |
get_entry (menu, first + offset)); |
get_entry (menu, first + offset)); |
265 |
offset++; |
offset++; |
266 |
print_entry (TERM_FIRST_ENTRY_Y + offset, 1, |
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1, |
267 |
get_entry (menu, first + offset)); |
get_entry (menu, first + offset)); |
268 |
} |
} |
269 |
else |
else |
289 |
break; |
break; |
290 |
|
|
291 |
case 'c': |
case 'c': |
|
grub_setcursor (1); |
|
292 |
grub_cmdline_run (1); |
grub_cmdline_run (1); |
293 |
goto refresh; |
goto refresh; |
294 |
|
|
295 |
case 'e': |
case 'e': |
296 |
edit_menu_entry (get_entry (menu, first + offset)); |
grub_menu_entry_run (get_entry (menu, first + offset)); |
297 |
goto refresh; |
goto refresh; |
298 |
|
|
299 |
default: |
default: |