2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc.
5
* GRUB 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, either version 3 of the License, or
8
* (at your option) any later version.
10
* GRUB is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19
#include <grub/normal.h>
20
#include <grub/term.h>
21
#include <grub/misc.h>
23
#include <grub/loader.h>
24
#include <grub/command.h>
25
#include <grub/parser.h>
26
#include <grub/script_sh.h>
27
#include <grub/auth.h>
28
#include <grub/i18n.h>
29
#include <grub/charset.h>
40
/* The line buffer. */
42
/* The length of the line. */
44
/* The maximum length of the line. */
48
struct per_term_screen
50
struct grub_term_output *term;
51
/* The X coordinate. */
53
/* The Y coordinate. */
59
/* The array of lines. */
61
/* The number of lines. */
63
/* The current column. */
65
/* The real column. */
67
/* The current line. */
69
/* The kill buffer. */
71
/* The flag of a completion window. */
76
struct per_term_screen *terms;
80
/* Used for storing completion items temporarily. */
81
static struct line completion_buffer;
82
static int completion_type;
84
/* Initialize a line. */
86
init_line (struct line *linep)
89
linep->max_len = 80; /* XXX */
90
linep->buf = grub_malloc (linep->max_len);
97
/* Allocate extra space if necessary. */
99
ensure_space (struct line *linep, int extra)
101
if (linep->max_len < linep->len + extra)
103
linep->max_len = linep->len + extra + 80; /* XXX */
104
linep->buf = grub_realloc (linep->buf, linep->max_len + 1);
112
/* Return the number of lines occupied by this line on the screen. */
114
get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
116
return (linep->len / grub_term_entry_width (term_screen->term)) + 1;
121
print_line (struct line *linep, int offset, int start, int y,
122
struct per_term_screen *term_screen)
124
grub_term_gotoxy (term_screen->term,
125
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
126
y + GRUB_TERM_FIRST_ENTRY_Y);
128
if (linep->len >= offset + grub_term_entry_width (term_screen->term))
131
p = linep->buf + offset + grub_term_entry_width (term_screen->term);
134
grub_puts_terminal (linep->buf + offset + start, term_screen->term);
136
grub_putcode ('\\', term_screen->term);
143
p = linep->buf + linep->len;
146
grub_puts_terminal (linep->buf + offset + start, term_screen->term);
150
i <= grub_term_entry_width (term_screen->term) - linep->len + offset;
152
grub_putcode (' ', term_screen->term);
156
/* Print an empty line. */
158
print_empty_line (int y, struct per_term_screen *term_screen)
162
grub_term_gotoxy (term_screen->term,
163
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
164
y + GRUB_TERM_FIRST_ENTRY_Y);
166
for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++)
167
grub_putcode (' ', term_screen->term);
170
/* Print an up arrow. */
172
print_up (int flag, struct per_term_screen *term_screen)
174
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
175
+ grub_term_border_width (term_screen->term),
176
GRUB_TERM_FIRST_ENTRY_Y);
179
grub_putcode (GRUB_UNICODE_UPARROW, term_screen->term);
181
grub_putcode (' ', term_screen->term);
184
/* Print a down arrow. */
186
print_down (int flag, struct per_term_screen *term_screen)
188
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
189
+ grub_term_border_width (term_screen->term),
190
GRUB_TERM_TOP_BORDER_Y
191
+ grub_term_num_entries (term_screen->term));
194
grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term);
196
grub_putcode (' ', term_screen->term);
199
/* Draw the lines of the screen SCREEN. */
201
update_screen (struct screen *screen, struct per_term_screen *term_screen,
202
int region_start, int region_column,
203
int up, int down, enum update_mode mode)
211
/* Check if scrolling is necessary. */
212
if (term_screen->y < 0 || term_screen->y
213
>= grub_term_num_entries (term_screen->term))
215
if (term_screen->y < 0)
218
term_screen->y = grub_term_num_entries (term_screen->term) - 1;
229
/* Draw lines. This code is tricky, because this must calculate logical
231
y = term_screen->y - screen->column
232
/ grub_term_entry_width (term_screen->term);
234
linep = screen->lines + i;
239
y -= get_logical_num_lines (linep, term_screen);
249
if (linep >= screen->lines + screen->num_lines)
254
&& y < grub_term_num_entries (term_screen->term);
255
column += grub_term_entry_width (term_screen->term), y++)
260
if (i == region_start)
262
if (region_column >= column
265
+ grub_term_entry_width (term_screen->term)))
266
print_line (linep, column, region_column - column, y,
268
else if (region_column < column)
269
print_line (linep, column, 0, y, term_screen);
271
else if (i > region_start && mode == ALL_LINES)
272
print_line (linep, column, 0, y, term_screen);
275
if (y == grub_term_num_entries (term_screen->term))
277
if (column <= linep->len || i + 1 < screen->num_lines)
284
if (mode == ALL_LINES && i == screen->num_lines)
285
for (; y < grub_term_num_entries (term_screen->term); y++)
286
print_empty_line (y, term_screen);
289
while (y < grub_term_num_entries (term_screen->term));
291
/* Draw up and down arrows. */
293
print_up (up_flag, term_screen);
295
print_down (down_flag, term_screen);
298
/* Place the cursor. */
299
grub_term_gotoxy (term_screen->term,
300
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1
302
GRUB_TERM_FIRST_ENTRY_Y + term_screen->y);
304
grub_term_refresh (term_screen->term);
308
update_screen_all (struct screen *screen,
309
int region_start, int region_column,
310
int up, int down, enum update_mode mode)
313
for (i = 0; i < screen->nterms; i++)
314
update_screen (screen, &screen->terms[i], region_start, region_column,
319
insert_string (struct screen *screen, char *s, int update)
321
int region_start = screen->num_lines;
322
int region_column = 0;
323
int down[screen->nterms];
324
enum update_mode mode[screen->nterms];
327
for (i = 0; i < screen->nterms; i++)
337
/* LF is special because it creates a new line. */
338
struct line *current_linep;
339
struct line *next_linep;
342
/* Make a new line. */
344
screen->lines = grub_realloc (screen->lines,
346
* sizeof (screen->lines[0]));
351
grub_memmove (screen->lines + screen->line + 2,
352
screen->lines + screen->line + 1,
353
((screen->num_lines - screen->line - 2)
354
* sizeof (struct line)));
356
if (! init_line (screen->lines + screen->line + 1))
360
current_linep = screen->lines + screen->line;
361
next_linep = current_linep + 1;
362
size = current_linep->len - screen->column;
364
if (! ensure_space (next_linep, size))
367
grub_memmove (next_linep->buf,
368
current_linep->buf + screen->column,
370
current_linep->len = screen->column;
371
next_linep->len = size;
373
/* Update a dirty region. */
374
if (region_start > screen->line)
376
region_start = screen->line;
377
region_column = screen->column;
380
for (i = 0; i < screen->nterms; i++)
383
down[i] = 1; /* XXX not optimal. */
386
/* Move the cursor. */
387
screen->column = screen->real_column = 0;
389
for (i = 0; i < screen->nterms; i++)
391
screen->terms[i].x = 0;
392
screen->terms[i].y++;
400
struct line *current_linep;
402
int orig_num[screen->nterms], new_num[screen->nterms];
404
/* Find a string delimited by LF. */
405
p = grub_strchr (s, '\n');
407
p = s + grub_strlen (s);
409
/* Insert the string. */
410
current_linep = screen->lines + screen->line;
412
if (! ensure_space (current_linep, size))
415
grub_memmove (current_linep->buf + screen->column + size,
416
current_linep->buf + screen->column,
417
current_linep->len - screen->column);
418
grub_memmove (current_linep->buf + screen->column,
421
for (i = 0; i < screen->nterms; i++)
422
orig_num[i] = get_logical_num_lines (current_linep,
424
current_linep->len += size;
425
for (i = 0; i < screen->nterms; i++)
426
new_num[i] = get_logical_num_lines (current_linep,
429
/* Update the dirty region. */
430
if (region_start > screen->line)
432
region_start = screen->line;
433
region_column = screen->column;
436
for (i = 0; i < screen->nterms; i++)
437
if (orig_num[i] != new_num[i])
440
down[i] = 1; /* XXX not optimal. */
442
else if (mode[i] != ALL_LINES)
443
mode[i] = SINGLE_LINE;
445
/* Move the cursor. */
446
screen->column += size;
447
screen->real_column = screen->column;
448
for (i = 0; i < screen->nterms; i++)
450
screen->terms[i].x += size;
451
screen->terms[i].y += screen->terms[i].x
452
/ grub_term_entry_width (screen->terms[i].term);
454
%= grub_term_entry_width (screen->terms[i].term);
461
for (i = 0; i < screen->nterms; i++)
462
update_screen (screen, &screen->terms[i],
463
region_start, region_column, 0, down[i], mode[i]);
468
/* Release the resource allocated for SCREEN. */
470
destroy_screen (struct screen *screen)
475
for (i = 0; i < screen->num_lines; i++)
477
struct line *linep = screen->lines + i;
480
grub_free (linep->buf);
483
grub_free (screen->killed_text);
484
grub_free (screen->lines);
485
grub_free (screen->terms);
489
/* Make a new screen. */
490
static struct screen *
491
make_screen (grub_menu_entry_t entry)
493
struct screen *screen;
496
/* Initialize the screen. */
497
screen = grub_zalloc (sizeof (*screen));
501
screen->submenu = entry->submenu;
503
screen->num_lines = 1;
504
screen->lines = grub_malloc (sizeof (struct line));
508
/* Initialize the first line which must be always present. */
509
if (! init_line (screen->lines))
512
insert_string (screen, (char *) entry->sourcecode, 0);
514
/* Reset the cursor position. */
516
screen->real_column = 0;
518
for (i = 0; i < screen->nterms; i++)
520
screen->terms[i].x = 0;
521
screen->terms[i].y = 0;
527
destroy_screen (screen);
532
forward_char (struct screen *screen, int update)
537
linep = screen->lines + screen->line;
538
if (screen->column < linep->len)
541
for (i = 0; i < screen->nterms; i++)
543
screen->terms[i].x++;
544
if (screen->terms[i].x
545
== grub_term_entry_width (screen->terms[i].term))
547
screen->terms[i].x = 0;
548
screen->terms[i].y++;
552
else if (screen->num_lines > screen->line + 1)
556
for (i = 0; i < screen->nterms; i++)
558
screen->terms[i].x = 0;
559
screen->terms[i].y++;
563
screen->real_column = screen->column;
566
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
571
backward_char (struct screen *screen, int update)
575
if (screen->column > 0)
578
for (i = 0; i < screen->nterms; i++)
580
screen->terms[i].x--;
581
if (screen->terms[i].x == -1)
584
= grub_term_entry_width (screen->terms[i].term) - 1;
585
screen->terms[i].y--;
589
else if (screen->line > 0)
594
linep = screen->lines + screen->line;
595
screen->column = linep->len;
596
for (i = 0; i < screen->nterms; i++)
598
screen->terms[i].x = screen->column
599
% grub_term_entry_width (screen->terms[i].term);
600
screen->terms[i].y--;
604
screen->real_column = screen->column;
607
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
613
previous_line (struct screen *screen, int update)
617
if (screen->line > 0)
622
/* How many physical lines from the current position
623
to the first physical line? */
624
col = screen->column;
628
linep = screen->lines + screen->line;
629
if (linep->len < screen->real_column)
630
screen->column = linep->len;
632
screen->column = screen->real_column;
634
for (i = 0; i < screen->nterms; i++)
637
dy = col / grub_term_entry_width (screen->terms[i].term);
639
/* How many physical lines from the current position
640
to the last physical line? */
641
dy += (linep->len / grub_term_entry_width (screen->terms[i].term)
643
/ grub_term_entry_width (screen->terms[i].term));
645
screen->terms[i].y -= dy + 1;
647
= screen->column % grub_term_entry_width (screen->terms[i].term);
652
for (i = 0; i < screen->nterms; i++)
655
-= screen->column / grub_term_entry_width (screen->terms[i].term);
656
screen->terms[i].x = 0;
662
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
668
next_line (struct screen *screen, int update)
672
if (screen->line < screen->num_lines - 1)
677
/* How many physical lines from the current position
678
to the last physical line? */
679
linep = screen->lines + screen->line;
686
if (linep->len < screen->real_column)
687
screen->column = linep->len;
689
screen->column = screen->real_column;
691
for (i = 0; i < screen->nterms; i++)
694
dy = l1 / grub_term_entry_width (screen->terms[i].term)
695
- c1 / grub_term_entry_width (screen->terms[i].term);
696
/* How many physical lines from the current position
697
to the first physical line? */
698
dy += screen->column / grub_term_entry_width (screen->terms[i].term);
699
screen->terms[i].y += dy + 1;
700
screen->terms[i].x = screen->column
701
% grub_term_entry_width (screen->terms[i].term);
709
linep = screen->lines + screen->line;
712
screen->column = linep->len;
713
for (i = 0; i < screen->nterms; i++)
716
+= (l / grub_term_entry_width (screen->terms[i].term)
717
- s / grub_term_entry_width (screen->terms[i].term));
719
= screen->column % grub_term_entry_width (screen->terms[i].term);
724
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
730
beginning_of_line (struct screen *screen, int update)
735
col = screen->column;
736
screen->column = screen->real_column = 0;
737
for (i = 0; i < screen->nterms; i++)
739
screen->terms[i].x = 0;
740
screen->terms[i].y -= col / grub_term_entry_width (screen->terms[i].term);
744
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
750
end_of_line (struct screen *screen, int update)
756
linep = screen->lines + screen->line;
757
col = screen->column;
758
screen->column = screen->real_column = linep->len;
759
for (i = 0; i < screen->nterms; i++)
762
+= (linep->len / grub_term_entry_width (screen->terms->term)
763
- col / grub_term_entry_width (screen->terms->term));
765
= screen->column % grub_term_entry_width (screen->terms->term);
769
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
775
delete_char (struct screen *screen, int update)
778
int start = screen->num_lines;
781
linep = screen->lines + screen->line;
782
if (linep->len > screen->column)
784
int orig_num[screen->nterms], new_num;
787
for (i = 0; i < screen->nterms; i++)
788
orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
790
grub_memmove (linep->buf + screen->column,
791
linep->buf + screen->column + 1,
792
linep->len - screen->column - 1);
795
start = screen->line;
796
column = screen->column;
798
screen->real_column = screen->column;
802
for (i = 0; i < screen->nterms; i++)
804
new_num = get_logical_num_lines (linep, &screen->terms[i]);
805
if (orig_num[i] != new_num)
806
update_screen (screen, &screen->terms[i],
807
start, column, 0, 0, ALL_LINES);
809
update_screen (screen, &screen->terms[i],
810
start, column, 0, 0, SINGLE_LINE);
814
else if (screen->num_lines > screen->line + 1)
816
struct line *next_linep;
818
next_linep = linep + 1;
819
if (! ensure_space (linep, next_linep->len))
822
grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len);
823
linep->len += next_linep->len;
825
grub_free (next_linep->buf);
826
grub_memmove (next_linep,
828
(screen->num_lines - screen->line - 2)
829
* sizeof (struct line));
832
start = screen->line;
833
column = screen->column;
835
screen->real_column = screen->column;
837
update_screen_all (screen, start, column, 0, 1, ALL_LINES);
844
backward_delete_char (struct screen *screen, int update)
849
saved_column = screen->column;
850
saved_line = screen->line;
852
if (! backward_char (screen, 0))
855
if (saved_column != screen->column || saved_line != screen->line)
856
if (! delete_char (screen, update))
863
kill_line (struct screen *screen, int continuous, int update)
870
p = screen->killed_text;
871
if (! continuous && p)
874
linep = screen->lines + screen->line;
875
size = linep->len - screen->column;
878
offset = grub_strlen (p);
884
int orig_num[screen->nterms], new_num;
887
p = grub_realloc (p, offset + size + 1);
891
grub_memmove (p + offset, linep->buf + screen->column, size);
892
p[offset + size - 1] = '\0';
894
screen->killed_text = p;
896
for (i = 0; i < screen->nterms; i++)
897
orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
898
linep->len = screen->column;
902
new_num = get_logical_num_lines (linep, &screen->terms[i]);
903
for (i = 0; i < screen->nterms; i++)
905
if (orig_num[i] != new_num)
906
update_screen (screen, &screen->terms[i],
907
screen->line, screen->column, 0, 1, ALL_LINES);
909
update_screen (screen, &screen->terms[i],
910
screen->line, screen->column, 0, 0, SINGLE_LINE);
914
else if (screen->line + 1 < screen->num_lines)
916
p = grub_realloc (p, offset + 1 + 1);
921
p[offset + 1] = '\0';
923
screen->killed_text = p;
925
return delete_char (screen, update);
932
yank (struct screen *screen, int update)
934
if (screen->killed_text)
935
return insert_string (screen, screen->killed_text, update);
941
open_line (struct screen *screen, int update)
943
int saved_y[screen->nterms];
946
for (i = 0; i < screen->nterms; i++)
947
saved_y[i] = screen->terms[i].y;
949
if (! insert_string (screen, "\n", 0))
952
if (! backward_char (screen, 0))
955
for (i = 0; i < screen->nterms; i++)
956
screen->terms[i].y = saved_y[i];
959
update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
964
/* A completion hook to print items. */
966
store_completion (const char *item, grub_completion_type_t type,
967
int count __attribute__ ((unused)))
971
completion_type = type;
973
/* Make sure that the completion buffer has enough room. */
974
if (completion_buffer.max_len < (completion_buffer.len
975
+ (int) grub_strlen (item) + 1 + 1))
979
new_len = completion_buffer.len + grub_strlen (item) + 80;
980
p = grub_realloc (completion_buffer.buf, new_len);
983
/* Possibly not fatal. */
984
grub_errno = GRUB_ERR_NONE;
987
p[completion_buffer.len] = 0;
988
completion_buffer.buf = p;
989
completion_buffer.max_len = new_len;
992
p = completion_buffer.buf + completion_buffer.len;
993
if (completion_buffer.len != 0)
996
completion_buffer.len++;
998
grub_strcpy (p, item);
999
completion_buffer.len += grub_strlen (item);
1003
complete (struct screen *screen, int continuous, int update)
1009
static int count = -1;
1011
grub_uint32_t *ucs4;
1013
grub_ssize_t ucs4len;
1020
completion_buffer.buf = 0;
1021
completion_buffer.len = 0;
1022
completion_buffer.max_len = 0;
1024
linep = screen->lines + screen->line;
1025
saved_char = linep->buf[screen->column];
1026
linep->buf[screen->column] = '\0';
1028
insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
1030
linep->buf[screen->column] = saved_char;
1032
if (completion_buffer.buf)
1034
buflen = grub_strlen (completion_buffer.buf);
1035
ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
1039
grub_print_error ();
1040
grub_errno = GRUB_ERR_NONE;
1044
ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
1045
(grub_uint8_t *) completion_buffer.buf,
1050
for (i = 0; i < screen->nterms; i++)
1052
int num_sections = ((completion_buffer.len
1053
+ grub_term_width (screen->terms[i].term)
1055
/ (grub_term_width (screen->terms[i].term)
1057
grub_uint32_t *endp;
1059
grub_uint32_t *p = ucs4;
1061
pos = grub_term_getxy (screen->terms[i].term);
1062
grub_term_gotoxy (screen->terms[i].term, 0,
1063
grub_term_height (screen->terms[i].term) - 3);
1065
screen->completion_shown = 1;
1067
grub_term_gotoxy (screen->terms[i].term, 0,
1068
grub_term_height (screen->terms[i].term) - 3);
1069
grub_puts_terminal (" ", screen->terms[i].term);
1070
switch (completion_type)
1072
case GRUB_COMPLETION_TYPE_COMMAND:
1073
grub_puts_terminal (_("Possible commands are:"),
1074
screen->terms[i].term);
1076
case GRUB_COMPLETION_TYPE_DEVICE:
1077
grub_puts_terminal (_("Possible devices are:"),
1078
screen->terms[i].term);
1080
case GRUB_COMPLETION_TYPE_FILE:
1081
grub_puts_terminal (_("Possible files are:"),
1082
screen->terms[i].term);
1084
case GRUB_COMPLETION_TYPE_PARTITION:
1085
grub_puts_terminal (_("Possible partitions are:"),
1086
screen->terms[i].term);
1088
case GRUB_COMPLETION_TYPE_ARGUMENT:
1089
grub_puts_terminal (_("Possible arguments are:"),
1090
screen->terms[i].term);
1093
grub_puts_terminal (_("Possible things are:"),
1094
screen->terms[i].term);
1098
grub_puts_terminal ("\n ", screen->terms[i].term);
1100
p += (count % num_sections)
1101
* (grub_term_width (screen->terms[i].term) - 8);
1102
endp = p + (grub_term_width (screen->terms[i].term) - 8);
1105
grub_putcode (GRUB_UNICODE_LEFTARROW, screen->terms[i].term);
1107
grub_putcode (' ', screen->terms[i].term);
1109
grub_print_ucs4 (p, ucs4 + ucs4len < endp ? ucs4 + ucs4len : endp,
1110
0, 0, screen->terms[i].term);
1112
if (ucs4 + ucs4len > endp)
1113
grub_putcode (GRUB_UNICODE_RIGHTARROW, screen->terms[i].term);
1114
grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF);
1120
insert_string (screen, insert, update);
1127
grub_free (completion_buffer.buf);
1131
/* Clear displayed completions. */
1133
clear_completions (struct per_term_screen *term_screen)
1138
pos = grub_term_getxy (term_screen->term);
1139
grub_term_gotoxy (term_screen->term, 0,
1140
grub_term_height (term_screen->term) - 3);
1142
for (i = 0; i < 2; i++)
1144
for (j = 0; j < grub_term_width (term_screen->term) - 1; j++)
1145
grub_putcode (' ', term_screen->term);
1146
grub_putcode ('\n', term_screen->term);
1149
grub_term_gotoxy (term_screen->term, pos >> 8, pos & 0xFF);
1150
grub_term_refresh (term_screen->term);
1154
clear_completions_all (struct screen *screen)
1158
for (i = 0; i < screen->nterms; i++)
1159
clear_completions (&screen->terms[i]);
1162
/* Execute the command list in the screen SCREEN. */
1164
run (struct screen *screen)
1171
auto grub_err_t editor_getline (char **line, int cont);
1172
grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
1174
struct line *linep = screen->lines + currline;
1177
if (currline > screen->num_lines)
1183
/* Trim down space characters. */
1184
for (p = linep->buf + linep->len - 1;
1185
p >= linep->buf && grub_isspace (*p);
1190
linep->len = p - linep->buf;
1191
for (p = linep->buf; grub_isspace (*p); p++)
1193
*line = grub_strdup (p);
1200
grub_printf_ (N_("Booting a command list"));
1201
grub_printf ("\n\n");
1203
errs_before = grub_err_printed_errors;
1205
if (screen->submenu)
1207
grub_env_context_open ();
1208
menu = grub_zalloc (sizeof (*menu));
1211
grub_env_set_menu (menu);
1214
/* Execute the script, line for line. */
1215
while (currline < screen->num_lines)
1217
editor_getline (&nextline, 0);
1218
if (grub_normal_parse_line (nextline, editor_getline))
1222
if (errs_before != grub_err_printed_errors)
1223
grub_wait_after_message ();
1225
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
1226
/* Implicit execution of boot, only if something is loaded. */
1227
grub_command_execute ("boot", 0, 0);
1229
if (screen->submenu)
1231
if (menu && menu->size)
1233
grub_show_menu (menu, 1);
1234
grub_normal_free_menu (menu);
1236
grub_env_context_close ();
1239
if (grub_errno != GRUB_ERR_NONE)
1241
grub_print_error ();
1242
grub_errno = GRUB_ERR_NONE;
1243
grub_wait_after_message ();
1249
/* Edit a menu entry with an Emacs-like interface. */
1251
grub_menu_entry_run (grub_menu_entry_t entry)
1253
struct screen *screen;
1255
grub_err_t err = GRUB_ERR_NONE;
1257
grub_term_output_t term;
1259
err = grub_auth_check_authentication (NULL);
1263
grub_print_error ();
1264
grub_errno = GRUB_ERR_NONE;
1268
screen = make_screen (entry);
1272
screen->terms = NULL;
1275
grub_free (screen->terms);
1277
FOR_ACTIVE_TERM_OUTPUTS(term)
1279
screen->terms = grub_malloc (screen->nterms * sizeof (screen->terms[0]));
1282
grub_print_error ();
1283
grub_errno = GRUB_ERR_NONE;
1287
FOR_ACTIVE_TERM_OUTPUTS(term)
1289
screen->terms[i].term = term;
1290
screen->terms[i].x = 0;
1291
screen->terms[i].y = 0;
1294
/* Draw the screen. */
1295
for (i = 0; i < screen->nterms; i++)
1296
grub_menu_init_page (0, 1, screen->terms[i].term);
1297
update_screen_all (screen, 0, 0, 1, 1, ALL_LINES);
1298
for (i = 0; i < screen->nterms; i++)
1299
grub_term_setcursor (screen->terms[i].term, 1);
1304
int c = grub_getkey ();
1306
if (screen->completion_shown)
1308
clear_completions_all (screen);
1309
screen->completion_shown = 0;
1312
if (grub_normal_exit_level)
1314
destroy_screen (screen);
1320
case GRUB_TERM_KEY_UP:
1321
case GRUB_TERM_CTRL | 'p':
1322
if (! previous_line (screen, 1))
1326
case GRUB_TERM_CTRL | 'n':
1327
case GRUB_TERM_KEY_DOWN:
1328
if (! next_line (screen, 1))
1332
case GRUB_TERM_CTRL | 'f':
1333
case GRUB_TERM_KEY_RIGHT:
1334
if (! forward_char (screen, 1))
1338
case GRUB_TERM_CTRL | 'b':
1339
case GRUB_TERM_KEY_LEFT:
1340
if (! backward_char (screen, 1))
1344
case GRUB_TERM_CTRL | 'a':
1345
case GRUB_TERM_KEY_HOME:
1346
if (! beginning_of_line (screen, 1))
1350
case GRUB_TERM_CTRL | 'e':
1351
case GRUB_TERM_KEY_END:
1352
if (! end_of_line (screen, 1))
1356
case GRUB_TERM_CTRL | 'i':
1358
if (! complete (screen, prev_c == c, 1))
1362
case GRUB_TERM_CTRL | 'd':
1363
case GRUB_TERM_KEY_DC:
1364
if (! delete_char (screen, 1))
1368
case GRUB_TERM_CTRL | 'h':
1370
if (! backward_delete_char (screen, 1))
1374
case GRUB_TERM_CTRL | 'k':
1375
if (! kill_line (screen, prev_c == c, 1))
1379
case GRUB_TERM_CTRL | 'u':
1380
/* FIXME: What behavior is good for this key? */
1383
case GRUB_TERM_CTRL | 'y':
1384
if (! yank (screen, 1))
1388
case GRUB_TERM_CTRL | 'l':
1389
/* FIXME: centering. */
1392
case GRUB_TERM_CTRL | 'o':
1393
if (! open_line (screen, 1))
1399
if (! insert_string (screen, "\n", 1))
1404
destroy_screen (screen);
1407
case GRUB_TERM_CTRL | 'c':
1408
case GRUB_TERM_KEY_F2:
1409
grub_cmdline_run (1);
1412
case GRUB_TERM_CTRL | 'x':
1413
case GRUB_TERM_KEY_F10:
1417
case GRUB_TERM_CTRL | 'r':
1418
case GRUB_TERM_CTRL | 's':
1419
case GRUB_TERM_CTRL | 't':
1424
if (grub_isprint (c))
1430
if (! insert_string (screen, buf, 1))
1440
destroy_screen (screen);
1443
grub_print_error ();
1444
grub_errno = GRUB_ERR_NONE;
1446
grub_printf_ (N_("Press any key to continue..."));
1447
(void) grub_getkey ();