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

« back to all changes in this revision

Viewing changes to term/terminfo.c

Tags: upstream-1.98+20100705
ImportĀ upstreamĀ versionĀ 1.98+20100705

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include <grub/tparm.h>
33
33
#include <grub/command.h>
34
34
#include <grub/i18n.h>
35
 
 
36
 
struct terminfo
37
 
{
38
 
  char *name;
39
 
 
40
 
  char *gotoxy;
41
 
  char *cls;
42
 
  char *reverse_video_on;
43
 
  char *reverse_video_off;
44
 
  char *cursor_on;
45
 
  char *cursor_off;
46
 
};
47
 
 
48
 
static struct terminfo term;
 
35
#include <grub/time.h>
 
36
 
 
37
static struct grub_term_output *terminfo_outputs;
49
38
 
50
39
/* Get current terminfo name.  */
51
40
char *
52
 
grub_terminfo_get_current (void)
 
41
grub_terminfo_get_current (struct grub_term_output *term)
53
42
{
54
 
  return term.name;
 
43
  struct grub_terminfo_output_state *data
 
44
    = (struct grub_terminfo_output_state *) term->data;
 
45
  return data->name;
55
46
}
56
47
 
57
48
/* Free *PTR and set *PTR to NULL, to prevent double-free.  */
62
53
  *ptr = 0;
63
54
}
64
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
 
65
72
/* Set current terminfo type.  */
66
73
grub_err_t
67
 
grub_terminfo_set_current (const char *str)
 
74
grub_terminfo_set_current (struct grub_term_output *term,
 
75
                           const char *str)
68
76
{
 
77
  struct grub_terminfo_output_state *data
 
78
    = (struct grub_terminfo_output_state *) term->data;
69
79
  /* TODO
70
80
   * Lookup user specified terminfo type. If found, set term variables
71
81
   * as appropriate. Otherwise return an error.
83
93
   *  d. Your idea here.
84
94
   */
85
95
 
86
 
  /* Free previously allocated memory.  */
87
 
  grub_terminfo_free (&term.name);
88
 
  grub_terminfo_free (&term.gotoxy);
89
 
  grub_terminfo_free (&term.cls);
90
 
  grub_terminfo_free (&term.reverse_video_on);
91
 
  grub_terminfo_free (&term.reverse_video_off);
92
 
  grub_terminfo_free (&term.cursor_on);
93
 
  grub_terminfo_free (&term.cursor_off);
 
96
  grub_terminfo_all_free (term);
94
97
 
95
98
  if (grub_strcmp ("vt100", str) == 0)
96
99
    {
97
 
      term.name              = grub_strdup ("vt100");
98
 
      term.gotoxy            = grub_strdup ("\e[%i%p1%d;%p2%dH");
99
 
      term.cls               = grub_strdup ("\e[H\e[J");
100
 
      term.reverse_video_on  = grub_strdup ("\e[7m");
101
 
      term.reverse_video_off = grub_strdup ("\e[m");
102
 
      term.cursor_on         = grub_strdup ("\e[?25h");
103
 
      term.cursor_off        = grub_strdup ("\e[?25l");
 
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;
104
150
      return grub_errno;
105
151
    }
106
152
 
107
153
  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
108
154
}
109
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
 
110
191
/* Wrapper for grub_putchar to write strings.  */
111
192
static void
112
 
putstr (const char *str, grub_term_output_t oterm)
 
193
putstr (struct grub_term_output *term, const char *str)
113
194
{
 
195
  struct grub_terminfo_output_state *data
 
196
    = (struct grub_terminfo_output_state *) term->data;
114
197
  while (*str)
115
 
    grub_putcode (*str++, oterm);
116
 
}
117
 
 
118
 
/* Move the cursor to the given position starting with "0".  */
 
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
 
119
210
void
120
 
grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
 
211
grub_terminfo_gotoxy (struct grub_term_output *term,
 
212
                      grub_uint8_t x, grub_uint8_t y)
121
213
{
122
 
  putstr (grub_terminfo_tparm (term.gotoxy, y, x), oterm);
 
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;
123
233
}
124
234
 
125
235
/* Clear the screen.  */
126
236
void
127
 
grub_terminfo_cls (grub_term_output_t oterm)
128
 
{
129
 
  putstr (grub_terminfo_tparm (term.cls), oterm);
130
 
}
131
 
 
132
 
/* Set reverse video mode on.  */
133
 
void
134
 
grub_terminfo_reverse_video_on (grub_term_output_t oterm)
135
 
{
136
 
  putstr (grub_terminfo_tparm (term.reverse_video_on), oterm);
137
 
}
138
 
 
139
 
/* Set reverse video mode off.  */
140
 
void
141
 
grub_terminfo_reverse_video_off (grub_term_output_t oterm)
142
 
{
143
 
  putstr (grub_terminfo_tparm (term.reverse_video_off), oterm);
144
 
}
145
 
 
146
 
/* Show cursor.  */
147
 
void
148
 
grub_terminfo_cursor_on (grub_term_output_t oterm)
149
 
{
150
 
  putstr (grub_terminfo_tparm (term.cursor_on), oterm);
151
 
}
152
 
 
153
 
/* Hide cursor.  */
154
 
void
155
 
grub_terminfo_cursor_off (grub_term_output_t oterm)
156
 
{
157
 
  putstr (grub_terminfo_tparm (term.cursor_off), oterm);
 
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;
158
510
}
159
511
 
160
512
/* GRUB Command.  */
161
513
 
162
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
163
547
grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
164
548
                   int argc, char **args)
165
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
 
166
555
  if (argc == 0)
167
 
  {
168
 
    grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
169
 
    return GRUB_ERR_NONE;
170
 
  }
171
 
  else if (argc != 1)
172
 
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
173
 
  else
174
 
    return grub_terminfo_set_current (args[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);
175
608
}
176
609
 
177
610
static grub_command_t cmd;
179
612
GRUB_MOD_INIT(terminfo)
180
613
{
181
614
  cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
182
 
                               N_("[TERM]"), N_("Set terminfo type."));
183
 
  grub_terminfo_set_current ("vt100");
 
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
                               );
184
622
}
185
623
 
186
624
GRUB_MOD_FINI(terminfo)