~ubuntu-branches/debian/stretch/grub2/stretch

« back to all changes in this revision

Viewing changes to normal/term.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <grub/dl.h>
24
24
#include <grub/env.h>
25
25
#include <grub/normal.h>
26
 
 
27
 
/* The amount of lines counted by the pager.  */
28
 
static unsigned grub_more_lines;
 
26
#include <grub/charset.h>
 
27
 
 
28
struct term_state
 
29
{
 
30
  struct term_state *next;
 
31
  const struct grub_unicode_glyph *backlog_glyphs;
 
32
  const grub_uint32_t *backlog_ucs4;
 
33
  grub_size_t backlog_len;
 
34
 
 
35
  void *free;
 
36
  int num_lines;
 
37
  char *term_name;
 
38
};
 
39
 
 
40
static struct term_state *term_states = NULL;
29
41
 
30
42
/* If the more pager is active.  */
31
43
static int grub_more;
32
44
 
33
 
static int grub_normal_line_counter = 0;
 
45
static int grub_normal_char_counter = 0;
34
46
 
35
47
int
36
 
grub_normal_get_line_counter (void)
37
 
{
38
 
  return grub_normal_line_counter;
 
48
grub_normal_get_char_counter (void)
 
49
{
 
50
  return grub_normal_char_counter;
 
51
}
 
52
 
 
53
void
 
54
grub_normal_reset_more (void)
 
55
{
 
56
  static struct term_state *state;
 
57
  for (state = term_states; state; state = state->next)
 
58
    state->num_lines = 0;
39
59
}
40
60
 
41
61
static void
42
 
process_newline (void)
 
62
print_more (void)
43
63
{
44
 
  struct grub_term_output *cur;
45
 
  unsigned height = -1;
46
 
 
47
 
  FOR_ACTIVE_TERM_OUTPUTS(cur)
48
 
    if (grub_term_height (cur) < height)
49
 
      height = grub_term_height (cur);
50
 
  grub_more_lines++;
51
 
 
52
 
  grub_normal_line_counter++;
53
 
 
54
 
  if (grub_more && grub_more_lines >= height - 1)
55
 
    {
56
 
      char key;
57
 
      grub_uint16_t *pos;
58
 
 
59
 
      pos = grub_term_save_pos ();
60
 
 
61
 
      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
62
 
      grub_printf ("--MORE--");
63
 
      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
64
 
 
65
 
      key = grub_getkey ();
66
 
 
67
 
      /* Remove the message.  */
68
 
      grub_term_restore_pos (pos);
69
 
      grub_printf ("        ");
70
 
      grub_term_restore_pos (pos);
71
 
 
72
 
      /* Scroll one lines or an entire page, depending on the key.  */
73
 
      if (key == '\r' || key =='\n')
74
 
        grub_more_lines = height - 2;
75
 
      else
76
 
        grub_more_lines = 0;
 
64
  char key;
 
65
  grub_uint16_t *pos;
 
66
  grub_term_output_t term;
 
67
  grub_uint32_t *unicode_str, *unicode_last_position;
 
68
 
 
69
  pos = grub_term_save_pos ();
 
70
 
 
71
  grub_utf8_to_ucs4_alloc ("--MORE--", &unicode_str,
 
72
                           &unicode_last_position);
 
73
 
 
74
  if (!unicode_str)
 
75
    {
 
76
      grub_errno = GRUB_ERR_NONE;
 
77
      return;
 
78
    }
 
79
 
 
80
  grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
 
81
 
 
82
  FOR_ACTIVE_TERM_OUTPUTS(term)
 
83
  {
 
84
    grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
 
85
  }
 
86
  grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
 
87
 
 
88
  grub_free (unicode_str);
 
89
  
 
90
  key = grub_getkey ();
 
91
 
 
92
  /* Remove the message.  */
 
93
  grub_term_restore_pos (pos);
 
94
  FOR_ACTIVE_TERM_OUTPUTS(term)
 
95
    grub_print_spaces (term, 8);
 
96
  grub_term_restore_pos (pos);
 
97
 
 
98
  /* Scroll one lines or an entire page, depending on the key.  */
 
99
 
 
100
  if (key == '\r' || key =='\n')
 
101
    grub_normal_reset_more ();
 
102
  else
 
103
    {
 
104
      static struct term_state *state;
 
105
      for (state = term_states; state; state = state->next)
 
106
        state->num_lines -= 2;
77
107
    }
78
108
}
79
109
 
84
114
    grub_more++;
85
115
  else
86
116
    grub_more--;
87
 
 
88
 
  grub_more_lines = 0;
 
117
  grub_normal_reset_more ();
89
118
}
90
119
 
91
 
void
92
 
grub_install_newline_hook (void)
 
120
enum
 
121
  {
 
122
    GRUB_CP437_UPARROW         = 0x18,
 
123
    GRUB_CP437_DOWNARROW       = 0x19,
 
124
    GRUB_CP437_RIGHTARROW      = 0x1a,
 
125
    GRUB_CP437_LEFTARROW       = 0x1b,
 
126
    GRUB_CP437_VLINE           = 0xb3,
 
127
    GRUB_CP437_CORNER_UR       = 0xbf,
 
128
    GRUB_CP437_CORNER_LL       = 0xc0,
 
129
    GRUB_CP437_HLINE           = 0xc4,
 
130
    GRUB_CP437_CORNER_LR       = 0xd9,
 
131
    GRUB_CP437_CORNER_UL       = 0xda,
 
132
  };
 
133
 
 
134
static grub_uint32_t
 
135
map_code (grub_uint32_t in, struct grub_term_output *term)
93
136
{
94
 
  grub_newline_hook = process_newline;
 
137
  if (in <= 0x7f)
 
138
    return in;
 
139
 
 
140
  switch (term->flags & GRUB_TERM_CODE_TYPE_MASK)
 
141
    {
 
142
    case GRUB_TERM_CODE_TYPE_CP437:
 
143
      switch (in)
 
144
        {
 
145
        case GRUB_UNICODE_LEFTARROW:
 
146
          return GRUB_CP437_LEFTARROW;
 
147
        case GRUB_UNICODE_UPARROW:
 
148
          return GRUB_CP437_UPARROW;
 
149
        case GRUB_UNICODE_RIGHTARROW:
 
150
          return GRUB_CP437_RIGHTARROW;
 
151
        case GRUB_UNICODE_DOWNARROW:
 
152
          return GRUB_CP437_DOWNARROW;
 
153
        case GRUB_UNICODE_HLINE:
 
154
          return GRUB_CP437_HLINE;
 
155
        case GRUB_UNICODE_VLINE:
 
156
          return GRUB_CP437_VLINE;
 
157
        case GRUB_UNICODE_CORNER_UL:
 
158
          return GRUB_CP437_CORNER_UL;
 
159
        case GRUB_UNICODE_CORNER_UR:
 
160
          return GRUB_CP437_CORNER_UR;
 
161
        case GRUB_UNICODE_CORNER_LL:
 
162
          return GRUB_CP437_CORNER_LL;
 
163
        case GRUB_UNICODE_CORNER_LR:
 
164
          return GRUB_CP437_CORNER_LR;
 
165
        }
 
166
      return '?';
 
167
    case GRUB_TERM_CODE_TYPE_ASCII:
 
168
      /* Better than nothing.  */
 
169
      switch (in)
 
170
        {
 
171
        case GRUB_UNICODE_LEFTARROW:
 
172
          return '<';
 
173
                
 
174
        case GRUB_UNICODE_UPARROW:
 
175
          return '^';
 
176
          
 
177
        case GRUB_UNICODE_RIGHTARROW:
 
178
          return '>';
 
179
                
 
180
        case GRUB_UNICODE_DOWNARROW:
 
181
          return 'v';
 
182
                  
 
183
        case GRUB_UNICODE_HLINE:
 
184
          return '-';
 
185
                  
 
186
        case GRUB_UNICODE_VLINE:
 
187
          return '|';
 
188
                  
 
189
        case GRUB_UNICODE_CORNER_UL:
 
190
        case GRUB_UNICODE_CORNER_UR:
 
191
        case GRUB_UNICODE_CORNER_LL:
 
192
        case GRUB_UNICODE_CORNER_LR:
 
193
          return '+';
 
194
                
 
195
        }
 
196
      return '?';
 
197
    }
 
198
  return in;
95
199
}
96
200
 
97
201
void
98
202
grub_puts_terminal (const char *str, struct grub_term_output *term)
99
203
{
100
 
  grub_uint32_t code;
101
 
  grub_ssize_t ret;
102
 
  const grub_uint8_t *ptr = (const grub_uint8_t *) str;
103
 
  const grub_uint8_t *end;
104
 
  end = (const grub_uint8_t *) (str + grub_strlen (str));
 
204
  grub_uint32_t *unicode_str, *unicode_last_position;
 
205
  grub_utf8_to_ucs4_alloc (str, &unicode_str,
 
206
                           &unicode_last_position);
105
207
 
106
 
  while (*ptr)
107
 
    {
108
 
      ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr);
109
 
      grub_putcode (code, term);        
110
 
    }
 
208
  grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
 
209
  grub_free (unicode_str);
111
210
}
112
211
 
113
212
grub_uint16_t *
262
361
 
263
362
  grub_errno = GRUB_ERR_NONE;
264
363
}
 
364
 
 
365
static void
 
366
putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
 
367
{
 
368
  struct grub_unicode_glyph c2 =
 
369
    {
 
370
      .variant = 0,
 
371
      .attributes = 0,
 
372
      .ncomb = 0,
 
373
      .combining = 0,
 
374
      .estimated_width = 1
 
375
    };
 
376
 
 
377
  grub_normal_char_counter++;
 
378
 
 
379
  if (c->base == '\t' && term->getxy)
 
380
    {
 
381
      int n;
 
382
 
 
383
      n = 8 - ((term->getxy (term) >> 8) & 7);
 
384
      c2.base = ' ';
 
385
      while (n--)
 
386
        (term->putchar) (term, &c2);
 
387
 
 
388
      return;
 
389
    }
 
390
 
 
391
  if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
 
392
      == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL 
 
393
      || (term->flags & GRUB_TERM_CODE_TYPE_MASK)
 
394
      == GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
 
395
    {
 
396
      int i;
 
397
      c2.estimated_width = grub_term_getcharwidth (term, c);
 
398
      for (i = -1; i < (int) c->ncomb; i++)
 
399
        {
 
400
          grub_uint8_t u8[20], *ptr;
 
401
          grub_uint32_t code;
 
402
              
 
403
          if (i == -1)
 
404
            {
 
405
              code = c->base;
 
406
              if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
 
407
                  == GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
 
408
                {
 
409
                  if ((c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR))
 
410
                    code = grub_unicode_mirror_code (code);
 
411
                  code = grub_unicode_shape_code (code, c->attributes);
 
412
                }
 
413
            }
 
414
          else
 
415
            code = c->combining[i].code;
 
416
 
 
417
          grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8));
 
418
 
 
419
          for (ptr = u8; *ptr; ptr++)
 
420
            {
 
421
              c2.base = *ptr;
 
422
              (term->putchar) (term, &c2);
 
423
              c2.estimated_width = 0;
 
424
            }
 
425
        }
 
426
      c2.estimated_width = 1;
 
427
    }
 
428
  else
 
429
    (term->putchar) (term, c);
 
430
 
 
431
  if (c->base == '\n')
 
432
    {
 
433
      c2.base = '\r';
 
434
      (term->putchar) (term, &c2);
 
435
    }
 
436
}
 
437
 
 
438
static void
 
439
putcode_real (grub_uint32_t code, struct grub_term_output *term)
 
440
{
 
441
  struct grub_unicode_glyph c =
 
442
    {
 
443
      .variant = 0,
 
444
      .attributes = 0,
 
445
      .ncomb = 0,
 
446
      .combining = 0,
 
447
      .estimated_width = 1
 
448
    };
 
449
 
 
450
  c.base = map_code (code, term);
 
451
  putglyph (&c, term);
 
452
}
 
453
 
 
454
/* Put a Unicode character.  */
 
455
void
 
456
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
 
457
{
 
458
  /* Combining character by itself?  */
 
459
  if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE)
 
460
    return;
 
461
 
 
462
  putcode_real (code, term);
 
463
}
 
464
 
 
465
static grub_ssize_t
 
466
get_maxwidth (struct grub_term_output *term,
 
467
              int margin_left, int margin_right)
 
468
{
 
469
  struct grub_unicode_glyph space_glyph = {
 
470
    .base = ' ',
 
471
    .variant = 0,
 
472
    .attributes = 0,
 
473
    .ncomb = 0,
 
474
    .combining = 0
 
475
  };
 
476
  return (grub_term_width (term)
 
477
          - grub_term_getcharwidth (term, &space_glyph) 
 
478
          * (margin_left + margin_right) - 1);
 
479
}
 
480
 
 
481
static grub_ssize_t
 
482
get_startwidth (struct grub_term_output *term,
 
483
                int margin_left)
 
484
{
 
485
  return ((term->getxy (term) >> 8) & 0xff) - margin_left;
 
486
}
 
487
 
 
488
static int
 
489
print_ucs4_terminal (const grub_uint32_t * str,
 
490
                     const grub_uint32_t * last_position,
 
491
                     int margin_left, int margin_right,
 
492
                     struct grub_term_output *term,
 
493
                     struct term_state *state)
 
494
{
 
495
  const grub_uint32_t *ptr;
 
496
  grub_ssize_t startwidth = get_startwidth (term, margin_left);
 
497
  grub_ssize_t line_width = startwidth;
 
498
  grub_ssize_t lastspacewidth = 0;
 
499
  grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right);
 
500
  const grub_uint32_t *line_start = str, *last_space = str - 1;
 
501
 
 
502
  for (ptr = str; ptr < last_position; ptr++)
 
503
    {
 
504
      grub_ssize_t last_width = 0;
 
505
      if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE)
 
506
        {
 
507
          struct grub_unicode_glyph c = {
 
508
            .variant = 0,
 
509
            .attributes = 0,
 
510
            .ncomb = 0,
 
511
            .combining = 0
 
512
          };
 
513
          c.base = *ptr;
 
514
          line_width += last_width = grub_term_getcharwidth (term, &c);
 
515
        }
 
516
 
 
517
      if (*ptr == ' ')
 
518
        {
 
519
          lastspacewidth = line_width;
 
520
          last_space = ptr;
 
521
        }
 
522
 
 
523
      if (line_width > max_width || *ptr == '\n')
 
524
        {
 
525
          const grub_uint32_t *ptr2;
 
526
 
 
527
          if (line_width > max_width && last_space > line_start)
 
528
            ptr = last_space;
 
529
          else if (line_width > max_width 
 
530
                   && line_start == str && startwidth != 0)
 
531
            {
 
532
              ptr = str;
 
533
              lastspacewidth = startwidth;
 
534
            }
 
535
          else
 
536
            lastspacewidth = line_width - last_width;
 
537
 
 
538
          for (ptr2 = line_start; ptr2 < ptr; ptr2++)
 
539
            {
 
540
              /* Skip combining characters on non-UTF8 terminals.  */
 
541
              if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
 
542
                  != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
 
543
                  && grub_unicode_get_comb_type (*ptr2)
 
544
                  != GRUB_UNICODE_COMB_NONE)
 
545
                continue;
 
546
              putcode_real (*ptr2, term);
 
547
            }
 
548
 
 
549
          grub_print_spaces (term, margin_right);
 
550
          grub_putcode ('\n', term);
 
551
          if (state && ++state->num_lines
 
552
              >= (grub_ssize_t) grub_term_height (term) - 2)
 
553
            {
 
554
              state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') 
 
555
                ? ptr + 1 : ptr;
 
556
              state->backlog_len = last_position - state->backlog_ucs4;
 
557
              return 1;
 
558
            }
 
559
 
 
560
          line_width -= lastspacewidth;
 
561
          grub_print_spaces (term, margin_left);
 
562
          if (ptr == last_space || *ptr == '\n')
 
563
            ptr++;
 
564
          line_start = ptr;
 
565
        }
 
566
    }
 
567
 
 
568
  {
 
569
    const grub_uint32_t *ptr2;
 
570
    for (ptr2 = line_start; ptr2 < last_position; ptr2++)
 
571
      {
 
572
        /* Skip combining characters on non-UTF8 terminals.  */
 
573
        if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
 
574
            != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
 
575
            && grub_unicode_get_comb_type (*ptr2)
 
576
            != GRUB_UNICODE_COMB_NONE)
 
577
          continue;
 
578
        putcode_real (*ptr2, term);
 
579
      }
 
580
  }
 
581
  return 0;
 
582
}
 
583
 
 
584
static struct term_state *
 
585
find_term_state (struct grub_term_output *term)
 
586
{
 
587
  struct term_state *state;
 
588
  for (state = term_states; state; state = state->next)
 
589
    if (grub_strcmp (state->term_name, term->name) == 0)
 
590
      return state;
 
591
 
 
592
  state = grub_zalloc (sizeof (*state));
 
593
  if (!state)
 
594
    {
 
595
      grub_errno = GRUB_ERR_NONE;
 
596
      return NULL;
 
597
    }
 
598
 
 
599
  state->term_name = grub_strdup (term->name);
 
600
  state->next = term_states;
 
601
  term_states = state;
 
602
 
 
603
  return state;
 
604
}
 
605
 
 
606
static int
 
607
put_glyphs_terminal (const struct grub_unicode_glyph *visual,
 
608
                     grub_ssize_t visual_len,
 
609
                     int margin_left, int margin_right,
 
610
                     struct grub_term_output *term,
 
611
                     struct term_state *state)
 
612
{
 
613
  const struct grub_unicode_glyph *visual_ptr;
 
614
  for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
 
615
    {
 
616
      if (visual_ptr->base == '\n')
 
617
        grub_print_spaces (term, margin_right);
 
618
      putglyph (visual_ptr, term);
 
619
      if (state && ++state->num_lines
 
620
          >= (grub_ssize_t) grub_term_height (term) - 2)
 
621
      {
 
622
        state->backlog_glyphs = visual_ptr + 1;
 
623
        state->backlog_len = visual_len - (visual - visual_ptr) - 1;
 
624
        return 1;
 
625
      }
 
626
 
 
627
      if (visual_ptr->base == '\n')
 
628
        grub_print_spaces (term, margin_left);
 
629
      grub_free (visual_ptr->combining);
 
630
    }
 
631
  return 0;
 
632
}
 
633
 
 
634
static int
 
635
print_backlog (struct grub_term_output *term,
 
636
               int margin_left, int margin_right)
 
637
{
 
638
  struct term_state *state = find_term_state (term);
 
639
 
 
640
  if (!state)
 
641
    return 0;
 
642
 
 
643
  if (state->backlog_ucs4)
 
644
    {
 
645
      int ret;
 
646
      ret = print_ucs4_terminal (state->backlog_ucs4,
 
647
                                 state->backlog_ucs4 + state->backlog_len,
 
648
                                 margin_left, margin_right, term, state);
 
649
      if (!ret)
 
650
        {
 
651
          grub_free (state->free);
 
652
          state->free = NULL;
 
653
          state->backlog_len = 0;
 
654
        }
 
655
      return ret;
 
656
    }
 
657
 
 
658
  if (state->backlog_glyphs)
 
659
    {
 
660
      int ret;
 
661
      ret = put_glyphs_terminal (state->backlog_glyphs,
 
662
                                 state->backlog_len,
 
663
                                 margin_left, margin_right, term, state);
 
664
      if (!ret)
 
665
        {
 
666
          grub_free (state->free);
 
667
          state->free = NULL;
 
668
          state->backlog_len = 0;
 
669
        }
 
670
      return ret;
 
671
    }
 
672
 
 
673
  return 0;
 
674
}
 
675
 
 
676
static int
 
677
print_ucs4_real (const grub_uint32_t * str,
 
678
                 const grub_uint32_t * last_position,
 
679
                 int margin_left, int margin_right,
 
680
                 struct grub_term_output *term, int backlog)
 
681
{
 
682
  struct term_state *state = NULL;
 
683
 
 
684
  if (backlog)
 
685
    state = find_term_state (term);
 
686
 
 
687
  if (((term->getxy (term) >> 8) & 0xff) < margin_left)
 
688
    grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
 
689
 
 
690
  if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
 
691
      == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
 
692
      || (term->flags & GRUB_TERM_CODE_TYPE_MASK) 
 
693
      == GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
 
694
    {
 
695
      grub_ssize_t visual_len;
 
696
      struct grub_unicode_glyph *visual;
 
697
      int ret;
 
698
 
 
699
      auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c);
 
700
      grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c)
 
701
      {
 
702
        return grub_term_getcharwidth (term, c);
 
703
      }
 
704
 
 
705
      visual_len = grub_bidi_logical_to_visual (str, last_position - str,
 
706
                                                &visual, getcharwidth,
 
707
                                                get_maxwidth (term, 
 
708
                                                              margin_left,
 
709
                                                              margin_right),
 
710
                                                get_startwidth (term, 
 
711
                                                                margin_left));
 
712
      if (visual_len < 0)
 
713
        {
 
714
          grub_print_error ();
 
715
          return 0;
 
716
        }
 
717
      ret = put_glyphs_terminal (visual, visual_len, margin_left, margin_right,
 
718
                                 term, state);
 
719
      if (!ret)
 
720
        grub_free (visual);
 
721
      else
 
722
        state->free = visual;
 
723
      return ret;
 
724
    }
 
725
  return print_ucs4_terminal (str, last_position, margin_left, margin_right,
 
726
                              term, state);
 
727
}
 
728
 
 
729
void
 
730
grub_print_ucs4 (const grub_uint32_t * str,
 
731
                 const grub_uint32_t * last_position,
 
732
                 int margin_left, int margin_right,
 
733
                 struct grub_term_output *term)
 
734
{
 
735
  print_ucs4_real (str, last_position, margin_left, margin_right,
 
736
                   term, 0);
 
737
}
 
738
 
 
739
 
 
740
void
 
741
grub_xputs_normal (const char *str)
 
742
{
 
743
  grub_term_output_t term;
 
744
  grub_uint32_t *unicode_str, *unicode_last_position;
 
745
  int backlog = 0;
 
746
  grub_utf8_to_ucs4_alloc (str, &unicode_str,
 
747
                           &unicode_last_position);
 
748
 
 
749
  if (!unicode_str)
 
750
    {
 
751
      grub_errno = GRUB_ERR_NONE;
 
752
      return;
 
753
    }
 
754
 
 
755
  FOR_ACTIVE_TERM_OUTPUTS(term)
 
756
  {
 
757
    int cur;
 
758
    cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0,
 
759
                           term, grub_more);
 
760
    if (cur)
 
761
      backlog = 1;
 
762
  }
 
763
  while (backlog)
 
764
    {
 
765
      print_more ();
 
766
      backlog = 0;
 
767
      FOR_ACTIVE_TERM_OUTPUTS(term)
 
768
      {
 
769
        int cur;
 
770
        cur = print_backlog (term, 0, 0);
 
771
        if (cur)
 
772
          backlog = 1;
 
773
      }
 
774
    }
 
775
  grub_free (unicode_str);
 
776
}
 
777
 
 
778
void
 
779
grub_cls (void)
 
780
{
 
781
  struct grub_term_output *term;
 
782
 
 
783
  FOR_ACTIVE_TERM_OUTPUTS(term)  
 
784
  {
 
785
    if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
 
786
      {
 
787
        grub_putcode ('\n', term);
 
788
        grub_term_refresh (term);
 
789
      }
 
790
    else
 
791
      (term->cls) (term);
 
792
  }
 
793
}