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. */
74
struct per_term_screen *terms;
78
/* Used for storing completion items temporarily. */
79
static struct line completion_buffer;
80
static int completion_type;
82
/* Initialize a line. */
84
init_line (struct line *linep)
87
linep->max_len = 80; /* XXX */
88
linep->buf = grub_malloc (linep->max_len);
95
/* Allocate extra space if necessary. */
97
ensure_space (struct line *linep, int extra)
99
if (linep->max_len < linep->len + extra)
101
linep->max_len = linep->len + extra + 80; /* XXX */
102
linep->buf = grub_realloc (linep->buf, linep->max_len + 1);
110
/* Return the number of lines occupied by this line on the screen. */
112
get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
114
return (linep->len / grub_term_entry_width (term_screen->term)) + 1;
119
print_line (struct line *linep, int offset, int start, int y,
120
struct per_term_screen *term_screen)
122
grub_term_gotoxy (term_screen->term,
123
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
124
y + GRUB_TERM_FIRST_ENTRY_Y);
126
if (linep->len >= offset + grub_term_entry_width (term_screen->term))
129
p = linep->buf + offset + grub_term_entry_width (term_screen->term);
132
grub_puts_terminal (linep->buf + offset + start, term_screen->term);
134
grub_putcode ('\\', term_screen->term);
141
p = linep->buf + linep->len;
144
grub_puts_terminal (linep->buf + offset + start, term_screen->term);
148
i <= grub_term_entry_width (term_screen->term) - linep->len + offset;
150
grub_putcode (' ', term_screen->term);
154
/* Print an empty line. */
156
print_empty_line (int y, struct per_term_screen *term_screen)
160
grub_term_gotoxy (term_screen->term,
161
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
162
y + GRUB_TERM_FIRST_ENTRY_Y);
164
for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++)
165
grub_putcode (' ', term_screen->term);
168
/* Print an up arrow. */
170
print_up (int flag, struct per_term_screen *term_screen)
172
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
173
+ grub_term_entry_width (term_screen->term),
174
GRUB_TERM_FIRST_ENTRY_Y);
177
grub_putcode (GRUB_UNICODE_UPARROW, term_screen->term);
179
grub_putcode (' ', term_screen->term);
182
/* Print a down arrow. */
184
print_down (int flag, struct per_term_screen *term_screen)
186
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
187
+ grub_term_border_width (term_screen->term),
188
GRUB_TERM_TOP_BORDER_Y
189
+ grub_term_num_entries (term_screen->term));
192
grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term);
194
grub_putcode (' ', term_screen->term);
197
/* Draw the lines of the screen SCREEN. */
199
update_screen (struct screen *screen, struct per_term_screen *term_screen,
200
int region_start, int region_column,
201
int up, int down, enum update_mode mode)
209
/* Check if scrolling is necessary. */
210
if (term_screen->y < 0 || term_screen->y
211
>= grub_term_num_entries (term_screen->term))
213
if (term_screen->y < 0)
216
term_screen->y = grub_term_num_entries (term_screen->term) - 1;
227
/* Draw lines. This code is tricky, because this must calculate logical
229
y = term_screen->y - screen->column
230
/ grub_term_entry_width (term_screen->term);
232
linep = screen->lines + i;
237
y -= get_logical_num_lines (linep, term_screen);
247
if (linep >= screen->lines + screen->num_lines)
252
&& y < grub_term_num_entries (term_screen->term);
253
column += grub_term_entry_width (term_screen->term), y++)
258
if (i == region_start)
260
if (region_column >= column
263
+ grub_term_entry_width (term_screen->term)))
264
print_line (linep, column, region_column - column, y,
266
else if (region_column < column)
267
print_line (linep, column, 0, y, term_screen);
269
else if (i > region_start && mode == ALL_LINES)
270
print_line (linep, column, 0, y, term_screen);
273
if (y == grub_term_num_entries (term_screen->term))
275
if (column <= linep->len || i + 1 < screen->num_lines)
282
if (mode == ALL_LINES && i == screen->num_lines)
283
for (; y < grub_term_num_entries (term_screen->term); y++)
284
print_empty_line (y, term_screen);
287
while (y < grub_term_num_entries (term_screen->term));
289
/* Draw up and down arrows. */
291
print_up (up_flag, term_screen);
293
print_down (down_flag, term_screen);
296
/* Place the cursor. */
297
grub_term_gotoxy (term_screen->term,
298
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1
300
GRUB_TERM_FIRST_ENTRY_Y + term_screen->y);
302
grub_term_refresh (term_screen->term);
306
update_screen_all (struct screen *screen,
307
int region_start, int region_column,
308
int up, int down, enum update_mode mode)
311
for (i = 0; i < screen->nterms; i++)
312
update_screen (screen, &screen->terms[i], region_start, region_column,
317
insert_string (struct screen *screen, char *s, int update)
319
int region_start = screen->num_lines;
320
int region_column = 0;
321
int down[screen->nterms];
322
enum update_mode mode[screen->nterms];
325
for (i = 0; i < screen->nterms; i++)
335
/* LF is special because it creates a new line. */
336
struct line *current_linep;
337
struct line *next_linep;
340
/* Make a new line. */
342
screen->lines = grub_realloc (screen->lines,
344
* sizeof (screen->lines[0]));
349
grub_memmove (screen->lines + screen->line + 2,
350
screen->lines + screen->line + 1,
351
((screen->num_lines - screen->line - 2)
352
* sizeof (struct line)));
354
if (! init_line (screen->lines + screen->line + 1))
358
current_linep = screen->lines + screen->line;
359
next_linep = current_linep + 1;
360
size = current_linep->len - screen->column;
362
if (! ensure_space (next_linep, size))
365
grub_memmove (next_linep->buf,
366
current_linep->buf + screen->column,
368
current_linep->len = screen->column;
369
next_linep->len = size;
371
/* Update a dirty region. */
372
if (region_start > screen->line)
374
region_start = screen->line;
375
region_column = screen->column;
378
for (i = 0; i < screen->nterms; i++)
381
down[i] = 1; /* XXX not optimal. */
384
/* Move the cursor. */
385
screen->column = screen->real_column = 0;
387
for (i = 0; i < screen->nterms; i++)
389
screen->terms[i].x = 0;
390
screen->terms[i].y++;
398
struct line *current_linep;
400
int orig_num[screen->nterms], new_num[screen->nterms];
402
/* Find a string delimited by LF. */
403
p = grub_strchr (s, '\n');
405
p = s + grub_strlen (s);
407
/* Insert the string. */
408
current_linep = screen->lines + screen->line;
410
if (! ensure_space (current_linep, size))
413
grub_memmove (current_linep->buf + screen->column + size,
414
current_linep->buf + screen->column,
415
current_linep->len - screen->column);
416
grub_memmove (current_linep->buf + screen->column,
419
for (i = 0; i < screen->nterms; i++)
420
orig_num[i] = get_logical_num_lines (current_linep,
422
current_linep->len += size;
423
for (i = 0; i < screen->nterms; i++)
424
new_num[i] = get_logical_num_lines (current_linep,
427
/* Update the dirty region. */
428
if (region_start > screen->line)
430
region_start = screen->line;
431
region_column = screen->column;
434
for (i = 0; i < screen->nterms; i++)
435
if (orig_num[i] != new_num[i])
438
down[i] = 1; /* XXX not optimal. */
440
else if (mode[i] != ALL_LINES)
441
mode[i] = SINGLE_LINE;
443
/* Move the cursor. */
444
screen->column += size;
445
screen->real_column = screen->column;
446
for (i = 0; i < screen->nterms; i++)
448
screen->terms[i].x += size;
449
screen->terms[i].y += screen->terms[i].x
450
/ grub_term_entry_width (screen->terms[i].term);
452
%= grub_term_entry_width (screen->terms[i].term);
459
for (i = 0; i < screen->nterms; i++)
460
update_screen (screen, &screen->terms[i],
461
region_start, region_column, 0, down[i], mode[i]);
466
/* Release the resource allocated for SCREEN. */
468
destroy_screen (struct screen *screen)
473
for (i = 0; i < screen->num_lines; i++)
475
struct line *linep = screen->lines + i;
478
grub_free (linep->buf);
481
grub_free (screen->killed_text);
482
grub_free (screen->lines);
483
grub_free (screen->terms);
487
/* Make a new screen. */
488
static struct screen *
489
make_screen (grub_menu_entry_t entry)
491
struct screen *screen;
494
/* Initialize the screen. */
495
screen = grub_zalloc (sizeof (*screen));
499
screen->num_lines = 1;
500
screen->lines = grub_malloc (sizeof (struct line));
504
/* Initialize the first line which must be always present. */
505
if (! init_line (screen->lines))
508
insert_string (screen, (char *) entry->sourcecode, 0);
510
/* Reset the cursor position. */
512
screen->real_column = 0;
514
for (i = 0; i < screen->nterms; i++)
516
screen->terms[i].x = 0;
517
screen->terms[i].y = 0;
523
destroy_screen (screen);
528
forward_char (struct screen *screen, int update)
533
linep = screen->lines + screen->line;
534
if (screen->column < linep->len)
537
for (i = 0; i < screen->nterms; i++)
539
screen->terms[i].x++;
540
if (screen->terms[i].x
541
== grub_term_entry_width (screen->terms[i].term))
543
screen->terms[i].x = 0;
544
screen->terms[i].y++;
548
else if (screen->num_lines > screen->line + 1)
552
for (i = 0; i < screen->nterms; i++)
554
screen->terms[i].x = 0;
555
screen->terms[i].y++;
559
screen->real_column = screen->column;
562
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
567
backward_char (struct screen *screen, int update)
571
if (screen->column > 0)
574
for (i = 0; i < screen->nterms; i++)
576
screen->terms[i].x--;
577
if (screen->terms[i].x == -1)
580
= grub_term_entry_width (screen->terms[i].term) - 1;
581
screen->terms[i].y--;
585
else if (screen->line > 0)
590
linep = screen->lines + screen->line;
591
screen->column = linep->len;
592
for (i = 0; i < screen->nterms; i++)
594
screen->terms[i].x = screen->column
595
% grub_term_entry_width (screen->terms[i].term);
596
screen->terms[i].y--;
600
screen->real_column = screen->column;
603
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
609
previous_line (struct screen *screen, int update)
613
if (screen->line > 0)
618
/* How many physical lines from the current position
619
to the first physical line? */
620
col = screen->column;
624
linep = screen->lines + screen->line;
625
if (linep->len < screen->real_column)
626
screen->column = linep->len;
628
screen->column = screen->real_column;
630
for (i = 0; i < screen->nterms; i++)
633
dy = col / grub_term_entry_width (screen->terms[i].term);
635
/* How many physical lines from the current position
636
to the last physical line? */
637
dy += (linep->len / grub_term_entry_width (screen->terms[i].term)
639
/ grub_term_entry_width (screen->terms[i].term));
641
screen->terms[i].y -= dy + 1;
643
= screen->column % grub_term_entry_width (screen->terms[i].term);
648
for (i = 0; i < screen->nterms; i++)
651
-= screen->column / grub_term_entry_width (screen->terms[i].term);
652
screen->terms[i].x = 0;
658
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
664
next_line (struct screen *screen, int update)
668
if (screen->line < screen->num_lines - 1)
673
/* How many physical lines from the current position
674
to the last physical line? */
675
linep = screen->lines + screen->line;
682
if (linep->len < screen->real_column)
683
screen->column = linep->len;
685
screen->column = screen->real_column;
687
for (i = 0; i < screen->nterms; i++)
690
dy = l1 / grub_term_entry_width (screen->terms[i].term)
691
- c1 / grub_term_entry_width (screen->terms[i].term);
692
/* How many physical lines from the current position
693
to the first physical line? */
694
dy += screen->column / grub_term_entry_width (screen->terms[i].term);
695
screen->terms[i].y += dy + 1;
696
screen->terms[i].x = screen->column
697
% grub_term_entry_width (screen->terms[i].term);
705
linep = screen->lines + screen->line;
708
screen->column = linep->len;
709
for (i = 0; i < screen->nterms; i++)
712
+= (l / grub_term_entry_width (screen->terms[i].term)
713
- s / grub_term_entry_width (screen->terms[i].term));
715
= screen->column % grub_term_entry_width (screen->terms[i].term);
720
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
726
beginning_of_line (struct screen *screen, int update)
731
col = screen->column;
732
screen->column = screen->real_column = 0;
733
for (i = 0; i < screen->nterms; i++)
735
screen->terms[i].x = 0;
736
screen->terms[i].y -= col / grub_term_entry_width (screen->terms[i].term);
740
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
746
end_of_line (struct screen *screen, int update)
752
linep = screen->lines + screen->line;
753
col = screen->column;
754
screen->column = screen->real_column = linep->len;
755
for (i = 0; i < screen->nterms; i++)
758
+= (linep->len / grub_term_entry_width (screen->terms->term)
759
- col / grub_term_entry_width (screen->terms->term));
761
= screen->column % grub_term_entry_width (screen->terms->term);
765
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
771
delete_char (struct screen *screen, int update)
774
int start = screen->num_lines;
777
linep = screen->lines + screen->line;
778
if (linep->len > screen->column)
780
int orig_num[screen->nterms], new_num;
783
for (i = 0; i < screen->nterms; i++)
784
orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
786
grub_memmove (linep->buf + screen->column,
787
linep->buf + screen->column + 1,
788
linep->len - screen->column - 1);
791
start = screen->line;
792
column = screen->column;
794
screen->real_column = screen->column;
798
for (i = 0; i < screen->nterms; i++)
800
new_num = get_logical_num_lines (linep, &screen->terms[i]);
801
if (orig_num[i] != new_num)
802
update_screen (screen, &screen->terms[i],
803
start, column, 0, 0, ALL_LINES);
805
update_screen (screen, &screen->terms[i],
806
start, column, 0, 0, SINGLE_LINE);
810
else if (screen->num_lines > screen->line + 1)
812
struct line *next_linep;
814
next_linep = linep + 1;
815
if (! ensure_space (linep, next_linep->len))
818
grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len);
819
linep->len += next_linep->len;
821
grub_free (next_linep->buf);
822
grub_memmove (next_linep,
824
(screen->num_lines - screen->line - 2)
825
* sizeof (struct line));
828
start = screen->line;
829
column = screen->column;
831
screen->real_column = screen->column;
833
update_screen_all (screen, start, column, 0, 1, ALL_LINES);
840
backward_delete_char (struct screen *screen, int update)
845
saved_column = screen->column;
846
saved_line = screen->line;
848
if (! backward_char (screen, 0))
851
if (saved_column != screen->column || saved_line != screen->line)
852
if (! delete_char (screen, update))
859
kill_line (struct screen *screen, int continuous, int update)
866
p = screen->killed_text;
867
if (! continuous && p)
870
linep = screen->lines + screen->line;
871
size = linep->len - screen->column;
874
offset = grub_strlen (p);
880
int orig_num[screen->nterms], new_num;
883
p = grub_realloc (p, offset + size + 1);
887
grub_memmove (p + offset, linep->buf + screen->column, size);
888
p[offset + size - 1] = '\0';
890
screen->killed_text = p;
892
for (i = 0; i < screen->nterms; i++)
893
orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
894
linep->len = screen->column;
898
new_num = get_logical_num_lines (linep, &screen->terms[i]);
899
for (i = 0; i < screen->nterms; i++)
901
if (orig_num[i] != new_num)
902
update_screen (screen, &screen->terms[i],
903
screen->line, screen->column, 0, 1, ALL_LINES);
905
update_screen (screen, &screen->terms[i],
906
screen->line, screen->column, 0, 0, SINGLE_LINE);
910
else if (screen->line + 1 < screen->num_lines)
912
p = grub_realloc (p, offset + 1 + 1);
917
p[offset + 1] = '\0';
919
screen->killed_text = p;
921
return delete_char (screen, update);
928
yank (struct screen *screen, int update)
930
if (screen->killed_text)
931
return insert_string (screen, screen->killed_text, update);
937
open_line (struct screen *screen, int update)
939
int saved_y[screen->nterms];
942
for (i = 0; i < screen->nterms; i++)
943
saved_y[i] = screen->terms[i].y;
945
if (! insert_string (screen, "\n", 0))
948
if (! backward_char (screen, 0))
951
for (i = 0; i < screen->nterms; i++)
952
screen->terms[i].y = saved_y[i];
955
update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
960
/* A completion hook to print items. */
962
store_completion (const char *item, grub_completion_type_t type,
963
int count __attribute__ ((unused)))
967
completion_type = type;
969
/* Make sure that the completion buffer has enough room. */
970
if (completion_buffer.max_len < (completion_buffer.len
971
+ (int) grub_strlen (item) + 1 + 1))
975
new_len = completion_buffer.len + grub_strlen (item) + 80;
976
p = grub_realloc (completion_buffer.buf, new_len);
979
/* Possibly not fatal. */
980
grub_errno = GRUB_ERR_NONE;
983
p[completion_buffer.len] = 0;
984
completion_buffer.buf = p;
985
completion_buffer.max_len = new_len;
988
p = completion_buffer.buf + completion_buffer.len;
989
if (completion_buffer.len != 0)
992
completion_buffer.len++;
994
grub_strcpy (p, item);
995
completion_buffer.len += grub_strlen (item);
999
complete (struct screen *screen, int continuous, int update)
1005
static int count = -1;
1007
grub_uint32_t *ucs4;
1009
grub_ssize_t ucs4len;
1016
completion_buffer.buf = 0;
1017
completion_buffer.len = 0;
1018
completion_buffer.max_len = 0;
1020
linep = screen->lines + screen->line;
1021
saved_char = linep->buf[screen->column];
1022
linep->buf[screen->column] = '\0';
1024
insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
1026
linep->buf[screen->column] = saved_char;
1028
if (completion_buffer.buf)
1030
buflen = grub_strlen (completion_buffer.buf);
1031
ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
1035
grub_print_error ();
1036
grub_errno = GRUB_ERR_NONE;
1040
ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
1041
(grub_uint8_t *) completion_buffer.buf,
1046
for (i = 0; i < screen->nterms; i++)
1048
int num_sections = ((completion_buffer.len
1049
+ grub_term_width (screen->terms[i].term)
1051
/ (grub_term_width (screen->terms[i].term)
1053
grub_uint32_t *endp;
1055
grub_uint32_t *p = ucs4;
1057
pos = grub_term_getxy (screen->terms[i].term);
1058
grub_term_gotoxy (screen->terms[i].term, 0,
1059
grub_term_height (screen->terms[i].term) - 3);
1061
screen->completion_shown = 1;
1063
grub_term_gotoxy (screen->terms[i].term, 0,
1064
grub_term_height (screen->terms[i].term) - 3);
1065
grub_puts_terminal (" ", screen->terms[i].term);
1066
switch (completion_type)
1068
case GRUB_COMPLETION_TYPE_COMMAND:
1069
grub_puts_terminal (_("Possible commands are:"),
1070
screen->terms[i].term);
1072
case GRUB_COMPLETION_TYPE_DEVICE:
1073
grub_puts_terminal (_("Possible devices are:"),
1074
screen->terms[i].term);
1076
case GRUB_COMPLETION_TYPE_FILE:
1077
grub_puts_terminal (_("Possible files are:"),
1078
screen->terms[i].term);
1080
case GRUB_COMPLETION_TYPE_PARTITION:
1081
grub_puts_terminal (_("Possible partitions are:"),
1082
screen->terms[i].term);
1084
case GRUB_COMPLETION_TYPE_ARGUMENT:
1085
grub_puts_terminal (_("Possible arguments are:"),
1086
screen->terms[i].term);
1089
grub_puts_terminal (_("Possible things are:"),
1090
screen->terms[i].term);
1094
grub_puts_terminal ("\n ", screen->terms[i].term);
1096
p += (count % num_sections)
1097
* (grub_term_width (screen->terms[i].term) - 8);
1098
endp = p + (grub_term_width (screen->terms[i].term) - 8);
1101
grub_putcode (GRUB_UNICODE_LEFTARROW, screen->terms[i].term);
1103
grub_putcode (' ', screen->terms[i].term);
1105
grub_print_ucs4 (p, ucs4 + ucs4len < endp ? ucs4 + ucs4len : endp,
1106
0, 0, screen->terms[i].term);
1108
if (ucs4 + ucs4len > endp)
1109
grub_putcode (GRUB_UNICODE_RIGHTARROW, screen->terms[i].term);
1110
grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF);
1116
insert_string (screen, insert, update);
1123
grub_free (completion_buffer.buf);
1127
/* Clear displayed completions. */
1129
clear_completions (struct per_term_screen *term_screen)
1134
pos = grub_term_getxy (term_screen->term);
1135
grub_term_gotoxy (term_screen->term, 0,
1136
grub_term_height (term_screen->term) - 3);
1138
for (i = 0; i < 2; i++)
1140
for (j = 0; j < grub_term_width (term_screen->term) - 1; j++)
1141
grub_putcode (' ', term_screen->term);
1142
grub_putcode ('\n', term_screen->term);
1145
grub_term_gotoxy (term_screen->term, pos >> 8, pos & 0xFF);
1146
grub_term_refresh (term_screen->term);
1150
clear_completions_all (struct screen *screen)
1154
for (i = 0; i < screen->nterms; i++)
1155
clear_completions (&screen->terms[i]);
1158
/* Execute the command list in the screen SCREEN. */
1160
run (struct screen *screen)
1165
auto grub_err_t editor_getline (char **line, int cont);
1166
grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
1168
struct line *linep = screen->lines + currline;
1171
if (currline > screen->num_lines)
1177
/* Trim down space characters. */
1178
for (p = linep->buf + linep->len - 1;
1179
p >= linep->buf && grub_isspace (*p);
1184
linep->len = p - linep->buf;
1185
for (p = linep->buf; grub_isspace (*p); p++)
1187
*line = grub_strdup (p);
1194
grub_printf_ (N_("Booting a command list"));
1195
grub_printf ("\n\n");
1198
/* Execute the script, line for line. */
1199
while (currline < screen->num_lines)
1201
editor_getline (&nextline, 0);
1202
if (grub_normal_parse_line (nextline, editor_getline))
1206
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
1207
/* Implicit execution of boot, only if something is loaded. */
1208
grub_command_execute ("boot", 0, 0);
1210
if (grub_errno != GRUB_ERR_NONE)
1212
grub_print_error ();
1213
grub_errno = GRUB_ERR_NONE;
1214
grub_wait_after_message ();
1220
/* Edit a menu entry with an Emacs-like interface. */
1222
grub_menu_entry_run (grub_menu_entry_t entry)
1224
struct screen *screen;
1226
grub_err_t err = GRUB_ERR_NONE;
1228
grub_term_output_t term;
1230
err = grub_auth_check_authentication (NULL);
1234
grub_print_error ();
1235
grub_errno = GRUB_ERR_NONE;
1239
screen = make_screen (entry);
1243
screen->terms = NULL;
1246
grub_free (screen->terms);
1248
FOR_ACTIVE_TERM_OUTPUTS(term)
1250
screen->terms = grub_malloc (screen->nterms * sizeof (screen->terms[0]));
1253
grub_print_error ();
1254
grub_errno = GRUB_ERR_NONE;
1258
FOR_ACTIVE_TERM_OUTPUTS(term)
1260
screen->terms[i].term = term;
1261
screen->terms[i].x = 0;
1262
screen->terms[i].y = 0;
1265
/* Draw the screen. */
1266
for (i = 0; i < screen->nterms; i++)
1267
grub_menu_init_page (0, 1, screen->terms[i].term);
1268
update_screen_all (screen, 0, 0, 1, 1, ALL_LINES);
1269
for (i = 0; i < screen->nterms; i++)
1270
grub_term_setcursor (screen->terms[i].term, 1);
1275
int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
1277
if (screen->completion_shown)
1279
clear_completions_all (screen);
1280
screen->completion_shown = 0;
1283
if (grub_normal_exit_level)
1285
destroy_screen (screen);
1292
if (! previous_line (screen, 1))
1297
if (! next_line (screen, 1))
1302
if (! forward_char (screen, 1))
1307
if (! backward_char (screen, 1))
1312
if (! beginning_of_line (screen, 1))
1317
if (! end_of_line (screen, 1))
1321
case '\t': /* C-i */
1322
if (! complete (screen, prev_c == c, 1))
1327
if (! delete_char (screen, 1))
1332
if (! backward_delete_char (screen, 1))
1337
if (! kill_line (screen, prev_c == c, 1))
1342
/* FIXME: What behavior is good for this key? */
1346
if (! yank (screen, 1))
1351
/* FIXME: centering. */
1355
if (! open_line (screen, 1))
1361
if (! insert_string (screen, "\n", 1))
1366
destroy_screen (screen);
1370
grub_cmdline_run (1);
1375
int chars_before = grub_normal_get_char_counter ();
1378
if (chars_before != grub_normal_get_char_counter ())
1379
grub_wait_after_message ();
1390
if (grub_isprint (c))
1396
if (! insert_string (screen, buf, 1))
1406
destroy_screen (screen);
1409
grub_print_error ();
1410
grub_errno = GRUB_ERR_NONE;
1412
grub_printf_ (N_("Press any key to continue..."));
1413
(void) grub_getkey ();