commit-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[2247] 2009-06-04 Vladimir Serbinenko <address@hidden>


From: Vladimir Serbinenko
Subject: [2247] 2009-06-04 Vladimir Serbinenko <address@hidden>
Date: Thu, 04 Jun 2009 18:22:45 +0000

Revision: 2247
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2247
Author:   phcoder
Date:     2009-06-04 18:22:45 +0000 (Thu, 04 Jun 2009)
Log Message:
-----------
2009-06-04  Vladimir Serbinenko  <address@hidden>

        gfxpayload support

        * commands/videotest.c (grub_cmd_videotest): use grub_video_set_mode
        * include/grub/video.h (GRUB_VIDEO_MODE_TYPE_PURE_TEXT): new definition
        (grub_video_setup): remove
        (grub_video_set_mode): new prototype
        * loader/i386/linux.c (DEFAULT_VIDEO_MODE): new definition
        (vid_mode): remove
        (linux_vesafb_res): compile only on PCBIOS
        (grub_linux_boot): support gfxpayload
        * loader/i386/pc/xnu.c (video_hook): new function
        (grub_xnu_set_video): support gfxpayload
        * term/gfxterm.c (DEFAULT_VIDEO_WIDTH): removed
        (DEFAULT_VIDEO_HEIGHT): likewise
        (DEFAULT_VIDEO_FLAGS): likewise
        (DEFAULT_VIDEO_MODE): new definition
        (video_hook): new function
        (grub_gfxterm_init): use grub_video_set_mode
        * util/grub.d/30_os-prober.in: remove explicit modesetting before 
        loading xnu
        * video/video.c (grub_video_setup): removed
        (grub_video_set_mode): new function based on grub_gfxterm_init and 
        grub_video_setup

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/commands/videotest.c
    trunk/grub2/include/grub/video.h
    trunk/grub2/loader/i386/linux.c
    trunk/grub2/loader/i386/pc/xnu.c
    trunk/grub2/term/gfxterm.c
    trunk/grub2/util/grub.d/30_os-prober.in
    trunk/grub2/video/video.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog       2009-06-04 17:58:25 UTC (rev 2246)
+++ trunk/grub2/ChangeLog       2009-06-04 18:22:45 UTC (rev 2247)
@@ -1,5 +1,31 @@
 2009-06-04  Vladimir Serbinenko  <address@hidden>
 
+       gfxpayload support
+
+       * commands/videotest.c (grub_cmd_videotest): use grub_video_set_mode
+       * include/grub/video.h (GRUB_VIDEO_MODE_TYPE_PURE_TEXT): new definition
+       (grub_video_setup): remove
+       (grub_video_set_mode): new prototype
+       * loader/i386/linux.c (DEFAULT_VIDEO_MODE): new definition
+       (vid_mode): remove
+       (linux_vesafb_res): compile only on PCBIOS
+       (grub_linux_boot): support gfxpayload
+       * loader/i386/pc/xnu.c (video_hook): new function
+       (grub_xnu_set_video): support gfxpayload
+       * term/gfxterm.c (DEFAULT_VIDEO_WIDTH): removed
+       (DEFAULT_VIDEO_HEIGHT): likewise
+       (DEFAULT_VIDEO_FLAGS): likewise
+       (DEFAULT_VIDEO_MODE): new definition
+       (video_hook): new function
+       (grub_gfxterm_init): use grub_video_set_mode
+       * util/grub.d/30_os-prober.in: remove explicit modesetting before 
+       loading xnu
+       * video/video.c (grub_video_setup): removed
+       (grub_video_set_mode): new function based on grub_gfxterm_init and 
+       grub_video_setup
+
+2009-06-04  Vladimir Serbinenko  <address@hidden>
+
        Avoid calling biosdisk in drivemap
 
        * commands/i386/pc/drivemap.c (parse_biosdisk): remove

Modified: trunk/grub2/commands/videotest.c
===================================================================
--- trunk/grub2/commands/videotest.c    2009-06-04 17:58:25 UTC (rev 2246)
+++ trunk/grub2/commands/videotest.c    2009-06-04 18:22:45 UTC (rev 2247)
@@ -30,8 +30,7 @@
                     int argc __attribute__ ((unused)),
                     char **args __attribute__ ((unused)))
 {
-  if (grub_video_setup (1024, 768,
-                        GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != GRUB_ERR_NONE)
+  if (grub_video_set_mode ("1024x768;800x600;640x480", 0) != GRUB_ERR_NONE)
     return grub_errno;
 
   grub_video_color_t color;

Modified: trunk/grub2/include/grub/video.h
===================================================================
--- trunk/grub2/include/grub/video.h    2009-06-04 17:58:25 UTC (rev 2246)
+++ trunk/grub2/include/grub/video.h    2009-06-04 18:22:45 UTC (rev 2247)
@@ -34,6 +34,7 @@
 struct grub_video_bitmap;
 
 /* Defines used to describe video mode or rendering target.  */
+#define GRUB_VIDEO_MODE_TYPE_PURE_TEXT         0x00000040
 #define GRUB_VIDEO_MODE_TYPE_ALPHA             0x00000020
 #define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED   0x00000010
 #define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP       0x00000004
@@ -236,9 +237,6 @@
 void grub_video_unregister (grub_video_adapter_t adapter);
 void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter));
 
-grub_err_t grub_video_setup (unsigned int width, unsigned int height,
-                             unsigned int mode_type);
-
 grub_err_t grub_video_restore (void);
 
 grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info);
@@ -299,4 +297,8 @@
 
 grub_err_t grub_video_get_active_render_target (struct 
grub_video_render_target **target);
 
+grub_err_t grub_video_set_mode (char *modestring,
+                               int NESTED_FUNC_ATTR (*hook) 
(grub_video_adapter_t p,
+                                                             struct 
grub_video_mode_info *mode_info));
+
 #endif /* ! GRUB_VIDEO_HEADER */

Modified: trunk/grub2/loader/i386/linux.c
===================================================================
--- trunk/grub2/loader/i386/linux.c     2009-06-04 17:58:25 UTC (rev 2246)
+++ trunk/grub2/loader/i386/linux.c     2009-06-04 18:22:45 UTC (rev 2247)
@@ -43,8 +43,10 @@
    into Linux, and therefore can benefit from seamless mode transition between
    GRUB and Linux (saving boot time and visual glitches).  Official GRUB, OTOH,
    needs to be conservative.  */
-#ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
-#define GRUB_ASSUME_LINUX_HAS_FB_SUPPORT 0
+#ifdef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
+#define DEFAULT_VIDEO_MODE "keep,1024x768,800x600,640x480"
+#else
+#define DEFAULT_VIDEO_MODE "text"
 #endif
 
 static grub_dl_t my_mod;
@@ -94,8 +96,7 @@
     0
   };
 
-static grub_uint16_t vid_mode;
-
+#ifdef GRUB_MACHINE_PCBIOS
 struct linux_vesafb_res
 {
   grub_uint16_t width;
@@ -262,6 +263,7 @@
     { VGA_800_500, 24 },       /* 0x372 */
     { VGA_800_500, 32 },       /* 0x373 */
   };
+#endif
 
 static inline grub_size_t
 page_align (grub_size_t size)
@@ -442,49 +444,37 @@
 {
   struct linux_kernel_params *params;
   int e820_num;
-  
+  grub_err_t err;
+  char *modevar, *tmp;
+
   params = real_mode_mem;
 
-  if (vid_mode == GRUB_LINUX_VID_MODE_NORMAL || vid_mode == 
GRUB_LINUX_VID_MODE_EXTENDED)
-    grub_video_restore ();
-  else if (vid_mode)
+  modevar = grub_env_get ("gfxpayload");
+
+  /* Now all graphical modes are acceptable. 
+     May change in future if we have modes without framebuffer.  */
+  if (modevar && *modevar != 0)
     {
-      struct linux_vesafb_mode *linux_mode;
-      int depth, flags;
-      
-      flags = 0;
-      linux_mode = &linux_vesafb_modes[vid_mode - 
GRUB_LINUX_VID_MODE_VESA_START];
-      depth = linux_mode->depth;
-      
-      /* If we have 8 or less bits, then assume that it is indexed color mode. 
 */
-      if ((depth <= 8) && (depth != -1))
-       flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
-      
-      /* We have more than 8 bits, then assume that it is RGB color mode.  */
-      if (depth > 8)
-       flags |= GRUB_VIDEO_MODE_TYPE_RGB;
-      
-      /* If user requested specific depth, forward that information to driver. 
 */
-      if (depth != -1)
-       flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
-         & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
-      
-      /* Try to initialize requested mode.  */
-      if (grub_video_setup (linux_vesafb_res[linux_mode->res_index].width,
-                           linux_vesafb_res[linux_mode->res_index].height,
-                           flags) != GRUB_ERR_NONE)
-       {
-         grub_printf ("Unable to initialize requested video mode 
(vga=0x%x)\n", vid_mode);
-         return grub_errno;
-       }
+      tmp = grub_malloc (grub_strlen (modevar) 
+                        + sizeof (DEFAULT_VIDEO_MODE) + 1);
+      if (! tmp)
+       return grub_errno;
+      grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+      err = grub_video_set_mode (tmp, 0);
+      grub_free (tmp);
     }
-#if ! GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
+#ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
   else
-    /* If user didn't request a video mode, and we can't assume Linux supports 
FB,
-       then we go back to text mode.  */
-    grub_video_restore ();
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0);
 #endif
 
+  if (err)
+    {
+      grub_print_error ();
+      grub_printf ("Booting however\n");
+      grub_errno = GRUB_ERR_NONE;
+    }
+
   if (! grub_linux_setup_video (params))
     params->have_vga = GRUB_VIDEO_TYPE_VLFB;
   else
@@ -708,7 +698,6 @@
               (unsigned) real_size, (unsigned) prot_size);
 
   /* Look for memory size and video mode specified on the command line.  */
-  vid_mode = 0;
   linux_mem_size = 0;
   for (i = 1; i < argc; i++)
 #ifdef GRUB_MACHINE_PCBIOS
@@ -716,6 +705,10 @@
       {
        /* Video mode selection support.  */
        char *val = argv[i] + 4;
+       unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+       struct linux_vesafb_mode *linux_mode;
+       grub_err_t err;
+       char *buf;
 
        if (grub_strcmp (val, "normal") == 0)
          vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
@@ -737,21 +730,57 @@
        switch (vid_mode)
          {
          case 0:
-           vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+         case GRUB_LINUX_VID_MODE_NORMAL:
+           grub_env_set ("gfxpayload", "text");
+           grub_printf ("%s is deprecated. "
+                        "Use set gfxpayload=text before "
+                        "linux command instead.\n", 
+                        argv[i]);      
            break;
+
          case 1:
-           vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
+         case GRUB_LINUX_VID_MODE_EXTENDED:
+           /* FIXME: support 80x50 text. */
+           grub_env_set ("gfxpayload", "text");
+           grub_printf ("%s is deprecated. "
+                        "Use set gfxpayload=text before "
+                        "linux command instead.\n", 
+                        argv[i]);      
            break;
          default:
            /* Ignore invalid values.  */
            if (vid_mode < GRUB_LINUX_VID_MODE_VESA_START ||
                vid_mode >= GRUB_LINUX_VID_MODE_VESA_START +
                ARRAY_SIZE (linux_vesafb_modes))
-             vid_mode = 0;
+             {
+               grub_env_set ("gfxpayload", "text");
+               grub_printf ("%s is deprecated. Mode %d isn't recognized. "
+                            "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] before "
+                            "linux command instead.\n", 
+                            argv[i], vid_mode);        
+               break;
+             }
+
+           buf = grub_malloc (20);
+           if (! buf)
+             goto fail;
+           
+           linux_mode 
+             = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START];
+           
+           grub_sprintf (buf, "%dx%dx%d", 
+                         linux_vesafb_res[linux_mode->res_index].width,
+                         linux_vesafb_res[linux_mode->res_index].height,
+                         linux_mode->depth);
+           grub_printf ("%s is deprecated. "
+                        "Use set gfxpayload=%s before "
+                        "linux command instead.\n", 
+                        argv[i], buf); 
+           err = grub_env_set ("gfxpayload", buf);
+           grub_free (buf);
+           if (err)
+             goto fail;
          }
-
-       if (grub_errno)
-         goto fail;
       }
     else
 #endif /* GRUB_MACHINE_PCBIOS */

Modified: trunk/grub2/loader/i386/pc/xnu.c
===================================================================
--- trunk/grub2/loader/i386/pc/xnu.c    2009-06-04 17:58:25 UTC (rev 2246)
+++ trunk/grub2/loader/i386/pc/xnu.c    2009-06-04 18:22:45 UTC (rev 2247)
@@ -19,6 +19,7 @@
 #include <grub/env.h>
 #include <grub/misc.h>
 #include <grub/xnu.h>
+#include <grub/mm.h>
 #include <grub/cpu/xnu.h>
 #include <grub/machine/vbe.h>
 #include <grub/machine/vga.h>
@@ -26,6 +27,17 @@
 #define min(a,b) (((a) < (b)) ? (a) : (b))
 #define max(a,b) (((a) > (b)) ? (a) : (b))
 
+#define DEFAULT_VIDEO_MODE "1024x768x32,800x600x32,640x480x32"
+
+static int NESTED_FUNC_ATTR video_hook (grub_video_adapter_t p __attribute__ 
((unused)),
+                                       struct grub_video_mode_info *info)
+{
+  if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
+    return 0;
+
+  return 1;
+}
+
 /* Setup video for xnu. */
 grub_err_t
 grub_xnu_set_video (struct grub_xnu_boot_params *params)
@@ -34,8 +46,27 @@
   struct grub_video_render_target *render_target;
   int ret;
   int x,y;
+  char *tmp, *modevar;
   grub_err_t err;
 
+  modevar = grub_env_get ("gfxpayload");
+  if (! modevar || *modevar == 0)
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
+  else
+    {
+      tmp = grub_malloc (grub_strlen (modevar) 
+                        + sizeof (DEFAULT_VIDEO_MODE) + 1);
+      if (! tmp)
+       return grub_error (GRUB_ERR_OUT_OF_MEMORY, 
+                          "couldn't allocate temporary storag");
+      grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+      err = grub_video_set_mode (tmp, video_hook);
+      grub_free (tmp);
+    }
+
+  if (err)
+    return err;
+
   ret = grub_video_get_info (&mode_info);
   if (ret)
     return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");

Modified: trunk/grub2/term/gfxterm.c
===================================================================
--- trunk/grub2/term/gfxterm.c  2009-06-04 17:58:25 UTC (rev 2246)
+++ trunk/grub2/term/gfxterm.c  2009-06-04 18:22:45 UTC (rev 2247)
@@ -27,10 +27,7 @@
 #include <grub/bitmap.h>
 #include <grub/command.h>
 
-#define DEFAULT_VIDEO_WIDTH    640
-#define DEFAULT_VIDEO_HEIGHT   480
-#define DEFAULT_VIDEO_FLAGS    0
-
+#define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480"
 #define DEFAULT_BORDER_WIDTH   10
 
 #define DEFAULT_STANDARD_COLOR  0x07
@@ -231,16 +228,22 @@
   return grub_errno;
 }
 
+static int NESTED_FUNC_ATTR video_hook (grub_video_adapter_t p __attribute__ 
((unused)),
+                                       struct grub_video_mode_info *info)
+{
+  return ! (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT);
+}
+
 static grub_err_t
 grub_gfxterm_init (void)
 {
   char *font_name;
   char *modevar;
-  int width = DEFAULT_VIDEO_WIDTH;
-  int height = DEFAULT_VIDEO_HEIGHT;
-  int depth = -1;
-  int flags = DEFAULT_VIDEO_FLAGS;
+  char *tmp;
   grub_video_color_t color;
+  int width;
+  int height;
+  grub_err_t err;
 
   /* Select the font to use. */
   font_name = grub_env_get ("gfxterm_font");
@@ -249,232 +252,25 @@
 
   /* Parse gfxmode environment variable if set.  */
   modevar = grub_env_get ("gfxmode");
-  if (modevar)
-    {
-      char *tmp;
-      char *next_mode;
-      char *current_mode;
-      char *param;
-      char *value;
-      int mode_found = 0;
-
-      /* Take copy of env.var. as we don't want to modify that.  */
-      tmp = grub_strdup (modevar);
-      modevar = tmp;
-
-      if (grub_errno != GRUB_ERR_NONE)
-        return grub_errno;
-        
-      /* Initialize next mode.  */
-      next_mode = modevar;
-      
-      /* Loop until all modes has been tested out.  */
-      while (next_mode != NULL)
-        {
-          /* Use last next_mode as current mode.  */
-          tmp = next_mode;
-          
-          /* Reset video mode settings.  */
-          width = DEFAULT_VIDEO_WIDTH;
-          height = DEFAULT_VIDEO_HEIGHT;
-          depth = -1;
-          flags = DEFAULT_VIDEO_FLAGS;
-        
-          /* Save position of next mode and separate modes.  */
-          next_mode = grub_strchr(next_mode, ';');
-          if (next_mode)
-            {
-              *next_mode = 0;
-              next_mode++;
-            }
-
-          /* Skip whitespace.  */
-          while (grub_isspace (*tmp))
-            tmp++;
-
-          /* Initialize token holders.  */
-          current_mode = tmp;
-          param = tmp;
-          value = NULL;
-
-          /* Parse <width>x<height>[x<depth>]*/
-
-          /* Find width value.  */
-          value = param;
-          param = grub_strchr(param, 'x');
-          if (param == NULL)
-            {
-              grub_err_t rc;
-              
-              /* First setup error message.  */
-             rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
-                               "Invalid mode: %s\n",
-                               current_mode);
-              
-              /* Free memory before returning.  */
-              grub_free (modevar);
-              
-              return rc;
-            }
-
-          *param = 0;
-          param++;
-
-          width = grub_strtoul (value, 0, 0);
-          if (grub_errno != GRUB_ERR_NONE)
-            {
-              grub_err_t rc;
-              
-              /* First setup error message.  */
-             rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
-                               "Invalid mode: %s\n",
-                               current_mode);
-              
-              /* Free memory before returning.  */
-              grub_free (modevar);
-              
-              return rc;
-            }
-
-          /* Find height value.  */
-          value = param;
-          param = grub_strchr(param, 'x');
-          if (param == NULL)
-            {
-              height = grub_strtoul (value, 0, 0);
-              if (grub_errno != GRUB_ERR_NONE)
-                {
-                  grub_err_t rc;
-
-                  /* First setup error message.  */
-                 rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                   "Invalid mode: %s\n",
-                                   current_mode);
-
-                  /* Free memory before returning.  */
-                  grub_free (modevar);
-
-                 return rc;
-               }
-            }
-         else
-            {
-             /* We have optional color depth value.  */
-             *param = 0;
-             param++;
-
-             height = grub_strtoul (value, 0, 0);
-             if (grub_errno != GRUB_ERR_NONE)
-               {
-                 grub_err_t rc;
-
-                 /* First setup error message.  */
-                 rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                  "Invalid mode: %s\n",
-                                  current_mode);
-
-                 /* Free memory before returning.  */
-                 grub_free (modevar);
-
-                 return rc;
-               }
-
-             /* Convert color depth value.  */
-             value = param;
-             depth = grub_strtoul (value, 0, 0);
-             if (grub_errno != GRUB_ERR_NONE)
-               {
-                 grub_err_t rc;
-
-                 /* First setup error message.  */
-                 rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                  "Invalid mode: %s\n",
-                                  current_mode);
-
-                 /* Free memory before returning.  */
-                 grub_free (modevar);
-
-                 return rc;
-               }
-            }
-
-         /* Try out video mode.  */
-
-         /* If we have 8 or less bits, then assume that it is indexed color 
mode.  */
-         if ((depth <= 8) && (depth != -1))
-           flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
-
-         /* We have more than 8 bits, then assume that it is RGB color mode.  
*/
-         if (depth > 8)
-           flags |= GRUB_VIDEO_MODE_TYPE_RGB;
-
-         /* If user requested specific depth, forward that information to 
driver.  */
-         if (depth != -1)
-           flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
-                    & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
-
-         /* Try to initialize requested mode.  Ignore any errors.  */
-         grub_error_push ();
-         if (grub_video_setup (width, height, flags) != GRUB_ERR_NONE)
-           {
-             grub_error_pop ();
-             continue;
-           }
-
-         /* Figure out what mode we ended up.  */
-         if (grub_video_get_info (&mode_info) != GRUB_ERR_NONE)
-           {
-             /* Couldn't get video mode info, restore old mode and continue to 
next one.  */
-             grub_error_pop ();
-
-             grub_video_restore ();
-             continue;
-           }
-          
-          /* Restore state of error stack.  */
-          grub_error_pop ();
-          
-          /* Mode found!  Exit loop.  */
-          mode_found = 1;
-          break;
-        }
-
-      /* Free memory.  */
-      grub_free (modevar);
-      
-      if (!mode_found)
-        return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                           "No suitable mode found.");
-    }
+  if (! modevar || *modevar == 0)
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
   else
     {
-      /* No gfxmode variable set, use defaults.  */
-      
-      /* If we have 8 or less bits, then assume that it is indexed color mode. 
 */
-      if ((depth <= 8) && (depth != -1))
-        flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+      tmp = grub_malloc (grub_strlen (modevar) 
+                        + sizeof (DEFAULT_VIDEO_MODE) + 1);
+      grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+      err = grub_video_set_mode (tmp, video_hook);
+      grub_free (tmp);
+    }
 
-      /* We have more than 8 bits, then assume that it is RGB color mode.  */
-      if (depth > 8)
-        flags |= GRUB_VIDEO_MODE_TYPE_RGB;
+  if (err)
+    return err;
 
-      /* If user requested specific depth, forward that information to driver. 
 */
-      if (depth != -1)
-        flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
-                 & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+  err = grub_video_get_info (&mode_info);
+  /* Figure out what mode we ended up.  */
+  if (err)
+    return err;
 
-      /* Initialize user requested mode.  */
-      if (grub_video_setup (width, height, flags) != GRUB_ERR_NONE)
-        return grub_errno;
-
-      /* Figure out what mode we ended up.  */
-      if (grub_video_get_info (&mode_info) != GRUB_ERR_NONE)
-        {
-          grub_video_restore ();
-          return grub_errno;
-        }
-    }
-
   /* Make sure screen is black.  */
   color = grub_video_map_rgb (0, 0, 0);
   grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);

Modified: trunk/grub2/util/grub.d/30_os-prober.in
===================================================================
--- trunk/grub2/util/grub.d/30_os-prober.in     2009-06-04 17:58:25 UTC (rev 
2246)
+++ trunk/grub2/util/grub.d/30_os-prober.in     2009-06-04 18:22:45 UTC (rev 
2247)
@@ -90,9 +90,6 @@
 menuentry "${LONGNAME} (on ${DEVICE})" {
        set root=${OSXROOT}
         insmod vbe
-        insmod gfxterm
-        gfxmode="1024x768x32;800x600x32"
-        terminal_output gfxterm
         do_resume=0
         if [ /var/vm/sleepimage -nt10 / ]; then
            if xnu_resume /var/vm/sleepimage; then

Modified: trunk/grub2/video/video.c
===================================================================
--- trunk/grub2/video/video.c   2009-06-04 17:58:25 UTC (rev 2246)
+++ trunk/grub2/video/video.c   2009-06-04 18:22:45 UTC (rev 2247)
@@ -19,6 +19,8 @@
 #include <grub/video.h>
 #include <grub/types.h>
 #include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
 
 /* The list of video adapters registered to system.  */
 static grub_video_adapter_t grub_video_adapter_list;
@@ -59,59 +61,6 @@
       break;
 }
 
-/* Setup specified video mode.  */
-grub_err_t
-grub_video_setup (unsigned int width, unsigned int height,
-                  unsigned int mode_type)
-{
-  grub_video_adapter_t p;
-
-  /* De-activate last set video adapter.  */
-  if (grub_video_adapter_active)
-    {
-      /* Finalize adapter.  */
-      grub_video_adapter_active->fini ();
-      if (grub_errno != GRUB_ERR_NONE)
-        return grub_errno;
-
-      /* Mark active adapter as not set.  */
-      grub_video_adapter_active = 0;
-    }
-
-  /* Loop thru all possible video adapter trying to find requested mode.  */
-  for (p = grub_video_adapter_list; p; p = p->next)
-    {
-      /* Try to initialize adapter, if it fails, skip to next adapter.  */
-      p->init ();
-      if (grub_errno != GRUB_ERR_NONE)
-        {
-          grub_errno = GRUB_ERR_NONE;
-          continue;
-        }
-
-      /* Try to initialize video mode.  */
-      p->setup (width, height, mode_type);
-      if (grub_errno == GRUB_ERR_NONE)
-        {
-          /* Valid mode found from adapter, and it has been activated.
-             Specify it as active adapter.  */
-          grub_video_adapter_active = p;
-          return GRUB_ERR_NONE;
-        }
-      else
-        grub_errno = GRUB_ERR_NONE;
-
-      /* No valid mode found in this adapter, finalize adapter.  */
-      p->fini ();
-      if (grub_errno != GRUB_ERR_NONE)
-        return grub_errno;
-    }
-
-  /* We couldn't find suitable adapter for specified mode.  */
-  return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                     "Can't locate valid adapter for mode");
-}
-
 /* Restore back to initial mode (where applicable).  */
 grub_err_t
 grub_video_restore (void)
@@ -430,6 +379,319 @@
   return grub_video_adapter_active->get_active_render_target (target);
 }
 
+grub_err_t
+grub_video_set_mode (char *modestring,
+                    int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
+                                                  struct grub_video_mode_info 
*mode_info))
+{
+  char *tmp;
+  char *next_mode;
+  char *current_mode;
+  char *param;
+  char *value;
+  char *modevar;
+  int width = -1;
+  int height = -1;
+  int depth = -1;
+  int flags = 0;
+
+  /* Take copy of env.var. as we don't want to modify that.  */
+  modevar = grub_strdup (modestring);
+
+  /* Initialize next mode.  */
+  next_mode = modevar;
+
+  if (! modevar)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, 
+                      "couldn't allocate space for local modevar copy");
+
+  if (grub_memcmp (next_mode, "keep", sizeof ("keep")) == 0
+      || grub_memcmp (next_mode, "keep,", sizeof ("keep,") - 1) == 0
+      || grub_memcmp (next_mode, "keep;", sizeof ("keep;") - 1) == 0)
+    {
+      struct grub_video_mode_info mode_info;
+      int suitable = 1;
+      grub_err_t err;
+      
+      grub_memset (&mode_info, 0, sizeof (mode_info));
+
+      if (grub_video_adapter_active)
+       {
+         err = grub_video_get_info (&mode_info);
+         if (err)
+           {
+             suitable = 0;
+             grub_errno = GRUB_ERR_NONE;
+           }
+       }
+      else
+       mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_PURE_TEXT;
+
+      if (suitable && hook)
+       suitable = hook (grub_video_adapter_active, &mode_info);
+      if (suitable)
+       {
+         grub_free (modevar);
+         return GRUB_ERR_NONE;
+       }
+      next_mode += sizeof ("keep") - 1;
+      if (! *next_mode)
+       {
+         grub_free (modevar);
+  
+         return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                            "No suitable mode found.");
+       }
+      
+      /* Skip separator. */
+      next_mode++;
+    }
+
+  /* De-activate last set video adapter.  */
+  if (grub_video_adapter_active)
+    {
+      /* Finalize adapter.  */
+      grub_video_adapter_active->fini ();
+      if (grub_errno != GRUB_ERR_NONE)
+       grub_errno = GRUB_ERR_NONE;
+      
+      /* Mark active adapter as not set.  */
+      grub_video_adapter_active = 0;
+    }
+    
+  /* Loop until all modes has been tested out.  */
+  while (next_mode != NULL)
+    {
+      /* Use last next_mode as current mode.  */
+      tmp = next_mode;
+      
+      /* Reset video mode settings.  */
+      width = -1;
+      height = -1;
+      depth = -1;
+      flags = 0;
+      
+      /* Save position of next mode and separate modes.  */
+      for (; *next_mode; next_mode++)
+       if (*next_mode == ',' || *next_mode == ';')
+         break;
+      if (*next_mode)
+       {
+         *next_mode = 0;
+         next_mode++;
+       }
+      else
+       next_mode = 0;
+      
+      /* Skip whitespace.  */
+      while (grub_isspace (*tmp))
+       tmp++;
+      
+      /* Initialize token holders.  */
+      current_mode = tmp;
+      param = tmp;
+      value = NULL;
+
+      /* XXX: we assume that we're in pure text mode if 
+        no video mode is initialized. Is it always true? */
+      if (grub_strcmp (param, "text") == 0)
+       {
+         struct grub_video_mode_info mode_info;
+         
+         grub_memset (&mode_info, 0, sizeof (mode_info));
+         mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_PURE_TEXT;
+
+         if (! hook || hook (0, &mode_info))
+           {
+             /* Valid mode found from adapter, and it has been activated.
+                Specify it as active adapter.  */
+             grub_video_adapter_active = NULL;
+
+             /* Free memory.  */
+             grub_free (modevar);
+
+             return GRUB_ERR_NONE;
+           }
+       }
+
+      /* Parse <width>x<height>[x<depth>]*/
+      
+      /* Find width value.  */
+      value = param;
+      param = grub_strchr(param, 'x');
+      if (param == NULL)
+       {
+         grub_err_t rc;
+          
+         /* First setup error message.  */
+         rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "Invalid mode: %s\n",
+                          current_mode);
+          
+         /* Free memory before returning.  */
+         grub_free (modevar);
+         
+         return rc;
+       }
+      
+      *param = 0;
+      param++;
+      
+      width = grub_strtoul (value, 0, 0);
+      if (grub_errno != GRUB_ERR_NONE)
+       {
+         grub_err_t rc;
+          
+         /* First setup error message.  */
+         rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "Invalid mode: %s\n",
+                          current_mode);
+         
+         /* Free memory before returning.  */
+         grub_free (modevar);
+          
+         return rc;
+       }
+      
+      /* Find height value.  */
+      value = param;
+      param = grub_strchr(param, 'x');
+      if (param == NULL)
+       {
+         height = grub_strtoul (value, 0, 0);
+         if (grub_errno != GRUB_ERR_NONE)
+           {
+             grub_err_t rc;
+             
+             /* First setup error message.  */
+             rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+                              "Invalid mode: %s\n",
+                              current_mode);
+             
+             /* Free memory before returning.  */
+             grub_free (modevar);
+             
+             return rc;
+           }
+       }
+      else
+       {
+         /* We have optional color depth value.  */
+         *param = 0;
+         param++;
+         
+         height = grub_strtoul (value, 0, 0);
+         if (grub_errno != GRUB_ERR_NONE)
+           {
+             grub_err_t rc;
+             
+             /* First setup error message.  */
+             rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+                              "Invalid mode: %s\n",
+                              current_mode);
+             
+             /* Free memory before returning.  */
+             grub_free (modevar);
+             
+             return rc;
+           }
+         
+         /* Convert color depth value.  */
+         value = param;
+         depth = grub_strtoul (value, 0, 0);
+         if (grub_errno != GRUB_ERR_NONE)
+           {
+             grub_err_t rc;
+             
+             /* First setup error message.  */
+             rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+                              "Invalid mode: %s\n",
+                              current_mode);
+             
+             /* Free memory before returning.  */
+             grub_free (modevar);
+
+             return rc;
+           }
+       }
+
+      /* Try out video mode.  */
+      
+      /* If we have 8 or less bits, then assume that it is indexed color mode. 
 */
+      if ((depth <= 8) && (depth != -1))
+       flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+
+      /* We have more than 8 bits, then assume that it is RGB color mode.  */
+      if (depth > 8)
+       flags |= GRUB_VIDEO_MODE_TYPE_RGB;
+      
+      /* If user requested specific depth, forward that information to driver. 
 */
+      if (depth != -1)
+       flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
+         & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+      
+      /* Try to initialize requested mode.  Ignore any errors.  */
+      grub_video_adapter_t p;
+
+      /* Loop thru all possible video adapter trying to find requested mode.  
*/
+      for (p = grub_video_adapter_list; p; p = p->next)
+       {
+         grub_err_t err;
+         struct grub_video_mode_info mode_info;
+         
+         grub_memset (&mode_info, 0, sizeof (mode_info));
+
+         /* Try to initialize adapter, if it fails, skip to next adapter.  */
+         err = p->init ();
+         if (err != GRUB_ERR_NONE)
+           {
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         /* Try to initialize video mode.  */
+         err = p->setup (width, height, flags);
+         if (err != GRUB_ERR_NONE)
+           {
+             p->fini ();
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         err = p->get_info (&mode_info);
+         if (err != GRUB_ERR_NONE)
+           {
+             p->fini ();
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         if (hook && ! hook (p, &mode_info))
+           {
+             p->fini ();
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+           
+         /* Valid mode found from adapter, and it has been activated.
+            Specify it as active adapter.  */
+         grub_video_adapter_active = p;
+         
+         /* Free memory.  */
+         grub_free (modevar);
+         
+         return GRUB_ERR_NONE;
+       }
+
+    }
+
+  /* Free memory.  */
+  grub_free (modevar);
+  
+  return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                    "No suitable mode found.");
+}
+
 /* Initialize Video API module.  */
 GRUB_MOD_INIT(video_video)
 {





reply via email to

[Prev in Thread] Current Thread [Next in Thread]