~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to grub-core/term/efi/console.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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/>.
 
17
 */
 
18
 
 
19
#include <grub/term.h>
 
20
#include <grub/misc.h>
 
21
#include <grub/types.h>
 
22
#include <grub/err.h>
 
23
#include <grub/efi/efi.h>
 
24
#include <grub/efi/api.h>
 
25
#include <grub/efi/console.h>
 
26
 
 
27
static grub_uint32_t
 
28
map_char (grub_uint32_t c)
 
29
{
 
30
  /* Map some unicode characters to the EFI character.  */
 
31
  switch (c)
 
32
    {
 
33
    case GRUB_UNICODE_LEFTARROW:
 
34
      c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE;
 
35
      break;
 
36
    case GRUB_UNICODE_UPARROW:
 
37
      c = GRUB_UNICODE_BLACK_UP_TRIANGLE;
 
38
      break;
 
39
    case GRUB_UNICODE_RIGHTARROW:
 
40
      c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE;
 
41
      break;
 
42
    case GRUB_UNICODE_DOWNARROW:
 
43
      c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE;
 
44
      break;
 
45
    case GRUB_UNICODE_HLINE:
 
46
      c = GRUB_UNICODE_LIGHT_HLINE;
 
47
      break;
 
48
    case GRUB_UNICODE_VLINE:
 
49
      c = GRUB_UNICODE_LIGHT_VLINE;
 
50
      break;
 
51
    case GRUB_UNICODE_CORNER_UL:
 
52
      c = GRUB_UNICODE_LIGHT_CORNER_UL;
 
53
      break;
 
54
    case GRUB_UNICODE_CORNER_UR:
 
55
      c = GRUB_UNICODE_LIGHT_CORNER_UR;
 
56
      break;
 
57
    case GRUB_UNICODE_CORNER_LL:
 
58
      c = GRUB_UNICODE_LIGHT_CORNER_LL;
 
59
      break;
 
60
    case GRUB_UNICODE_CORNER_LR:
 
61
      c = GRUB_UNICODE_LIGHT_CORNER_LR;
 
62
      break;
 
63
    }
 
64
 
 
65
  return c;
 
66
}
 
67
 
 
68
static void
 
69
grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
 
70
                      const struct grub_unicode_glyph *c)
 
71
{
 
72
  grub_efi_char16_t str[2 + c->ncomb];
 
73
  grub_efi_simple_text_output_interface_t *o;
 
74
  unsigned i, j;
 
75
 
 
76
  if (grub_efi_is_finished)
 
77
    return;
 
78
 
 
79
  o = grub_efi_system_table->con_out;
 
80
 
 
81
  /* For now, do not try to use a surrogate pair.  */
 
82
  if (c->base > 0xffff)
 
83
    str[0] = '?';
 
84
  else
 
85
    str[0] = (grub_efi_char16_t)  map_char (c->base & 0xffff);
 
86
  j = 1;
 
87
  for (i = 0; i < c->ncomb; i++)
 
88
    if (c->base < 0xffff)
 
89
      str[j++] = c->combining[i].code;
 
90
  str[j] = 0;
 
91
 
 
92
  /* Should this test be cached?  */
 
93
  if ((c->base > 0x7f || c->ncomb)
 
94
      && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
 
95
    return;
 
96
 
 
97
  efi_call_2 (o->output_string, o, str);
 
98
}
 
99
 
 
100
const unsigned efi_codes[] =
 
101
  {
 
102
    0, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_RIGHT,
 
103
    GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_END, GRUB_TERM_KEY_INSERT,
 
104
    GRUB_TERM_KEY_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_F1,
 
105
    GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5,
 
106
    GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9,
 
107
    GRUB_TERM_KEY_F10, 0, 0, '\e'
 
108
  };
 
109
 
 
110
 
 
111
static int
 
112
grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
 
113
{
 
114
  grub_efi_simple_input_interface_t *i;
 
115
  grub_efi_input_key_t key;
 
116
  grub_efi_status_t status;
 
117
 
 
118
  if (grub_efi_is_finished)
 
119
    return 0;
 
120
 
 
121
  i = grub_efi_system_table->con_in;
 
122
  status = efi_call_2 (i->read_key_stroke, i, &key);
 
123
 
 
124
  if (status != GRUB_EFI_SUCCESS)
 
125
    return GRUB_TERM_NO_KEY;
 
126
 
 
127
  if (key.scan_code == 0)
 
128
    return key.unicode_char;
 
129
  else if (key.scan_code < ARRAY_SIZE (efi_codes))
 
130
    return efi_codes[key.scan_code];
 
131
 
 
132
  return GRUB_TERM_NO_KEY;
 
133
}
 
134
 
 
135
static grub_uint16_t
 
136
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
 
137
{
 
138
  grub_efi_simple_text_output_interface_t *o;
 
139
  grub_efi_uintn_t columns, rows;
 
140
 
 
141
  o = grub_efi_system_table->con_out;
 
142
  if (grub_efi_is_finished || efi_call_4 (o->query_mode, o, o->mode->mode,
 
143
                                          &columns, &rows) != GRUB_EFI_SUCCESS)
 
144
    {
 
145
      /* Why does this fail?  */
 
146
      columns = 80;
 
147
      rows = 25;
 
148
    }
 
149
 
 
150
  return ((columns << 8) | rows);
 
151
}
 
152
 
 
153
static grub_uint16_t
 
154
grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
 
155
{
 
156
  grub_efi_simple_text_output_interface_t *o;
 
157
 
 
158
  if (grub_efi_is_finished)
 
159
    return 0;
 
160
 
 
161
  o = grub_efi_system_table->con_out;
 
162
  return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
 
163
}
 
164
 
 
165
static void
 
166
grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
 
167
                     grub_uint8_t x, grub_uint8_t y)
 
168
{
 
169
  grub_efi_simple_text_output_interface_t *o;
 
170
 
 
171
  if (grub_efi_is_finished)
 
172
    return;
 
173
 
 
174
  o = grub_efi_system_table->con_out;
 
175
  efi_call_3 (o->set_cursor_position, o, x, y);
 
176
}
 
177
 
 
178
static void
 
179
grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
 
180
{
 
181
  grub_efi_simple_text_output_interface_t *o;
 
182
  grub_efi_int32_t orig_attr;
 
183
 
 
184
  if (grub_efi_is_finished)
 
185
    return;
 
186
 
 
187
  o = grub_efi_system_table->con_out;
 
188
  orig_attr = o->mode->attribute;
 
189
  efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
 
190
  efi_call_1 (o->clear_screen, o);
 
191
  efi_call_2 (o->set_attributes, o, orig_attr);
 
192
}
 
193
 
 
194
static void
 
195
grub_console_setcolorstate (struct grub_term_output *term,
 
196
                            grub_term_color_state state)
 
197
{
 
198
  grub_efi_simple_text_output_interface_t *o;
 
199
 
 
200
  if (grub_efi_is_finished)
 
201
    return;
 
202
 
 
203
  o = grub_efi_system_table->con_out;
 
204
 
 
205
  switch (state) {
 
206
    case GRUB_TERM_COLOR_STANDARD:
 
207
      efi_call_2 (o->set_attributes, o, GRUB_TERM_DEFAULT_STANDARD_COLOR
 
208
                  & 0x7f);
 
209
      break;
 
210
    case GRUB_TERM_COLOR_NORMAL:
 
211
      efi_call_2 (o->set_attributes, o, term->normal_color & 0x7f);
 
212
      break;
 
213
    case GRUB_TERM_COLOR_HIGHLIGHT:
 
214
      efi_call_2 (o->set_attributes, o, term->highlight_color & 0x7f);
 
215
      break;
 
216
    default:
 
217
      break;
 
218
  }
 
219
}
 
220
 
 
221
static void
 
222
grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
 
223
                        int on)
 
224
{
 
225
  grub_efi_simple_text_output_interface_t *o;
 
226
 
 
227
  if (grub_efi_is_finished)
 
228
    return;
 
229
 
 
230
  o = grub_efi_system_table->con_out;
 
231
  efi_call_2 (o->enable_cursor, o, on);
 
232
}
 
233
 
 
234
static grub_err_t
 
235
grub_efi_console_init (struct grub_term_output *term)
 
236
{
 
237
  grub_console_setcursor (term, 1);
 
238
  return 0;
 
239
}
 
240
 
 
241
static grub_err_t
 
242
grub_efi_console_fini (struct grub_term_output *term)
 
243
{
 
244
  grub_console_setcursor (term, 0);
 
245
  return 0;
 
246
}
 
247
 
 
248
static struct grub_term_input grub_console_term_input =
 
249
  {
 
250
    .name = "console",
 
251
    .getkey = grub_console_getkey,
 
252
  };
 
253
 
 
254
static struct grub_term_output grub_console_term_output =
 
255
  {
 
256
    .name = "console",
 
257
    .init = grub_efi_console_init,
 
258
    .fini = grub_efi_console_fini,
 
259
    .putchar = grub_console_putchar,
 
260
    .getwh = grub_console_getwh,
 
261
    .getxy = grub_console_getxy,
 
262
    .gotoxy = grub_console_gotoxy,
 
263
    .cls = grub_console_cls,
 
264
    .setcolorstate = grub_console_setcolorstate,
 
265
    .setcursor = grub_console_setcursor,
 
266
    .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
 
267
    .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
 
268
    .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
 
269
  };
 
270
 
 
271
void
 
272
grub_console_init (void)
 
273
{
 
274
  /* FIXME: it is necessary to consider the case where no console control
 
275
     is present but the default is already in text mode.  */
 
276
  if (! grub_efi_set_text_mode (1))
 
277
    {
 
278
      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
 
279
      return;
 
280
    }
 
281
 
 
282
  grub_term_register_input ("console", &grub_console_term_input);
 
283
  grub_term_register_output ("console", &grub_console_term_output);
 
284
}
 
285
 
 
286
void
 
287
grub_console_fini (void)
 
288
{
 
289
  grub_term_unregister_input (&grub_console_term_input);
 
290
  grub_term_unregister_output (&grub_console_term_output);
 
291
}