~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to term/terminfo.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
 
/* terminfo.c - simple terminfo module */
2
 
/*
3
 
 *  GRUB  --  GRand Unified Bootloader
4
 
 *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
5
 
 *
6
 
 *  GRUB is free software: you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation, either version 3 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  GRUB is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
/*
21
 
 * This file contains various functions dealing with different
22
 
 * terminal capabilities. For example, vt52 and vt100.
23
 
 */
24
 
 
25
 
#include <grub/types.h>
26
 
#include <grub/misc.h>
27
 
#include <grub/mm.h>
28
 
#include <grub/err.h>
29
 
#include <grub/dl.h>
30
 
#include <grub/term.h>
31
 
#include <grub/terminfo.h>
32
 
#include <grub/tparm.h>
33
 
#include <grub/command.h>
34
 
#include <grub/i18n.h>
35
 
#include <grub/time.h>
36
 
 
37
 
static struct grub_term_output *terminfo_outputs;
38
 
 
39
 
/* Get current terminfo name.  */
40
 
char *
41
 
grub_terminfo_get_current (struct grub_term_output *term)
42
 
{
43
 
  struct grub_terminfo_output_state *data
44
 
    = (struct grub_terminfo_output_state *) term->data;
45
 
  return data->name;
46
 
}
47
 
 
48
 
/* Free *PTR and set *PTR to NULL, to prevent double-free.  */
49
 
static void
50
 
grub_terminfo_free (char **ptr)
51
 
{
52
 
  grub_free (*ptr);
53
 
  *ptr = 0;
54
 
}
55
 
 
56
 
static void
57
 
grub_terminfo_all_free (struct grub_term_output *term)
58
 
{
59
 
  struct grub_terminfo_output_state *data
60
 
    = (struct grub_terminfo_output_state *) term->data;
61
 
 
62
 
  /* Free previously allocated memory.  */
63
 
  grub_terminfo_free (&data->name);
64
 
  grub_terminfo_free (&data->gotoxy);
65
 
  grub_terminfo_free (&data->cls);
66
 
  grub_terminfo_free (&data->reverse_video_on);
67
 
  grub_terminfo_free (&data->reverse_video_off);
68
 
  grub_terminfo_free (&data->cursor_on);
69
 
  grub_terminfo_free (&data->cursor_off);
70
 
}
71
 
 
72
 
/* Set current terminfo type.  */
73
 
grub_err_t
74
 
grub_terminfo_set_current (struct grub_term_output *term,
75
 
                           const char *str)
76
 
{
77
 
  struct grub_terminfo_output_state *data
78
 
    = (struct grub_terminfo_output_state *) term->data;
79
 
  /* TODO
80
 
   * Lookup user specified terminfo type. If found, set term variables
81
 
   * as appropriate. Otherwise return an error.
82
 
   *
83
 
   * How should this be done?
84
 
   *  a. A static table included in this module.
85
 
   *     - I do not like this idea.
86
 
   *  b. A table stored in the configuration directory.
87
 
   *     - Users must convert their terminfo settings if we have not already.
88
 
   *  c. Look for terminfo files in the configuration directory.
89
 
   *     - /usr/share/terminfo is 6.3M on my system.
90
 
   *     - /usr/share/terminfo is not on most users boot partition.
91
 
   *     + Copying the terminfo files you want to use to the grub
92
 
   *       configuration directory is easier then (b).
93
 
   *  d. Your idea here.
94
 
   */
95
 
 
96
 
  grub_terminfo_all_free (term);
97
 
 
98
 
  if (grub_strcmp ("vt100", str) == 0)
99
 
    {
100
 
      data->name              = grub_strdup ("vt100");
101
 
      data->gotoxy            = grub_strdup ("\e[%i%p1%d;%p2%dH");
102
 
      data->cls               = grub_strdup ("\e[H\e[J");
103
 
      data->reverse_video_on  = grub_strdup ("\e[7m");
104
 
      data->reverse_video_off = grub_strdup ("\e[m");
105
 
      data->cursor_on         = grub_strdup ("\e[?25h");
106
 
      data->cursor_off        = grub_strdup ("\e[?25l");
107
 
      data->setcolor          = NULL;
108
 
      return grub_errno;
109
 
    }
110
 
 
111
 
  if (grub_strcmp ("vt100-color", str) == 0)
112
 
    {
113
 
      data->name              = grub_strdup ("vt100-color");
114
 
      data->gotoxy            = grub_strdup ("\e[%i%p1%d;%p2%dH");
115
 
      data->cls               = grub_strdup ("\e[H\e[J");
116
 
      data->reverse_video_on  = grub_strdup ("\e[7m");
117
 
      data->reverse_video_off = grub_strdup ("\e[m");
118
 
      data->cursor_on         = grub_strdup ("\e[?25h");
119
 
      data->cursor_off        = grub_strdup ("\e[?25l");
120
 
      data->setcolor          = grub_strdup ("\e[3%p1%dm\e[4%p2%dm");
121
 
      return grub_errno;
122
 
    }
123
 
 
124
 
  if (grub_strcmp ("ieee1275", str) == 0)
125
 
    {
126
 
      data->name              = grub_strdup ("ieee1275");
127
 
      data->gotoxy            = grub_strdup ("\e[%i%p1%d;%p2%dH");
128
 
      /* Clear the screen.  Using serial console, screen(1) only recognizes the
129
 
       * ANSI escape sequence.  Using video console, Apple Open Firmware
130
 
       * (version 3.1.1) only recognizes the literal ^L.  So use both.  */
131
 
      data->cls               = grub_strdup (" \e[2J");
132
 
      data->reverse_video_on  = grub_strdup ("\e[7m");
133
 
      data->reverse_video_off = grub_strdup ("\e[m");
134
 
      data->cursor_on         = grub_strdup ("\e[?25h");
135
 
      data->cursor_off        = grub_strdup ("\e[?25l");
136
 
      data->setcolor          = grub_strdup ("\e[3%p1%dm\e[4%p2%dm");
137
 
      return grub_errno;
138
 
    }
139
 
 
140
 
  if (grub_strcmp ("dumb", str) == 0)
141
 
    {
142
 
      data->name              = grub_strdup ("dumb");
143
 
      data->gotoxy            = NULL;
144
 
      data->cls               = NULL;
145
 
      data->reverse_video_on  = NULL;
146
 
      data->reverse_video_off = NULL;
147
 
      data->cursor_on         = NULL;
148
 
      data->cursor_off        = NULL;
149
 
      data->setcolor          = NULL;
150
 
      return grub_errno;
151
 
    }
152
 
 
153
 
  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
154
 
}
155
 
 
156
 
grub_err_t
157
 
grub_terminfo_output_register (struct grub_term_output *term,
158
 
                               const char *type)
159
 
{
160
 
  grub_err_t err;
161
 
  struct grub_terminfo_output_state *data;
162
 
 
163
 
  err = grub_terminfo_set_current (term, type);
164
 
 
165
 
  if (err)
166
 
    return err;
167
 
 
168
 
  data = (struct grub_terminfo_output_state *) term->data;
169
 
  data->next = terminfo_outputs;
170
 
  terminfo_outputs = term;
171
 
 
172
 
  return GRUB_ERR_NONE;
173
 
}
174
 
 
175
 
grub_err_t
176
 
grub_terminfo_output_unregister (struct grub_term_output *term)
177
 
{
178
 
  struct grub_term_output **ptr;
179
 
 
180
 
  for (ptr = &terminfo_outputs; *ptr;
181
 
       ptr = &((struct grub_terminfo_output_state *) (*ptr)->data)->next)
182
 
    if (*ptr == term)
183
 
      {
184
 
        grub_terminfo_all_free (term);
185
 
        *ptr = ((struct grub_terminfo_output_state *) (*ptr)->data)->next;
186
 
        return GRUB_ERR_NONE;
187
 
      }
188
 
  return grub_error (GRUB_ERR_BAD_ARGUMENT, "terminal not found");
189
 
}
190
 
 
191
 
/* Wrapper for grub_putchar to write strings.  */
192
 
static void
193
 
putstr (struct grub_term_output *term, const char *str)
194
 
{
195
 
  struct grub_terminfo_output_state *data
196
 
    = (struct grub_terminfo_output_state *) term->data;
197
 
  while (*str)
198
 
    data->put (*str++);
199
 
}
200
 
 
201
 
grub_uint16_t
202
 
grub_terminfo_getxy (struct grub_term_output *term)
203
 
{
204
 
  struct grub_terminfo_output_state *data
205
 
    = (struct grub_terminfo_output_state *) term->data;
206
 
 
207
 
  return ((data->xpos << 8) | data->ypos);
208
 
}
209
 
 
210
 
void
211
 
grub_terminfo_gotoxy (struct grub_term_output *term,
212
 
                      grub_uint8_t x, grub_uint8_t y)
213
 
{
214
 
  struct grub_terminfo_output_state *data
215
 
    = (struct grub_terminfo_output_state *) term->data;
216
 
 
217
 
  if (x > grub_term_width (term) || y > grub_term_height (term))
218
 
    {
219
 
      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
220
 
      return;
221
 
    }
222
 
 
223
 
  if (data->gotoxy)
224
 
    putstr (term, grub_terminfo_tparm (data->gotoxy, y, x));
225
 
  else
226
 
    {
227
 
      if ((y == data->ypos) && (x == data->xpos - 1))
228
 
        data->put ('\b');
229
 
    }
230
 
 
231
 
  data->xpos = x;
232
 
  data->ypos = y;
233
 
}
234
 
 
235
 
/* Clear the screen.  */
236
 
void
237
 
grub_terminfo_cls (struct grub_term_output *term)
238
 
{
239
 
  struct grub_terminfo_output_state *data
240
 
    = (struct grub_terminfo_output_state *) term->data;
241
 
 
242
 
  putstr (term, grub_terminfo_tparm (data->cls));
243
 
 
244
 
  data->xpos = data->ypos = 0;
245
 
}
246
 
 
247
 
void
248
 
grub_terminfo_setcolorstate (struct grub_term_output *term,
249
 
                             const grub_term_color_state state)
250
 
{
251
 
  struct grub_terminfo_output_state *data
252
 
    = (struct grub_terminfo_output_state *) term->data;
253
 
 
254
 
  if (data->setcolor)
255
 
    {
256
 
      int fg;
257
 
      int bg;
258
 
      /* Map from VGA to terminal colors.  */
259
 
      const int colormap[8] 
260
 
        = { 0, /* Black. */
261
 
            4, /* Blue. */
262
 
            2, /* Green. */
263
 
            6, /* Cyan. */
264
 
            1, /* Red.  */
265
 
            5, /* Magenta.  */
266
 
            3, /* Yellow.  */
267
 
            7, /* White.  */
268
 
      };
269
 
 
270
 
      switch (state)
271
 
        {
272
 
        case GRUB_TERM_COLOR_STANDARD:
273
 
        case GRUB_TERM_COLOR_NORMAL:
274
 
          fg = term->normal_color & 0x0f;
275
 
          bg = term->normal_color >> 4;
276
 
          break;
277
 
        case GRUB_TERM_COLOR_HIGHLIGHT:
278
 
          fg = term->highlight_color & 0x0f;
279
 
          bg = term->highlight_color >> 4;
280
 
          break;
281
 
        default:
282
 
          return;
283
 
        }
284
 
 
285
 
      putstr (term, grub_terminfo_tparm (data->setcolor, colormap[fg & 7],
286
 
                                         colormap[bg & 7]));
287
 
      return;
288
 
    }
289
 
 
290
 
  switch (state)
291
 
    {
292
 
    case GRUB_TERM_COLOR_STANDARD:
293
 
    case GRUB_TERM_COLOR_NORMAL:
294
 
      putstr (term, grub_terminfo_tparm (data->reverse_video_off));
295
 
      break;
296
 
    case GRUB_TERM_COLOR_HIGHLIGHT:
297
 
      putstr (term, grub_terminfo_tparm (data->reverse_video_on));
298
 
      break;
299
 
    default:
300
 
      break;
301
 
    }
302
 
}
303
 
 
304
 
void
305
 
grub_terminfo_setcursor (struct grub_term_output *term, const int on)
306
 
{
307
 
  struct grub_terminfo_output_state *data
308
 
    = (struct grub_terminfo_output_state *) term->data;
309
 
 
310
 
  if (on)
311
 
    putstr (term, grub_terminfo_tparm (data->cursor_on));
312
 
  else
313
 
    putstr (term, grub_terminfo_tparm (data->cursor_off));
314
 
}
315
 
 
316
 
/* The terminfo version of putchar.  */
317
 
void
318
 
grub_terminfo_putchar (struct grub_term_output *term,
319
 
                       const struct grub_unicode_glyph *c)
320
 
{
321
 
  struct grub_terminfo_output_state *data
322
 
    = (struct grub_terminfo_output_state *) term->data;
323
 
 
324
 
  /* Keep track of the cursor.  */
325
 
  switch (c->base)
326
 
    {
327
 
    case '\a':
328
 
      break;
329
 
 
330
 
    case '\b':
331
 
    case 127:
332
 
      if (data->xpos > 0)
333
 
        data->xpos--;
334
 
    break;
335
 
 
336
 
    case '\n':
337
 
      if (data->ypos < grub_term_height (term) - 1)
338
 
        data->ypos++;
339
 
      break;
340
 
 
341
 
    case '\r':
342
 
      data->xpos = 0;
343
 
      break;
344
 
 
345
 
    default:
346
 
      if (data->xpos + c->estimated_width >= grub_term_width (term) + 1)
347
 
        {
348
 
          data->xpos = 0;
349
 
          if (data->ypos < grub_term_height (term) - 1)
350
 
            data->ypos++;
351
 
          data->put ('\r');
352
 
          data->put ('\n');
353
 
        }
354
 
      data->xpos += c->estimated_width;
355
 
      break;
356
 
    }
357
 
 
358
 
  data->put (c->base);
359
 
}
360
 
 
361
 
#define ANSI_C0 0x9b
362
 
 
363
 
static void
364
 
grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
365
 
{
366
 
  int c;
367
 
 
368
 
#define CONTINUE_READ                                           \
369
 
  {                                                             \
370
 
    grub_uint64_t start;                                        \
371
 
    /* On 9600 we have to wait up to 12 milliseconds.  */       \
372
 
    start = grub_get_time_ms ();                                \
373
 
    do                                                          \
374
 
      c = readkey ();                                           \
375
 
    while (c == -1 && grub_get_time_ms () - start < 12);        \
376
 
    if (c == -1)                                                \
377
 
      return;                                                   \
378
 
                                                                \
379
 
    keys[*len] = c;                                             \
380
 
    (*len)++;                                                   \
381
 
  }
382
 
 
383
 
  c = readkey ();
384
 
  if (c < 0)
385
 
    {
386
 
      *len = 0;
387
 
      return;
388
 
    }
389
 
  *len = 1;
390
 
  keys[0] = c;
391
 
  if (c != ANSI_C0 && c != '\e')
392
 
    {
393
 
      /* Backspace: Ctrl-h.  */
394
 
      if (c == 0x7f)
395
 
        c = '\b'; 
396
 
      *len = 1;
397
 
      keys[0] = c;
398
 
      return;
399
 
    }
400
 
 
401
 
  {
402
 
    static struct
403
 
    {
404
 
      char key;
405
 
      char ascii;
406
 
    }
407
 
    three_code_table[] =
408
 
      {
409
 
        {'4', GRUB_TERM_DC},
410
 
        {'A', GRUB_TERM_UP},
411
 
        {'B', GRUB_TERM_DOWN},
412
 
        {'C', GRUB_TERM_RIGHT},
413
 
        {'D', GRUB_TERM_LEFT},
414
 
        {'F', GRUB_TERM_END},
415
 
        {'H', GRUB_TERM_HOME},
416
 
        {'K', GRUB_TERM_END},
417
 
        {'P', GRUB_TERM_DC},
418
 
        {'?', GRUB_TERM_PPAGE},
419
 
        {'/', GRUB_TERM_NPAGE}
420
 
      };
421
 
 
422
 
    static struct
423
 
    {
424
 
      char key;
425
 
      char ascii;
426
 
    }
427
 
    four_code_table[] =
428
 
      {
429
 
        {'1', GRUB_TERM_HOME},
430
 
        {'3', GRUB_TERM_DC},
431
 
        {'5', GRUB_TERM_PPAGE},
432
 
        {'6', GRUB_TERM_NPAGE}
433
 
      };
434
 
    unsigned i;
435
 
 
436
 
    if (c == '\e')
437
 
      {
438
 
        CONTINUE_READ;
439
 
 
440
 
        if (c != '[')
441
 
          return;
442
 
      }
443
 
 
444
 
    CONTINUE_READ;
445
 
        
446
 
    for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
447
 
      if (three_code_table[i].key == c)
448
 
        {
449
 
          keys[0] = three_code_table[i].ascii;
450
 
          *len = 1;
451
 
          return;
452
 
        }
453
 
 
454
 
    for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
455
 
      if (four_code_table[i].key == c)
456
 
        {
457
 
          CONTINUE_READ;
458
 
          if (c != '~')
459
 
            return;
460
 
          keys[0] = three_code_table[i].ascii;
461
 
          *len = 1;
462
 
          return;
463
 
        }
464
 
    return;
465
 
  }
466
 
#undef CONTINUE_READ
467
 
}
468
 
 
469
 
/* The terminfo version of checkkey.  */
470
 
int
471
 
grub_terminfo_checkkey (struct grub_term_input *termi)
472
 
{
473
 
  struct grub_terminfo_input_state *data
474
 
    = (struct grub_terminfo_input_state *) (termi->data);
475
 
  if (data->npending)
476
 
    return data->input_buf[0];
477
 
 
478
 
  grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey);
479
 
 
480
 
  if (data->npending)
481
 
    return data->input_buf[0];
482
 
 
483
 
  return -1;
484
 
}
485
 
 
486
 
/* The terminfo version of getkey.  */
487
 
int
488
 
grub_terminfo_getkey (struct grub_term_input *termi)
489
 
{
490
 
  struct grub_terminfo_input_state *data
491
 
    = (struct grub_terminfo_input_state *) (termi->data);
492
 
  int ret;
493
 
  while (! data->npending)
494
 
    grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey);
495
 
 
496
 
  ret = data->input_buf[0];
497
 
  data->npending--;
498
 
  grub_memmove (data->input_buf, data->input_buf + 1, data->npending);
499
 
  return ret;
500
 
}
501
 
 
502
 
grub_err_t
503
 
grub_terminfo_input_init (struct grub_term_input *termi)
504
 
{
505
 
  struct grub_terminfo_input_state *data
506
 
    = (struct grub_terminfo_input_state *) (termi->data);
507
 
  data->npending = 0;
508
 
 
509
 
  return GRUB_ERR_NONE;
510
 
}
511
 
 
512
 
/* GRUB Command.  */
513
 
 
514
 
static grub_err_t
515
 
print_terminfo (void)
516
 
{
517
 
  const char *encoding_names[(GRUB_TERM_CODE_TYPE_MASK 
518
 
                              >> GRUB_TERM_CODE_TYPE_SHIFT) + 1]
519
 
    = {
520
 
    /* VGA and glyph descriptor types are just for completeness,
521
 
       they are not used on terminfo terminals.
522
 
    */
523
 
    [GRUB_TERM_CODE_TYPE_ASCII >> GRUB_TERM_CODE_TYPE_SHIFT] = _("ASCII"),
524
 
    [GRUB_TERM_CODE_TYPE_CP437 >> GRUB_TERM_CODE_TYPE_SHIFT] = "CP-437",
525
 
    [GRUB_TERM_CODE_TYPE_UTF8_LOGICAL >> GRUB_TERM_CODE_TYPE_SHIFT]
526
 
    = _("UTF-8"),
527
 
    [GRUB_TERM_CODE_TYPE_UTF8_VISUAL >> GRUB_TERM_CODE_TYPE_SHIFT]
528
 
    = _("UTF-8 visual"),
529
 
    [GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS >> GRUB_TERM_CODE_TYPE_SHIFT]
530
 
    = "Glyph descriptors",
531
 
    _("Unknown"), _("Unknown"), _("Unknown")
532
 
  };
533
 
  struct grub_term_output *cur;
534
 
 
535
 
  grub_printf ("Current terminfo types: \n");
536
 
  for (cur = terminfo_outputs; cur;
537
 
       cur = ((struct grub_terminfo_output_state *) cur->data)->next)
538
 
    grub_printf ("%s: %s\t%s\n", cur->name,
539
 
                 grub_terminfo_get_current(cur),
540
 
                 encoding_names[(cur->flags & GRUB_TERM_CODE_TYPE_MASK)
541
 
                                >> GRUB_TERM_CODE_TYPE_SHIFT]);
542
 
 
543
 
  return GRUB_ERR_NONE;
544
 
}
545
 
 
546
 
static grub_err_t
547
 
grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
548
 
                   int argc, char **args)
549
 
{
550
 
  struct grub_term_output *cur;
551
 
  int encoding = GRUB_TERM_CODE_TYPE_ASCII;
552
 
  int i;
553
 
  char *name = NULL, *type = NULL;
554
 
 
555
 
  if (argc == 0)
556
 
    return print_terminfo ();
557
 
 
558
 
  for (i = 0; i < argc; i++)
559
 
    {
560
 
      if (grub_strcmp (args[i], "-a") == 0
561
 
          || grub_strcmp (args[i], "--ascii") == 0)
562
 
        {
563
 
          encoding = GRUB_TERM_CODE_TYPE_ASCII;
564
 
          continue;
565
 
        }
566
 
      if (grub_strcmp (args[i], "-u") == 0
567
 
          || grub_strcmp (args[i], "--utf8") == 0)
568
 
        {
569
 
          encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL;
570
 
          continue;
571
 
        }
572
 
      if (grub_strcmp (args[i], "-v") == 0
573
 
          || grub_strcmp (args[i], "--visual-utf8") == 0)
574
 
        {
575
 
          encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL;
576
 
          continue;
577
 
        }
578
 
      if (!name)
579
 
        {
580
 
          name = args[i];
581
 
          continue;
582
 
        }
583
 
      if (!type)
584
 
        {
585
 
          type = args[i];
586
 
          continue;
587
 
        }
588
 
 
589
 
      return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
590
 
    }
591
 
 
592
 
  if (name == NULL)
593
 
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few parameters");
594
 
 
595
 
  for (cur = terminfo_outputs; cur;
596
 
       cur = ((struct grub_terminfo_output_state *) cur->data)->next)
597
 
    if (grub_strcmp (name, cur->name) == 0)
598
 
      {
599
 
        cur->flags = (cur->flags & ~GRUB_TERM_CODE_TYPE_MASK) | encoding;
600
 
        if (!type)
601
 
          return GRUB_ERR_NONE;
602
 
 
603
 
        return grub_terminfo_set_current (cur, type);
604
 
      }
605
 
  return grub_error (GRUB_ERR_BAD_ARGUMENT,
606
 
                     "no terminal %s found or it's not handled by terminfo",
607
 
                     name);
608
 
}
609
 
 
610
 
static grub_command_t cmd;
611
 
 
612
 
GRUB_MOD_INIT(terminfo)
613
 
{
614
 
  cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
615
 
                               N_("[[-a|-u|-v] TERM [TYPE]]"),
616
 
                               N_("Set terminfo type of TERM  to TYPE.\n"
617
 
                                  "-a, --ascii            Terminal is ASCII-only [default].\n"
618
 
                                  "-u, --utf8             Terminal is logical-ordered UTF-8.\n"
619
 
                                  "-v, --visual-utf8      Terminal is visually-ordered UTF-8.")
620
 
 
621
 
                               );
622
 
}
623
 
 
624
 
GRUB_MOD_FINI(terminfo)
625
 
{
626
 
  grub_unregister_command (cmd);
627
 
}