# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: colin@gibibit.com-20080705175913-xmp2j688zzymz798
# target_branch: ../../repo/cdbmain
# testament_sha1: f20a1f4db0c7558275043ca686fb96b6b43d1947
# timestamp: 2008-07-05 11:47:43 -0700
# source_branch: http://grub.gibibit.com/bzr/cdbmain
# base_revision_id: colin@gibibit.com-20080704214036-04igfy0boo1z9489
# 
# Begin patch
=== modified file 'conf/common.rmk'
--- conf/common.rmk	2008-07-03 14:12:08 +0000
+++ conf/common.rmk	2008-07-05 17:04:34 +0000
@@ -287,6 +287,7 @@
 	cmp.mod cat.mod help.mod font.mod search.mod		\
 	loopback.mod fs_uuid.mod configfile.mod echo.mod	\
 	terminfo.mod test.mod blocklist.mod hexdump.mod		\
+	protomenu.mod                                           \
 	read.mod sleep.mod loadenv.mod
 
 # For hello.mod.
@@ -374,6 +375,11 @@
 hexdump_mod_CFLAGS = $(COMMON_CFLAGS)
 hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For protomenu.mod.
+protomenu_mod_SOURCES = protomenu/protomenu.c
+protomenu_mod_CFLAGS = $(COMMON_CFLAGS)
+protomenu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For read.mod.
 read_mod_SOURCES = commands/read.c
 read_mod_CFLAGS = $(COMMON_CFLAGS)

=== added directory 'protomenu'
=== added file 'protomenu/protomenu.c'
--- protomenu/protomenu.c	1970-01-01 00:00:00 +0000
+++ protomenu/protomenu.c	2008-07-05 17:59:13 +0000
@@ -0,0 +1,277 @@
+/* protomenu.c - Prototype graphical menu: command implementation. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2003  NIIBE Yutaka <gniibe@m17n.org>
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+#include <grub/term.h>
+
+/* A 2D rectangle type.
+ * This could be worth integrating into the video API if it proves useful.*/
+struct grub_video_rect
+{
+  /* These are signed because if there are unsigned it causes Bad Things 
+   * to happen when arithmetic and comparisions involving signed types is 
+   * done.  Important signed types include offsets from absolute locations. */
+  int x;
+  int y;
+  int width;
+  int height;
+};
+typedef struct grub_video_rect grub_video_rect_t;
+
+typedef struct menu_item
+{
+  const char *name;
+  struct grub_video_bitmap *icon;
+  /* TODO add a command to execute. */
+}
+menu_item_t;
+
+static const int icon_width = 48;
+static const int icon_height = 48;
+static grub_video_rect_t screen;
+static grub_font_t title_font;
+static grub_font_t item_font;
+static grub_font_t status_font;
+static grub_video_color_t title_color;
+static grub_video_color_t item_color;
+static grub_video_color_t status_color;
+static grub_video_color_t status_bg_color;
+static struct grub_video_bitmap *background_image;
+static const char title_text[] = "GRUB 2 Boot Menu";
+static menu_item_t items[3];
+static int selected_item_index;
+
+static void
+style_init (void)
+{
+  if (!(title_font = grub_font_get ("Helvetica Bold 24"))
+      || !(item_font = grub_font_get ("Helvetica Bold 14"))
+      || !(status_font = grub_font_get ("Helvetica 10")))
+    return;
+
+  title_color = grub_video_map_rgb (0, 0, 0);
+  item_color = grub_video_map_rgb (0, 0, 0);
+  status_color = grub_video_map_rgb (255, 255, 255);
+  status_bg_color = grub_video_map_rgba (0, 0, 0, 112);
+
+  struct grub_video_bitmap *img;
+  grub_video_bitmap_load (&img, "/boot/images/bg-protomenu1.tga");
+  if (grub_errno != GRUB_ERR_NONE)
+    return;
+
+  grub_video_bitmap_create_scaled (&background_image, screen.width,
+                                   screen.height, img,
+                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+  if (grub_errno != GRUB_ERR_NONE)
+    return;
+  grub_video_bitmap_destroy (img);
+
+
+  items[0].name = "Ubuntu 8.10";
+  grub_video_bitmap_load (&img, "/boot/images/icon-ubuntu.tga");
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_create_scaled (&items[0].icon, icon_width,
+                                       icon_height, img,
+                                       GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+      if (grub_errno != GRUB_ERR_NONE)
+        return;
+      grub_video_bitmap_destroy (img);
+    }
+
+  items[1].name = "Gentoo Linux";
+  grub_video_bitmap_load (&img, "/boot/images/icon-gentoo.tga");
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_create_scaled (&items[1].icon, icon_width,
+                                       icon_height, img,
+                                       GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+      if (grub_errno != GRUB_ERR_NONE)
+        return;
+      grub_video_bitmap_destroy (img);
+    }
+
+  items[2].name = "Windows Vista";
+  grub_video_bitmap_load (&img, "/boot/images/icon-vista.tga");
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_create_scaled (&items[2].icon, icon_width,
+                                       icon_height, img,
+                                       GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+      if (grub_errno != GRUB_ERR_NONE)
+        return;
+      grub_video_bitmap_destroy (img);
+    }
+}
+
+static void
+draw_background (void)
+{
+  grub_video_blit_bitmap (background_image, GRUB_VIDEO_BLIT_REPLACE,
+                          0, 0, 0, 0,
+                          grub_video_bitmap_get_width (background_image),
+                          grub_video_bitmap_get_height (background_image));
+}
+
+static void
+draw_menu (void)
+{
+  /* TODO make this use pixmaps and draw a cool menu */
+
+  grub_video_rect_t r;
+  r.width = screen.width * 2 / 3;
+  r.height = screen.height * 1 / 2;
+  r.x = (screen.width - r.width) / 2;
+  r.y = (screen.height - r.height) / 2;
+
+  grub_video_color_t bg = grub_video_map_rgb (255, 255, 255);
+  grub_video_fill_rect (bg, r.x, r.y, r.width, r.height);
+
+  int boxpad = 6;
+  int icon_text_space = 4;
+  int item_pad = 3;
+  int item_vspace = 2;
+
+  int ascent = grub_font_get_ascent (item_font);
+  int descent = grub_font_get_descent (item_font);
+  int item_top = r.y + boxpad;
+  int item_left = r.x + boxpad;
+  int item_height = 54;
+  unsigned i;
+  for (i = 0; i < sizeof (items) / sizeof (*items); i++)
+    {
+      if ((int) i == selected_item_index)
+        {
+          /* TODO use pixmap-stylized box to highlight selected item */
+          grub_video_fill_rect (grub_video_map_rgb (128, 128, 255),
+                                item_left, item_top,
+                                r.width - 2 * boxpad, item_height);
+        }
+
+      if (items[i].icon)
+        grub_video_blit_bitmap (items[i].icon, GRUB_VIDEO_BLIT_BLEND,
+                                item_left,
+                                item_top + (item_height - icon_height) / 2,
+                                0, 0, icon_width, icon_height);
+
+      grub_video_draw_string (items[i].name, item_font, item_color,
+                              item_left + icon_width + icon_text_space,
+                              (item_top + (item_height - (ascent + descent)) 
+                               / 2 + ascent));
+
+      item_top += item_height + item_vspace;
+    }
+}
+
+static void
+draw_title (void)
+{
+  /* Center the title. */
+  int title_width = grub_font_get_string_width (title_font, title_text);
+  int x = (screen.width - title_width) / 2;
+  int y = 40 + grub_font_get_ascent (title_font);
+  grub_video_draw_string (title_text, title_font, title_color, x, y);
+}
+
+static void
+draw_status (void)
+{
+  int descent = grub_font_get_descent (status_font);
+  int ascent = grub_font_get_ascent (status_font);
+  int vpad = 5;
+  int textheight = descent + ascent;
+  int h = 2 * vpad + textheight;
+
+  grub_video_fill_rect (status_bg_color, 0, screen.height - h,
+                        screen.width, screen.height - 1);
+
+  int texty = screen.height - vpad - descent;
+  grub_video_draw_string ("Select an item with the arrow keys and "
+                          "press Enter to boot.",
+                          status_font, status_color, 30, texty);
+}
+
+static grub_err_t
+grub_cmd_protomenu (struct grub_arg_list *state __attribute__ ((unused)),
+                    int argc __attribute__ ((unused)),
+                    char **args __attribute__ ((unused)))
+{
+  if (grub_video_setup (1024, 768, GRUB_VIDEO_MODE_TYPE_RGB) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_get_viewport ((unsigned *) &screen.x,
+                           (unsigned *) &screen.y,
+                           (unsigned *) &screen.width,
+                           (unsigned *) &screen.height);
+
+  style_init ();
+  selected_item_index = 0;
+
+  int done = 0;
+  while (!done)
+    {
+      draw_background ();
+      draw_menu ();
+      draw_title ();
+      draw_status ();
+
+      int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
+      if (c == 'j')
+        {
+          selected_item_index++;
+          if (selected_item_index >= (int) (sizeof (items) / sizeof (*items)))
+            selected_item_index = 0;
+        }
+      else if (c == 'k')
+        {
+          selected_item_index--;
+          if (selected_item_index < 0)
+            selected_item_index = (sizeof (items) / sizeof (*items)) - 1;
+        }
+      else if (c == GRUB_TERM_ESC)
+        {
+          done = 1;
+        }
+    }
+
+  grub_video_restore ();
+  return 0;
+}
+
+GRUB_MOD_INIT (protomenu)
+{
+  (void) mod;                   /* To stop warning. */
+  grub_register_command ("protomenu",
+                         grub_cmd_protomenu, GRUB_COMMAND_FLAG_BOTH,
+                         "protomenu", "Show graphical menu prototype", 0);
+}
+
+GRUB_MOD_FINI (protomenu)
+{
+  grub_unregister_command ("protomenu");
+}

# Begin bundle
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
hIa+S+AA
