Index: ChangeLog
===================================================================
RCS file: /sources/grub/grub2/ChangeLog,v
retrieving revision 1.375
diff -u -r1.375 ChangeLog
--- ChangeLog 20 May 2007 09:10:05 -0000 1.375
+++ ChangeLog 30 May 2007 06:00:57 -0000
@@ -1,3 +1,8 @@
+2007-05-30 Vesa Jaaskelainen
+
+ * term/gfxterm.c (grub_gfxterm_init): Added support for specifying
+ list of video modes.
+
2007-05-20 Robert Millan
* util/update-grub_lib.in: New file.
Index: term/gfxterm.c
===================================================================
RCS file: /sources/grub/grub2/term/gfxterm.c,v
retrieving revision 1.3
diff -u -r1.3 gfxterm.c
--- term/gfxterm.c 31 Jul 2006 14:21:35 -0000 1.3
+++ term/gfxterm.c 30 May 2007 06:00:58 -0000
@@ -202,8 +202,11 @@
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);
@@ -211,110 +214,216 @@
if (grub_errno != GRUB_ERR_NONE)
return grub_errno;
-
- /* Skip whitespace. */
- while (grub_isspace (*tmp))
- tmp++;
-
- /* Initialize token holders. */
- param = tmp;
- value = NULL;
-
- /* Parse x[x]*/
-
- /* Find width value. */
- value = param;
- param = grub_strchr(param, 'x');
- if (param == NULL)
+
+ /* Initialize next mode. */
+ next_mode = modevar;
+
+ /* Loop until all modes has been tested out. */
+ while (next_mode != NULL)
{
- /* Free memory before returning. */
- grub_free (modevar);
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
- "Invalid argument: %s\n",
- param);
- }
+ /* 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++;
+ }
- *param = 0;
- param++;
+ /* Skip whitespace. */
+ while (grub_isspace (*tmp))
+ tmp++;
+
+ /* Initialize token holders. */
+ current_mode = tmp;
+ param = tmp;
+ value = NULL;
- width = grub_strtoul (value, 0, 0);
- if (grub_errno != GRUB_ERR_NONE)
- {
- /* Free memory before returning. */
- grub_free (modevar);
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
- "Invalid argument: %s\n",
- param);
- }
+ /* Parse x[x]*/
- /* 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)
+ /* 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 grub_error (GRUB_ERR_BAD_ARGUMENT,
- "Invalid argument: %s\n",
- param);
+
+ return rc;
}
- }
- else
- {
- /* We have optional color depth value. */
+
*param = 0;
param++;
- height = grub_strtoul (value, 0, 0);
+ 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 grub_error (GRUB_ERR_BAD_ARGUMENT,
- "Invalid argument: %s\n",
- param);
+
+ return rc;
}
- /* Convert color depth value. */
+ /* Find height value. */
value = param;
- depth = grub_strtoul (value, 0, 0);
- if (grub_errno != GRUB_ERR_NONE)
+ param = grub_strchr(param, 'x');
+ if (param == NULL)
{
- /* Free memory before returning. */
- grub_free (modevar);
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
- "Invalid argument: %s\n",
- 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;
+ }
+ }
+ 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 assuem 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.");
}
+ else
+ {
+ /* No gfxmode variable set, use defaults. */
+
+ /* If we have 8 or less bits, then assuem 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;
+
+ /* Initialize user requested mode. */
+ if (grub_video_setup (width, height, flags) != GRUB_ERR_NONE)
+ return grub_errno;
- /* If we have 8 or less bits, then assuem 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;
-
- /* 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)
- 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);