Hell[o]

> I prefer if it can be detected if this is Efika or for example an
> apple implementation of OF and handle these characters depending on
> that.  IIRC this code does work on the apple, but unfortunately I
> cannot check this anymore.

Attached current console patchset. The graphical frames workaround is
used only for SmartFirmware then Apple machines should get cp437
frames normaly. Sorry still no time to split it :( Anyway I will try
to explain a bit each of them.

========

Simple Console: Generaly it seems cp437 frames are used on pc, same
for simple frames using '-' characters which are used for ncurses
console and serial console on pc. I think keep same code in many
places is not so good idea then I moved conversion rutines in to one
place and introduce two term flags GRUB_TERM_SIMPLE_MENU and
GRUB_TERM_CP437_MENU.

In case when term has GRUB_TERM_SIMPLE_MENU set it would automaticly
use '-' frames and same for GRUB_TERM_CP437_MENU to use cp437 frames.
If no flags is set there would be no charset translation for frames.

Cosmetic: In general I see no reason to use multiple
grub_ieee1275_write() calls if we can use single one. Nothing
important, but good to have IMHO.

Backspace: As I already wrote my version of OF seems to sent \b &&
<del> sequence for backspace key. This change cause no side effects on
Efika (USB keyboard) and Pegasos 1 with PS/2 keyboard. Can anyone
check it on Apple OF ? In case of any troubles we can still use a
IEEE1275 flag to use it only for SmartFw.

OFConsole: A biggest patch in pack. Generaly the grub console is
completly broken here (Pegasos 1 && 2, Efika) The x/y cursor tracking
not works as expect to and cursor position is random after few written
lines.

Generaly I introduce realy working x/y position tracking and in result
this give me a working console output in all cases (no random cursor
position after 'ls' command, no empty screen after more than one
output, etc)

Second change was detection of console type (serial, screen,
framebuffer) The reason was to draw frames which looks good in all
three. Default ofconsole uses now simple frames (same for serial
console) and switch to cp437 frames if detect normal screen console,
unfortunatly if of uses framebuffer mode (efika, unofficial OF upgrade
for Pegasos 2) we can not use this frame type as framebuffer font lack
required characters. The reason why framebuffer mode and serial mode
are separated is planned vesa support as I already have a basic vesa
framework we will be able to use it when finished (Then simple frames
on serial console, cp437 on normal console and graphical frames on
framebuffer)

This code uses some new flags:

GRUB_IEEE1275_FLAG_NOFB_ROWS25: For some reason all versions of SF has
25 rows on normal console, but report only 24 which broke the grub
console. This flag was added to workaround this problem.

GRUB_IEEE1275_FLAG_NOCLS: Pegasos 1 OF seems to not interpret the cls
escape then if detected we use \n workaround.

GRUB_IEEE1275_FLAG_BPLAN_LOGO: Arghhh, we can use cp437 frames on
pegasos, but it seems a parts of characters used by grub are replaced
by bPlan logo. Use a workaround proposed here in this case and in a
result have a nice looking grub menu on pegasos/efika too.

I hope I explain everything here. In another e-mail I attach rest of
my patches for grub.

-- 
--- Marcin 'Morgoth' Kurek ---
diff -urN grub2.org/include/grub/term.h grub2/include/grub/term.h
--- grub2.org/include/grub/term.h	2007-07-22 01:32:22.000000000 +0200
+++ grub2/include/grub/term.h	2007-10-15 21:26:48.401210358 +0200
@@ -51,6 +51,10 @@
 #define GRUB_TERM_NO_EDIT	(1 << 1)
 /* Set when the terminal cannot do fancy things.  */
 #define GRUB_TERM_DUMB		(1 << 2)
+/* Set to use ascii menu borders.  */
+#define GRUB_TERM_SIMPLE_MENU	(1 << 3) 
+/* Set to use cp437 menu borders.  */
+#define GRUB_TERM_CP437_MENU	(1 << 4)
 /* Set when the terminal needs to be initialized.  */
 #define GRUB_TERM_NEED_INIT	(1 << 16)
 
diff -urN grub2.org/kern/term.c grub2/kern/term.c
--- grub2.org/kern/term.c	2007-07-22 01:32:26.000000000 +0200
+++ grub2/kern/term.c	2007-10-15 21:26:48.402210358 +0200
@@ -90,6 +90,94 @@
   return grub_cur_term;
 }
 
+static
+grub_uint32_t remap_border(grub_uint32_t code)
+{
+  if (grub_cur_term->flags & GRUB_TERM_SIMPLE_MENU)
+    {
+      switch (code)
+        {
+        case GRUB_TERM_DISP_LEFT:
+          code = '<';
+          break;
+
+        case GRUB_TERM_DISP_UP:
+          code = '^';
+          break;
+
+        case GRUB_TERM_DISP_RIGHT:
+          code = '>';
+          break;
+
+        case GRUB_TERM_DISP_DOWN:
+          code = 'v';
+          break;
+
+        case GRUB_TERM_DISP_HLINE:
+          code = '-';
+          break;
+
+        case GRUB_TERM_DISP_VLINE:
+          code = '|';
+          break;
+                                                                                                    
+        case GRUB_TERM_DISP_UL:
+        case GRUB_TERM_DISP_UR:
+        case GRUB_TERM_DISP_LL:
+        case GRUB_TERM_DISP_LR:
+          code = '+';
+          break;
+        }
+    }
+  else if(grub_cur_term->flags & GRUB_TERM_CP437_MENU)
+    {
+      switch (code)
+        {
+        case GRUB_TERM_DISP_LEFT:
+          code = 0x1b;
+          break;
+
+        case GRUB_TERM_DISP_UP:
+          code = 0x18;
+          break;
+
+        case GRUB_TERM_DISP_RIGHT:
+          code = 0x1a;
+          break;
+
+        case GRUB_TERM_DISP_DOWN:
+          code = 0x19;
+          break;
+
+        case GRUB_TERM_DISP_HLINE:
+          code = 0xc4;
+          break;
+
+        case GRUB_TERM_DISP_VLINE:
+          code = 0xb3;
+          break;
+                                                                                                    
+        case GRUB_TERM_DISP_UL:
+          code = 0xda;
+          break;
+
+        case GRUB_TERM_DISP_UR:
+          code = 0xbf;
+          break;
+
+        case GRUB_TERM_DISP_LL:
+          code = 0xc0;
+          break;
+
+        case GRUB_TERM_DISP_LR:
+          code = 0xd9;
+          break;
+        }
+    }
+
+  return code;
+}
+
 /* Put a Unicode character.  */
 void
 grub_putcode (grub_uint32_t code)
@@ -107,6 +195,8 @@
       return;
     }
   
+  code = remap_border (code);
+
   (grub_cur_term->putchar) (code);
   
   if (code == '\n')
diff -urN grub2.org/term/i386/pc/console.c grub2/term/i386/pc/console.c
--- grub2.org/term/i386/pc/console.c	2007-07-22 01:32:30.000000000 +0200
+++ grub2/term/i386/pc/console.c	2007-10-15 21:26:48.403210358 +0200
@@ -25,58 +25,13 @@
 static grub_uint8_t grub_console_normal_color = 0x7;
 static grub_uint8_t grub_console_highlight_color = 0x70;
 
-static grub_uint32_t
-map_char (grub_uint32_t c)
-{
-  if (c > 0x7f)
-    {
-      /* Map some unicode characters to the VGA font, if possible.  */
-      switch (c)
-	{
-	case 0x2190:	/* left arrow */
-	  c = 0x1b;
-	  break;
-	case 0x2191:	/* up arrow */
-	  c = 0x18;
-	  break;
-	case 0x2192:	/* right arrow */
-	  c = 0x1a;
-	  break;
-	case 0x2193:	/* down arrow */
-	  c = 0x19;
-	  break;
-	case 0x2501:	/* horizontal line */
-	  c = 0xc4;
-	  break;
-	case 0x2503:	/* vertical line */
-	  c = 0xb3;
-	  break;
-	case 0x250F:	/* upper-left corner */
-	  c = 0xda;
-	  break;
-	case 0x2513:	/* upper-right corner */
-	  c = 0xbf;
-	  break;
-	case 0x2517:	/* lower-left corner */
-	  c = 0xc0;
-	  break;
-	case 0x251B:	/* lower-right corner */
-	  c = 0xd9;
-	  break;
-
-	default:
-	  c = '?';
-	  break;
-	}
-    }
-
-  return c;
-}
-
 static void
 grub_console_putchar (grub_uint32_t c)
 {
-  grub_console_real_putchar (map_char (c));
+  /* No Unicode support.  */
+  if (c > 0x7f)
+    c = '?';
+  grub_console_real_putchar (c);
 }
 
 static grub_ssize_t
@@ -133,7 +88,7 @@
     .setcolorstate = grub_console_setcolorstate,
     .setcolor = grub_console_setcolor,
     .setcursor = grub_console_setcursor,
-    .flags = 0,
+    .flags = GRUB_TERM_CP437_MENU,
     .next = 0
   };
 
diff -urN grub2.org/term/i386/pc/serial.c grub2/term/i386/pc/serial.c
--- grub2.org/term/i386/pc/serial.c	2007-07-22 01:32:30.000000000 +0200
+++ grub2/term/i386/pc/serial.c	2007-10-15 21:26:48.405210358 +0200
@@ -324,48 +324,9 @@
   /* Keep track of the cursor.  */
   if (keep_track)
     {
-      /* The serial terminal does not have VGA fonts.  */
+      /* The serial terminal does not support Unicode.  */
       if (c > 0x7F)
-	{
-	  /* Better than nothing.  */
-	  switch (c)
-	    {
-	    case GRUB_TERM_DISP_LEFT:
-	      c = '<';
-	      break;
-	      
-	    case GRUB_TERM_DISP_UP:
-	      c = '^';
-	      break;
-	      
-	    case GRUB_TERM_DISP_RIGHT:
-	      c = '>';
-	      break;
-	      
-	    case GRUB_TERM_DISP_DOWN:
-	      c = 'v';
-	      break;
-	      
-	    case GRUB_TERM_DISP_HLINE:
-	      c = '-';
-	      break;
-	      
-	    case GRUB_TERM_DISP_VLINE:
-	      c = '|';
-	      break;
-	      
-	    case GRUB_TERM_DISP_UL:
-	    case GRUB_TERM_DISP_UR:
-	    case GRUB_TERM_DISP_LL:
-	    case GRUB_TERM_DISP_LR:
-	      c = '+';
-	      break;
-	      
-	    default:
-	      c = '?';
-	      break;
-	    }
-	}
+        c = '?';
       
       switch (c)
 	{
@@ -498,7 +459,7 @@
   .setcolorstate = grub_serial_setcolorstate,
   .setcolor = grub_serial_setcolor,
   .setcursor = grub_serial_setcursor,
-  .flags = 0,
+  .flags = GRUB_TERM_SIMPLE_MENU,
   .next = 0
 };
 
diff -urN grub2.org/term/i386/pc/vesafb.c grub2/term/i386/pc/vesafb.c
--- grub2.org/term/i386/pc/vesafb.c	2007-07-22 01:32:31.000000000 +0200
+++ grub2/term/i386/pc/vesafb.c	2007-10-15 21:26:48.418210358 +0200
@@ -214,45 +214,7 @@
 			       unsigned *width)
 {
   if (code > 0x7f)
-    {
-      /* Map some unicode characters to the VGA font, if possible.  */
-      switch (code)
-	{
-	case 0x2190:	/* left arrow */
-	  code = 0x1b;
-	  break;
-	case 0x2191:	/* up arrow */
-	  code = 0x18;
-	  break;
-	case 0x2192:	/* right arrow */
-	  code = 0x1a;
-	  break;
-	case 0x2193:	/* down arrow */
-	  code = 0x19;
-	  break;
-	case 0x2501:	/* horizontal line */
-	  code = 0xc4;
-	  break;
-	case 0x2503:	/* vertical line */
-	  code = 0xb3;
-	  break;
-	case 0x250F:	/* upper-left corner */
-	  code = 0xda;
-	  break;
-	case 0x2513:	/* upper-right corner */
-	  code = 0xbf;
-	  break;
-	case 0x2517:	/* lower-left corner */
-	  code = 0xc0;
-	  break;
-	case 0x251B:	/* lower-right corner */
-	  code = 0xd9;
-	  break;
-
-	default:
-	  return grub_font_get_glyph (code, bitmap, width);
-	}
-    }
+    return grub_font_get_glyph (code, bitmap, width);
 
   if (bitmap)
     grub_memcpy (bitmap,
@@ -601,7 +563,7 @@
     .setcolorstate = grub_virtual_screen_setcolorstate,
     .setcolor = grub_virtual_screen_setcolor,
     .setcursor = grub_vesafb_setcursor,
-    .flags = 0,
+    .flags = GRUB_TERM_CP437_MENU,
     .next = 0
   };
 
diff -urN grub2.org/term/i386/pc/vga.c grub2/term/i386/pc/vga.c
--- grub2.org/term/i386/pc/vga.c	2007-07-22 01:32:31.000000000 +0200
+++ grub2/term/i386/pc/vga.c	2007-10-15 21:26:48.447210358 +0200
@@ -198,45 +198,7 @@
 get_vga_glyph (grub_uint32_t code, unsigned char bitmap[32], unsigned *width)
 {
   if (code > 0x7f)
-    {
-      /* Map some unicode characters to the VGA font, if possible.  */
-      switch (code)
-	{
-	case 0x2190:	/* left arrow */
-	  code = 0x1b;
-	  break;
-	case 0x2191:	/* up arrow */
-	  code = 0x18;
-	  break;
-	case 0x2192:	/* right arrow */
-	  code = 0x1a;
-	  break;
-	case 0x2193:	/* down arrow */
-	  code = 0x19;
-	  break;
-	case 0x2501:	/* horizontal line */
-	  code = 0xc4;
-	  break;
-	case 0x2503:	/* vertical line */
-	  code = 0xb3;
-	  break;
-	case 0x250F:	/* upper-left corner */
-	  code = 0xda;
-	  break;
-	case 0x2513:	/* upper-right corner */
-	  code = 0xbf;
-	  break;
-	case 0x2517:	/* lower-left corner */
-	  code = 0xc0;
-	  break;
-	case 0x251B:	/* lower-right corner */
-	  code = 0xd9;
-	  break;
-
-	default:
-	  return grub_font_get_glyph (code, bitmap, width);
-	}
-    }
+    return grub_font_get_glyph (code, bitmap, width);
 
   if (bitmap)
     grub_memcpy (bitmap, vga_font + code * CHAR_HEIGHT, CHAR_HEIGHT);
@@ -590,7 +552,7 @@
     .setcolorstate = grub_vga_setcolorstate,
     .setcolor = grub_vga_setcolor,
     .setcursor = grub_vga_setcursor,
-    .flags = 0,
+    .flags = GRUB_TERM_CP437_MENU,
     .next = 0
   };
 
diff -urN grub2.org/term/ieee1275/ofconsole.c grub2/term/ieee1275/ofconsole.c
--- grub2.org/term/ieee1275/ofconsole.c	2007-07-22 11:05:11.000000000 +0200
+++ grub2/term/ieee1275/ofconsole.c	2007-10-15 21:27:17.621210358 +0200
@@ -366,7 +366,7 @@
     .setcolor = grub_ofconsole_setcolor,
     .setcursor = grub_ofconsole_setcursor,
     .refresh = grub_ofconsole_refresh,
-    .flags = 0,
+    .flags = GRUB_TERM_SIMPLE_MENU,
     .next = 0
   };
 
diff -urN grub2.org/util/console.c grub2/util/console.c
--- grub2.org/util/console.c	2007-07-22 01:32:31.000000000 +0200
+++ grub2/util/console.c	2007-10-15 21:26:48.456210358 +0200
@@ -44,47 +44,6 @@
 static void
 grub_ncurses_putchar (grub_uint32_t c)
 {
-  /* Better than nothing.  */
-  switch (c)
-    {
-    case GRUB_TERM_DISP_LEFT:
-      c = '<';
-      break;
-
-    case GRUB_TERM_DISP_UP:
-      c = '^';
-      break;
-
-    case GRUB_TERM_DISP_RIGHT:
-      c = '>';
-      break;
-
-    case GRUB_TERM_DISP_DOWN:
-      c = 'v';
-      break;
-
-    case GRUB_TERM_DISP_HLINE:
-      c = '-';
-      break;
-
-    case GRUB_TERM_DISP_VLINE:
-      c = '|';
-      break;
-
-    case GRUB_TERM_DISP_UL:
-    case GRUB_TERM_DISP_UR:
-    case GRUB_TERM_DISP_LL:
-    case GRUB_TERM_DISP_LR:
-      c = '+';
-      break;
-
-    default:
-      /* ncurses does not support Unicode.  */
-      if (c > 0x7f)
-	c = '?';
-      break;
-    }
-  
   addch (c | grub_console_attr);
 }
 
@@ -302,7 +261,7 @@
     .setcolor = grub_ncurses_setcolor,
     .setcursor = grub_ncurses_setcursor,
     .refresh = grub_ncurses_refresh,
-    .flags = 0,
+    .flags = GRUB_TERM_SIMPLE_MENU,
     .next = 0
   };
 
diff -urN grub2.org/term/ieee1275/ofconsole.c grub2/term/ieee1275/ofconsole.c
--- grub2.org/term/ieee1275/ofconsole.c	2007-10-03 10:55:27.191943734 +0200
+++ grub2/term/ieee1275/ofconsole.c	2007-10-03 10:56:26.399943734 +0200
@@ -63,12 +63,8 @@
 static void
 grub_ofconsole_writeesc (const char *str)
 {
-  while (*str)
-    {
-      char chr = *(str++);
-      grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
-    }
-  
+  int len = grub_strlen(str);
+  grub_ieee1275_write (stdout_ihandle, str, len, 0);
 }
 
 static void
diff -urN grub2.org/term/ieee1275/ofconsole.c grub2/term/ieee1275/ofconsole.c
--- grub2.org/term/ieee1275/ofconsole.c	2007-10-15 21:23:24.554210358 +0200
+++ grub2/term/ieee1275/ofconsole.c	2007-10-15 21:24:13.111210358 +0200
@@ -135,41 +135,54 @@
 
   grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
 
-  if (actual > 0 && c == '\e')
+  if (actual > 0)
     {
-      grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-      if (actual <= 0)
-	{
-	  *key = '\e';
-	  return 1;
-	}
+      if (c != '\e')
+      {
+        switch(c)
+        {
+          case 127:
+            /* Backspace */
+            c = '\b';
+            break;
+        }
+      }
+      else
+      {
+        grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+        if (actual <= 0)
+	  {
+	    *key = '\e';
+	    return 1;
+	  }
       
-      if (c != 91)
-	return 0;
+        if (c != 91)
+	  return 0;
       
-      grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-      if (actual <= 0)
-	return 0;
+        grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+        if (actual <= 0)
+	  return 0;
       
-      switch (c)
-	{
-	case 65:
-	  /* Up: Ctrl-p.  */
-	  c = 16; 
-	  break;
-	case 66:
-	  /* Down: Ctrl-n.  */
-	  c = 14;
-	  break;
-	case 67:
-	  /* Right: Ctrl-f.  */
-	  c = 6;
-	  break;
-	case 68:
-	  /* Left: Ctrl-b.  */
-	  c = 2;
-	  break;
-	}
+        switch (c)
+	  {
+	  case 65:
+	    /* Up: Ctrl-p.  */
+	    c = 16; 
+	    break;
+	  case 66:
+	    /* Down: Ctrl-n.  */
+	    c = 14;
+	    break;
+	  case 67:
+	    /* Right: Ctrl-f.  */
+	    c = 6;
+	    break;
+	  case 68:
+	    /* Left: Ctrl-b.  */
+	    c = 2;
+	    break;
+	  }
+      }
     }
   
   *key = c;
diff -urN grub2.org/include/grub/ieee1275/ieee1275.h grub2/include/grub/ieee1275/ieee1275.h
--- grub2.org/include/grub/ieee1275/ieee1275.h	2007-10-04 22:44:12.000000000 +0200
+++ grub2/include/grub/ieee1275/ieee1275.h	2007-10-10 16:41:39.594688149 +0200
@@ -82,6 +82,16 @@
 
   /* CodeGen firmware does not correctly implement "output-device output" */
   GRUB_IEEE1275_FLAG_BROKEN_OUTPUT,
+
+  /* In non fb mode default number of console rows is 24, but in fact it's 25 */
+  GRUB_IEEE1275_FLAG_NOFB_ROWS25,
+
+  /* Old Pegaos firmware does not accept cls escape sequence */
+  GRUB_IEEE1275_FLAG_NOCLS,
+
+  /* On CodeGen firmware, cp437 characters 0xc0 to 0xcb are reserved for the
+     bplan logo */
+  GRUB_IEEE1275_FLAG_BPLAN_LOGO,
 };
 
 extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);
diff -urN grub2.org/kern/powerpc/ieee1275/cmain.c grub2/kern/powerpc/ieee1275/cmain.c
--- grub2.org/kern/powerpc/ieee1275/cmain.c	2007-10-04 22:44:12.000000000 +0200
+++ grub2/kern/powerpc/ieee1275/cmain.c	2007-10-10 16:42:30.520688149 +0200
@@ -73,6 +73,8 @@
     {
       /* Broken in all versions */
       grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
+      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NOFB_ROWS25);
+      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BPLAN_LOGO);
 
       /* There are two incompatible ways of checking the version number.  Try
          both. */
@@ -98,6 +100,13 @@
 	      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
 	      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
 	    }
+	  /* It seems old firmware for Pegaos 1 do not accept cls escape then
+	     we need to emulate it using \n sequence */
+	  if (!grub_strcmp (tmp, "1.0")
+	      || !grub_strcmp (tmp, "1.1"))
+	    {
+	      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NOCLS);
+	    }
 	}
     }
 }
diff -urN grub2.org/term/ieee1275/ofconsole.c grub2/term/ieee1275/ofconsole.c
--- grub2.org/term/ieee1275/ofconsole.c	2007-10-04 22:44:12.000000000 +0200
+++ grub2/term/ieee1275/ofconsole.c	2007-10-10 16:51:56.829688149 +0200
@@ -24,12 +24,18 @@
 #include <grub/machine/console.h>
 #include <grub/ieee1275/ieee1275.h>
 
+static void grub_ofconsole_setflags(int flags, int x);
+
 static grub_ieee1275_ihandle_t stdout_ihandle;
 static grub_ieee1275_ihandle_t stdin_ihandle;
 
 static grub_uint8_t grub_ofconsole_width;
 static grub_uint8_t grub_ofconsole_height;
 
+/* We will assume serial console by default */
+static grub_uint8_t grub_ofconsole_fb     = 0;
+static grub_uint8_t grub_ofconsole_serial = 1;
+
 static int grub_curr_x;
 static int grub_curr_y;
 
@@ -70,20 +76,76 @@
 static void
 grub_ofconsole_putchar (grub_uint32_t c)
 {
-  char chr = c;
-  
-  if (c == '\n')
+  char chr;
+
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BPLAN_LOGO))
     {
+      /* cp437 characters 0xc0 to 0xcb are reserved for the bplan logo.  Use
+         this layout to workaround it:
+         ╒═╕
+         │ │
+         ╘═╛ */
+      switch (c)
+        {
+        case 0xc4:
+          /* GRUB_TERM_DISP_HLINE */
+          c = 0xcd;
+          break;
+        case 0xb3:
+          /* GRUB_TERM_DISP_VLINE */
+          c = 0xb3;
+          break;
+        case 0xda:
+          /* GRUB_TERM_DISP_UL */
+          c = 0xd5;
+          break;
+        case 0xbf:
+          /* GRUB_TERM_DISP_UR */
+          c = 0xb8;
+          break;
+        case 0xc0:
+          /* GRUB_TERM_DISP_LL */
+          c = 0xd4;
+          break;
+        case 0xd9:
+          /* GRUB_TERM_DISP_LR */
+          c = 0xbe;
+          break;
+        }
+    }
+
+  switch(c)
+  {
+    case '\a':
+      break;            
+    case '\n':
+      grub_putcode ('\r');
       grub_curr_y++;
+      if(grub_curr_y > (grub_ofconsole_height - 1))
+        /* Is this realy correct for all OF versions around ? */
+        grub_curr_y = grub_ofconsole_fb ?
+          grub_curr_y - 4 : grub_ofconsole_height - 1; 
+      break;
+    case '\r':
       grub_curr_x = 0;
-    }
-  else
-    {
+      break;
+    case '\b':
+      if(grub_curr_x > 0)
+        grub_curr_x--;
+      break;
+
+    default:
+      if(c == '\t')
+        c = ' ';
+
+      if (grub_curr_x >= (grub_ofconsole_width - 1))
+        grub_putcode ('\n');
+
       grub_curr_x++;
-      if (grub_curr_x > grub_ofconsole_width)
-	grub_putcode ('\n');
-    }
+      break;
+  }                                                                                                                                                                        
 
+  chr = c;
   grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
 }
 
@@ -228,7 +290,7 @@
 static grub_uint16_t
 grub_ofconsole_getxy (void)
 {
-  return ((grub_curr_x - 1) << 8) | grub_curr_y;
+  return (grub_curr_x << 8) | grub_curr_y;
 }
 
 static grub_uint16_t
@@ -278,6 +340,10 @@
   if (! grub_ofconsole_height)
     grub_ofconsole_height = 24;
 
+  if ( grub_ofconsole_fb == 0 && grub_ofconsole_serial == 0 && grub_ofconsole_height == 24 && 
+       grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NOFB_ROWS25))
+    grub_ofconsole_height = 25;
+
   return (grub_ofconsole_width << 8) | grub_ofconsole_height;
 }
 
@@ -295,10 +361,20 @@
 static void
 grub_ofconsole_cls (void)
 {
-  /* Clear the screen.  Using serial console, screen(1) only recognizes the
-   * ANSI escape sequence.  Using video console, Apple Open Firmware (version
-   * 3.1.1) only recognizes the literal ^L.  So use both.  */
-  grub_ofconsole_writeesc ("\e[2J");
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NOCLS))
+    {
+      /* Clear the screen.  Using serial console, screen(1) only recognizes the
+       * ANSI escape sequence.  Using video console, Apple Open Firmware (version
+       * 3.1.1) only recognizes the literal ^L.  So use both.  */
+      grub_ofconsole_writeesc ("\e[2J");
+    }
+  else
+    {
+      /* It seems no cls escape is available then simulate it using \n flood */
+      int x = (grub_ofconsole_height * 2) - grub_curr_y;
+      while(x--)
+        grub_putcode ('\n');
+    }
   grub_gotoxy (0, 0);
 }
 
@@ -317,6 +393,7 @@
 static grub_err_t
 grub_ofconsole_init (void)
 {
+  grub_ieee1275_phandle_t stdout_phandle;
   unsigned char data[4];
   grub_ssize_t actual;
   int col;
@@ -349,6 +426,48 @@
   /* Set the right fg and bg colors.  */
   grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL);
 
+  /* Check do we are on serial or normal console */
+  if(! grub_ieee1275_instance_to_package (stdout_ihandle, &stdout_phandle))
+    {
+      char type[16];
+      char name[128];
+      
+      if(! grub_ieee1275_get_property (stdout_phandle, "device_type", &type,
+                                       sizeof type, 0) &&
+         ! grub_ieee1275_get_property (stdout_phandle, "name", &name,
+                                       sizeof name, 0))
+        {
+          /*
+           * In general type "serial" is used for console without
+           * framebuffer support in recent firmware versions then
+           * we need to check the name too to determine is it real or
+           * serial console
+           */
+
+          if (! grub_strcmp (type, "serial"))
+            {
+              /* If "name" is something else than "display" we assume serial console */
+              if(! grub_strcmp (name, "display"))
+                  grub_ofconsole_serial = 0;
+            }
+          else
+            { 
+              grub_ofconsole_serial = 0;
+
+              /* Older versions use name/type set to "bootconsole" */
+              if ( grub_strcmp (name, "bootconsole"))
+                grub_ofconsole_fb = 1;
+            }
+        }
+    }
+                        
+  /* Set term flags */
+  if(!grub_ofconsole_serial && !grub_ofconsole_fb)
+    {
+      grub_ofconsole_setflags(GRUB_TERM_SIMPLE_MENU, 0);
+      grub_ofconsole_setflags(GRUB_TERM_CP437_MENU, 1);
+    }
+
   return 0;
 }
 
@@ -377,7 +496,7 @@
     .setcolor = grub_ofconsole_setcolor,
     .setcursor = grub_ofconsole_setcursor,
     .refresh = grub_ofconsole_refresh,
-    .flags = GRUB_TERM_SIMPLE_MENU,
+    .flags = GRUB_TERM_SIMPLE_MENU, /* We are set to serial by default */
     .next = 0
   };
 
@@ -393,3 +512,12 @@
 {
   grub_term_unregister (&grub_ofconsole_term);
 }
+
+static void
+grub_ofconsole_setflags(int flags, int x)
+{
+  if(x)
+    grub_ofconsole_term.flags |= flags;
+  else
+    grub_ofconsole_term.flags &= ~flags;
+}
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to