2010-01-17 Vladimir Serbinenko <phcoder@gmail.com>

Use flag-based instead of hook-based video mode selection and "auto"
	keyword.

	* include/grub/video.h (grub_video_adapter): Changed 'setup' member.
	(grub_video_set_mode): Changed prototype. All users updated.
	(grub_video_check_mode_flag): New inline function.
	* video/video.c (parse_modespec): New function.
	(grub_video_set_mode): Parse flags and keywords.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-17 17:52:01 +01:00
commit b0b139075e
14 changed files with 187 additions and 189 deletions

View file

@ -1,3 +1,14 @@
2010-01-17 Vladimir Serbinenko <phcoder@gmail.com>
Use flag-based instead of hook-based video mode selection and "auto"
keyword.
* include/grub/video.h (grub_video_adapter): Changed 'setup' member.
(grub_video_set_mode): Changed prototype. All users updated.
(grub_video_check_mode_flag): New inline function.
* video/video.c (parse_modespec): New function.
(grub_video_set_mode): Parse flags and keywords.
2010-01-17 Carles Pina i Estany <carles@pina.cat> 2010-01-17 Carles Pina i Estany <carles@pina.cat>
* util/misc.c (grub_util_info): Fix the order of the parameters in a * util/misc.c (grub_util_info): Fix the order of the parameters in a

View file

@ -31,9 +31,7 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)), int argc __attribute__ ((unused)),
char **args __attribute__ ((unused))) char **args __attribute__ ((unused)))
{ {
if (grub_video_set_mode ("1024x768;800x600;640x480", 0) != GRUB_ERR_NONE) grub_err_t err;
return grub_errno;
grub_video_color_t color; grub_video_color_t color;
unsigned int x; unsigned int x;
unsigned int y; unsigned int y;
@ -50,6 +48,10 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
const char *str; const char *str;
int texty; int texty;
err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
if (err)
return err;
grub_video_get_viewport (&x, &y, &width, &height); grub_video_get_viewport (&x, &y, &width, &height);
grub_video_create_render_target (&text_layer, width, height, grub_video_create_render_target (&text_layer, width, height,
@ -153,12 +155,13 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
for (i = 0; i < 255; i++) for (i = 0; i < 5; i++)
{ {
color = grub_video_map_rgb (i, 33, 77); color = grub_video_map_rgb (i, 33, 77);
grub_video_fill_rect (color, 0, 0, width, height); grub_video_fill_rect (color, 0, 0, width, height);
grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0, grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
0, 0, width, height); 0, 0, width, height);
grub_video_swap_buffers ();
} }
grub_getkey (); grub_getkey ();

View file

@ -180,7 +180,7 @@ struct grub_video_adapter
grub_err_t (*fini) (void); grub_err_t (*fini) (void);
grub_err_t (*setup) (unsigned int width, unsigned int height, grub_err_t (*setup) (unsigned int width, unsigned int height,
unsigned int mode_type); unsigned int mode_type, unsigned int mode_mask);
grub_err_t (*get_info) (struct grub_video_mode_info *mode_info); grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
@ -316,8 +316,15 @@ grub_err_t grub_video_set_active_render_target (struct grub_video_render_target
grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
grub_err_t grub_video_set_mode (const char *modestring, grub_err_t grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p, unsigned int modemask,
struct grub_video_mode_info *mode_info)); unsigned int modevalue);
static inline int
grub_video_check_mode_flag (unsigned int flags, unsigned int mask,
unsigned int flag, int def)
{
return (flag & mask) ? !! (flags & flag) : def;
}
grub_video_driver_id_t grub_video_driver_id_t
grub_video_get_driver_id (void); grub_video_get_driver_id (void);

View file

@ -509,7 +509,7 @@ grub_freebsd_boot (void)
bi.bi_kernend = kern_end; bi.bi_kernend = kern_end;
grub_video_set_mode ("text", NULL); grub_video_set_mode ("text", 0, 0);
if (is_64bit) if (is_64bit)
{ {
@ -619,7 +619,7 @@ grub_openbsd_boot (void)
pa->ba_type = OPENBSD_BOOTARG_END; pa->ba_type = OPENBSD_BOOTARG_END;
pa++; pa++;
grub_video_set_mode ("text", NULL); grub_video_set_mode ("text", 0, 0);
grub_unix_real_boot (entry, bootflags, openbsd_root, OPENBSD_BOOTARG_APIVER, grub_unix_real_boot (entry, bootflags, openbsd_root, OPENBSD_BOOTARG_APIVER,
0, (grub_uint32_t) (grub_mmap_get_upper () >> 10), 0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
@ -717,7 +717,7 @@ grub_netbsd_boot (void)
bootinfo->bi_data[0] = mmap; bootinfo->bi_data[0] = mmap;
} }
grub_video_set_mode ("text", NULL); grub_video_set_mode ("text", 0, 0);
grub_unix_real_boot (entry, bootflags, 0, bootinfo, grub_unix_real_boot (entry, bootflags, 0, bootinfo,
0, (grub_uint32_t) (grub_mmap_get_upper () >> 10), 0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),

View file

@ -524,11 +524,11 @@ grub_linux_boot (void)
if (! tmp) if (! tmp)
return grub_errno; return grub_errno;
grub_sprintf (tmp, "%s;text", modevar); grub_sprintf (tmp, "%s;text", modevar);
err = grub_video_set_mode (tmp, 0); err = grub_video_set_mode (tmp, 0, 0);
grub_free (tmp); grub_free (tmp);
} }
else else
err = grub_video_set_mode ("text", 0); err = grub_video_set_mode ("text", 0, 0);
if (err) if (err)
{ {

View file

@ -134,7 +134,7 @@ set_video_mode (void)
{ {
modevar = grub_env_get ("gfxpayload"); modevar = grub_env_get ("gfxpayload");
if (! modevar || *modevar == 0) if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0); err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
else else
{ {
char *tmp; char *tmp;
@ -143,12 +143,12 @@ set_video_mode (void)
if (! tmp) if (! tmp)
return grub_errno; return grub_errno;
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, 0); err = grub_video_set_mode (tmp, 0, 0);
grub_free (tmp); grub_free (tmp);
} }
} }
else else
err = grub_video_set_mode ("text", 0); err = grub_video_set_mode ("text", 0, 0);
return err; return err;
} }

View file

@ -43,7 +43,7 @@ static void *boot_part_addr;
static grub_err_t static grub_err_t
grub_chainloader_boot (void) grub_chainloader_boot (void)
{ {
grub_video_set_mode ("text", NULL); grub_video_set_mode ("text", 0, 0);
grub_chainloader_real_boot (boot_drive, boot_part_addr); grub_chainloader_real_boot (boot_drive, boot_part_addr);
/* Never reach here. */ /* Never reach here. */

View file

@ -53,7 +53,7 @@ grub_linux_unload (void)
static grub_err_t static grub_err_t
grub_linux16_boot (void) grub_linux16_boot (void)
{ {
grub_video_set_mode ("text", NULL); grub_video_set_mode ("text", 0, 0);
grub_linux16_real_boot (); grub_linux16_real_boot ();
/* Not reached. */ /* Not reached. */

View file

@ -26,16 +26,7 @@
#define min(a,b) (((a) < (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b))
#define DEFAULT_VIDEO_MODE "1024x768x32,800x600x32,640x480x32" #define DEFAULT_VIDEO_MODE "auto"
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. */ /* Setup video for xnu. */
grub_err_t grub_err_t
@ -48,8 +39,12 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
grub_err_t err; grub_err_t err;
modevar = grub_env_get ("gfxpayload"); modevar = grub_env_get ("gfxpayload");
/* Consider only graphical 32-bit deep modes. */
if (! modevar || *modevar == 0) if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook); err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
else else
{ {
tmp = grub_malloc (grub_strlen (modevar) tmp = grub_malloc (grub_strlen (modevar)
@ -58,7 +53,10 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate temporary storag"); "couldn't allocate temporary storag");
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, video_hook); err = grub_video_set_mode (tmp,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
grub_free (tmp); grub_free (tmp);
} }

View file

@ -27,7 +27,7 @@
#include <grub/bitmap.h> #include <grub/bitmap.h>
#include <grub/command.h> #include <grub/command.h>
#define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480" #define DEFAULT_VIDEO_MODE "auto"
#define DEFAULT_BORDER_WIDTH 10 #define DEFAULT_BORDER_WIDTH 10
#define DEFAULT_STANDARD_COLOR 0x07 #define DEFAULT_STANDARD_COLOR 0x07
@ -244,12 +244,6 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
return grub_errno; 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 static grub_err_t
grub_gfxterm_init (void) grub_gfxterm_init (void)
{ {
@ -269,13 +263,15 @@ grub_gfxterm_init (void)
/* Parse gfxmode environment variable if set. */ /* Parse gfxmode environment variable if set. */
modevar = grub_env_get ("gfxmode"); modevar = grub_env_get ("gfxmode");
if (! modevar || *modevar == 0) if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook); err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
else else
{ {
tmp = grub_malloc (grub_strlen (modevar) tmp = grub_malloc (grub_strlen (modevar)
+ sizeof (DEFAULT_VIDEO_MODE) + 1); + sizeof (DEFAULT_VIDEO_MODE) + 1);
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, video_hook); err = grub_video_set_mode (tmp,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
grub_free (tmp); grub_free (tmp);
} }

View file

@ -185,7 +185,7 @@ grub_video_gop_fill_mode_info (struct grub_efi_gop_mode_info *in,
static grub_err_t static grub_err_t
grub_video_gop_setup (unsigned int width, unsigned int height, grub_video_gop_setup (unsigned int width, unsigned int height,
unsigned int mode_type) unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
{ {
unsigned int depth; unsigned int depth;
struct grub_efi_gop_mode_info *info = NULL; struct grub_efi_gop_mode_info *info = NULL;

View file

@ -198,7 +198,7 @@ grub_video_uga_fini (void)
static grub_err_t static grub_err_t
grub_video_uga_setup (unsigned int width, unsigned int height, grub_video_uga_setup (unsigned int width, unsigned int height,
unsigned int mode_type) unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
{ {
unsigned int depth; unsigned int depth;
int found = 0; int found = 0;

View file

@ -369,7 +369,7 @@ grub_video_vbe_fini (void)
static grub_err_t static grub_err_t
grub_video_vbe_setup (unsigned int width, unsigned int height, grub_video_vbe_setup (unsigned int width, unsigned int height,
unsigned int mode_type) unsigned int mode_type, unsigned int mode_mask)
{ {
grub_uint16_t *p; grub_uint16_t *p;
struct grub_vbe_mode_info_block vbe_mode_info; struct grub_vbe_mode_info_block vbe_mode_info;
@ -415,32 +415,40 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
/* Not compatible memory model. */ /* Not compatible memory model. */
continue; continue;
if ((vbe_mode_info.x_resolution != width) if (((vbe_mode_info.x_resolution != width)
|| (vbe_mode_info.y_resolution != height)) || (vbe_mode_info.y_resolution != height)) && width != 0 && height != 0)
/* Non matching resolution. */ /* Non matching resolution. */
continue; continue;
/* Check if user requested RGB or index color mode. */ /* Check if user requested RGB or index color mode. */
if ((mode_type & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0) if ((mode_mask & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0)
{ {
if (((mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) unsigned my_mode_type = 0;
&& (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL))
/* Requested only index color modes. */
continue;
if (((mode_type & GRUB_VIDEO_MODE_TYPE_RGB) != 0) if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
&& (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)) my_mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
/* Requested only RGB modes. */
continue; if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)
my_mode_type |= GRUB_VIDEO_MODE_TYPE_RGB;
if ((my_mode_type & mode_mask
& (GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_INDEX_COLOR))
!= (mode_type & mode_mask
& (GRUB_VIDEO_MODE_TYPE_RGB
| GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)))
continue;
} }
/* If there is a request for specific depth, ignore others. */ /* If there is a request for specific depth, ignore others. */
if ((depth != 0) && (vbe_mode_info.bits_per_pixel != depth)) if ((depth != 0) && (vbe_mode_info.bits_per_pixel != depth))
continue; continue;
/* Select mode with most number of bits per pixel. */ /* Select mode with most of "volume" (size of framebuffer in bits). */
if (best_vbe_mode != 0) if (best_vbe_mode != 0)
if (vbe_mode_info.bits_per_pixel < best_vbe_mode_info.bits_per_pixel) if ((grub_uint64_t) vbe_mode_info.bits_per_pixel
* vbe_mode_info.x_resolution * vbe_mode_info.y_resolution
< (grub_uint64_t) best_vbe_mode_info.bits_per_pixel
* best_vbe_mode_info.x_resolution * best_vbe_mode_info.y_resolution)
continue; continue;
/* Save so far best mode information for later use. */ /* Save so far best mode information for later use. */

View file

@ -407,21 +407,81 @@ grub_video_get_active_render_target (struct grub_video_render_target **target)
return grub_video_adapter_active->get_active_render_target (target); return grub_video_adapter_active->get_active_render_target (target);
} }
/* Parse <width>x<height>[x<depth>]*/
static grub_err_t
parse_modespec (const char *current_mode, int *width, int *height, int *depth)
{
const char *value;
const char *param = current_mode;
*width = *height = *depth = -1;
if (grub_strcmp (param, "auto") == 0)
{
*width = *height = 0;
return GRUB_ERR_NONE;
}
/* Find width value. */
value = param;
param = grub_strchr(param, 'x');
if (param == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
param++;
*width = grub_strtoul (value, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
/* 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)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
}
else
{
/* We have optional color depth value. */
param++;
*height = grub_strtoul (value, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
/* Convert color depth value. */
value = param;
*depth = grub_strtoul (value, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
}
return GRUB_ERR_NONE;
}
grub_err_t grub_err_t
grub_video_set_mode (const char *modestring, grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p, unsigned int modemask,
struct grub_video_mode_info *mode_info)) unsigned int modevalue)
{ {
char *tmp; char *tmp;
char *next_mode; char *next_mode;
char *current_mode; char *current_mode;
char *param;
char *value;
char *modevar; char *modevar;
int width = -1;
int height = -1; modevalue &= modemask;
int depth = -1;
int flags = 0;
/* Take copy of env.var. as we don't want to modify that. */ /* Take copy of env.var. as we don't want to modify that. */
modevar = grub_strdup (modestring); modevar = grub_strdup (modestring);
@ -437,26 +497,26 @@ grub_video_set_mode (const char *modestring,
|| grub_memcmp (next_mode, "keep,", sizeof ("keep,") - 1) == 0 || grub_memcmp (next_mode, "keep,", sizeof ("keep,") - 1) == 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; int suitable = 1;
grub_err_t err; grub_err_t err;
grub_memset (&mode_info, 0, sizeof (mode_info));
if (grub_video_adapter_active) if (grub_video_adapter_active)
{ {
struct grub_video_mode_info mode_info;
grub_memset (&mode_info, 0, sizeof (mode_info));
err = grub_video_get_info (&mode_info); err = grub_video_get_info (&mode_info);
if (err) if (err)
{ {
suitable = 0; suitable = 0;
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
} }
if ((mode_info.mode_type & modemask) != modevalue)
suitable = 0;
} }
else else if (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) != 0)
mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_PURE_TEXT; && ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) == 0))
suitable = 0;
if (suitable && hook)
suitable = hook (grub_video_adapter_active, &mode_info);
if (suitable) if (suitable)
{ {
grub_free (modevar); grub_free (modevar);
@ -490,15 +550,16 @@ grub_video_set_mode (const char *modestring,
/* Loop until all modes has been tested out. */ /* Loop until all modes has been tested out. */
while (next_mode != NULL) while (next_mode != NULL)
{ {
int width = -1;
int height = -1;
int depth = -1;
grub_err_t err;
unsigned int flags = modevalue;
unsigned int flagmask = modemask;
/* Use last next_mode as current mode. */ /* Use last next_mode as current mode. */
tmp = next_mode; tmp = next_mode;
/* Reset video mode settings. */
width = -1;
height = -1;
depth = -1;
flags = 0;
/* Save position of next mode and separate modes. */ /* Save position of next mode and separate modes. */
for (; *next_mode; next_mode++) for (; *next_mode; next_mode++)
if (*next_mode == ',' || *next_mode == ';') if (*next_mode == ',' || *next_mode == ';')
@ -517,19 +578,16 @@ grub_video_set_mode (const char *modestring,
/* Initialize token holders. */ /* Initialize token holders. */
current_mode = tmp; current_mode = tmp;
param = tmp;
value = NULL;
/* XXX: we assume that we're in pure text mode if /* XXX: we assume that we're in pure text mode if
no video mode is initialized. Is it always true? */ no video mode is initialized. Is it always true? */
if (grub_strcmp (param, "text") == 0) if (grub_strcmp (current_mode, "text") == 0)
{ {
struct grub_video_mode_info mode_info; struct grub_video_mode_info mode_info;
grub_memset (&mode_info, 0, sizeof (mode_info)); grub_memset (&mode_info, 0, sizeof (mode_info));
mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_PURE_TEXT; if (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) == 0)
|| ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) != 0))
if (! hook || hook (0, &mode_info))
{ {
/* Valid mode found from adapter, and it has been activated. /* Valid mode found from adapter, and it has been activated.
Specify it as active adapter. */ Specify it as active adapter. */
@ -542,121 +600,31 @@ grub_video_set_mode (const char *modestring,
} }
} }
/* Parse <width>x<height>[x<depth>]*/ err = parse_modespec (current_mode, &width, &height, &depth);
if (err)
/* 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",
current_mode);
/* Free memory before returning. */ /* Free memory before returning. */
grub_free (modevar); grub_free (modevar);
return rc; return err;
}
*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",
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",
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",
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",
current_mode);
/* Free memory before returning. */
grub_free (modevar);
return rc;
}
} }
/* Try out video mode. */ /* Try out video mode. */
/* If we have 8 or less bits, then assume that it is indexed color mode. */ /* If user requested specific depth check if this depth is supported. */
if ((depth <= 8) && (depth != -1)) if (depth != -1 && (flagmask & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; &&
(((flags & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
!= ((depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
& GRUB_VIDEO_MODE_TYPE_DEPTH_MASK))))
continue;
/* 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) if (depth != -1)
flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) {
& GRUB_VIDEO_MODE_TYPE_DEPTH_MASK; flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
& GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
flagmask |= GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
}
/* Try to initialize requested mode. Ignore any errors. */ /* Try to initialize requested mode. Ignore any errors. */
grub_video_adapter_t p; grub_video_adapter_t p;
@ -664,7 +632,6 @@ grub_video_set_mode (const char *modestring,
/* Loop thru all possible video adapter trying to find requested mode. */ /* Loop thru all possible video adapter trying to find requested mode. */
for (p = grub_video_adapter_list; p; p = p->next) for (p = grub_video_adapter_list; p; p = p->next)
{ {
grub_err_t err;
struct grub_video_mode_info mode_info; struct grub_video_mode_info mode_info;
grub_memset (&mode_info, 0, sizeof (mode_info)); grub_memset (&mode_info, 0, sizeof (mode_info));
@ -678,7 +645,7 @@ grub_video_set_mode (const char *modestring,
} }
/* Try to initialize video mode. */ /* Try to initialize video mode. */
err = p->setup (width, height, flags); err = p->setup (width, height, flags, flagmask);
if (err != GRUB_ERR_NONE) if (err != GRUB_ERR_NONE)
{ {
p->fini (); p->fini ();
@ -694,7 +661,15 @@ grub_video_set_mode (const char *modestring,
continue; continue;
} }
if (hook && ! hook (p, &mode_info)) flags = mode_info.mode_type & ~GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
flags |= (mode_info.bpp << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
& GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
/* Check that mode is suitable for upper layer. */
if ((flags & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
? (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) != 0)
&& ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) == 0))
: ((flags & modemask) != modevalue))
{ {
p->fini (); p->fini ();
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;