2009-06-04 Vladimir Serbinenko <phcoder@gmail.com>

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
This commit is contained in:
phcoder 2009-06-04 18:22:45 +00:00
parent fd8c967c29
commit 3eb5ed4ec0
8 changed files with 480 additions and 338 deletions

View file

@ -1,3 +1,29 @@
2009-06-04 Vladimir Serbinenko <phcoder@gmail.com>
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 <phcoder@gmail.com> 2009-06-04 Vladimir Serbinenko <phcoder@gmail.com>
Avoid calling biosdisk in drivemap Avoid calling biosdisk in drivemap

View file

@ -30,8 +30,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_setup (1024, 768, if (grub_video_set_mode ("1024x768;800x600;640x480", 0) != GRUB_ERR_NONE)
GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != GRUB_ERR_NONE)
return grub_errno; return grub_errno;
grub_video_color_t color; grub_video_color_t color;

View file

@ -34,6 +34,7 @@ struct grub_video_render_target;
struct grub_video_bitmap; struct grub_video_bitmap;
/* Defines used to describe video mode or rendering target. */ /* 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_ALPHA 0x00000020
#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010 #define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010
#define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP 0x00000004 #define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP 0x00000004
@ -236,9 +237,6 @@ void grub_video_register (grub_video_adapter_t adapter);
void grub_video_unregister (grub_video_adapter_t adapter); void grub_video_unregister (grub_video_adapter_t adapter);
void grub_video_iterate (int (*hook) (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_restore (void);
grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info); grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info);
@ -299,4 +297,8 @@ 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 (char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
struct grub_video_mode_info *mode_info));
#endif /* ! GRUB_VIDEO_HEADER */ #endif /* ! GRUB_VIDEO_HEADER */

View file

@ -43,8 +43,10 @@
into Linux, and therefore can benefit from seamless mode transition between into Linux, and therefore can benefit from seamless mode transition between
GRUB and Linux (saving boot time and visual glitches). Official GRUB, OTOH, GRUB and Linux (saving boot time and visual glitches). Official GRUB, OTOH,
needs to be conservative. */ needs to be conservative. */
#ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT #ifdef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
#define GRUB_ASSUME_LINUX_HAS_FB_SUPPORT 0 #define DEFAULT_VIDEO_MODE "keep,1024x768,800x600,640x480"
#else
#define DEFAULT_VIDEO_MODE "text"
#endif #endif
static grub_dl_t my_mod; static grub_dl_t my_mod;
@ -94,8 +96,7 @@ static struct idt_descriptor idt_desc =
0 0
}; };
static grub_uint16_t vid_mode; #ifdef GRUB_MACHINE_PCBIOS
struct linux_vesafb_res struct linux_vesafb_res
{ {
grub_uint16_t width; grub_uint16_t width;
@ -262,6 +263,7 @@ struct linux_vesafb_mode linux_vesafb_modes[] =
{ VGA_800_500, 24 }, /* 0x372 */ { VGA_800_500, 24 }, /* 0x372 */
{ VGA_800_500, 32 }, /* 0x373 */ { VGA_800_500, 32 }, /* 0x373 */
}; };
#endif
static inline grub_size_t static inline grub_size_t
page_align (grub_size_t size) page_align (grub_size_t size)
@ -442,49 +444,37 @@ grub_linux_boot (void)
{ {
struct linux_kernel_params *params; struct linux_kernel_params *params;
int e820_num; int e820_num;
grub_err_t err;
char *modevar, *tmp;
params = real_mode_mem; params = real_mode_mem;
if (vid_mode == GRUB_LINUX_VID_MODE_NORMAL || vid_mode == GRUB_LINUX_VID_MODE_EXTENDED) modevar = grub_env_get ("gfxpayload");
grub_video_restore ();
else if (vid_mode) /* 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; tmp = grub_malloc (grub_strlen (modevar)
int depth, flags; + sizeof (DEFAULT_VIDEO_MODE) + 1);
if (! tmp)
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; return grub_errno;
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, 0);
grub_free (tmp);
} }
} #ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
#if ! GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
else else
/* If user didn't request a video mode, and we can't assume Linux supports FB, err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0);
then we go back to text mode. */
grub_video_restore ();
#endif #endif
if (err)
{
grub_print_error ();
grub_printf ("Booting however\n");
grub_errno = GRUB_ERR_NONE;
}
if (! grub_linux_setup_video (params)) if (! grub_linux_setup_video (params))
params->have_vga = GRUB_VIDEO_TYPE_VLFB; params->have_vga = GRUB_VIDEO_TYPE_VLFB;
else else
@ -708,7 +698,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
(unsigned) real_size, (unsigned) prot_size); (unsigned) real_size, (unsigned) prot_size);
/* Look for memory size and video mode specified on the command line. */ /* Look for memory size and video mode specified on the command line. */
vid_mode = 0;
linux_mem_size = 0; linux_mem_size = 0;
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
#ifdef GRUB_MACHINE_PCBIOS #ifdef GRUB_MACHINE_PCBIOS
@ -716,6 +705,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
{ {
/* Video mode selection support. */ /* Video mode selection support. */
char *val = argv[i] + 4; 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) if (grub_strcmp (val, "normal") == 0)
vid_mode = GRUB_LINUX_VID_MODE_NORMAL; vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
@ -737,21 +730,57 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
switch (vid_mode) switch (vid_mode)
{ {
case 0: 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; break;
case 1: 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; break;
default: default:
/* Ignore invalid values. */ /* Ignore invalid values. */
if (vid_mode < GRUB_LINUX_VID_MODE_VESA_START || if (vid_mode < GRUB_LINUX_VID_MODE_VESA_START ||
vid_mode >= GRUB_LINUX_VID_MODE_VESA_START + vid_mode >= GRUB_LINUX_VID_MODE_VESA_START +
ARRAY_SIZE (linux_vesafb_modes)) 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;
} }
if (grub_errno) buf = grub_malloc (20);
if (! buf)
goto fail; 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;
}
} }
else else
#endif /* GRUB_MACHINE_PCBIOS */ #endif /* GRUB_MACHINE_PCBIOS */

View file

@ -19,6 +19,7 @@
#include <grub/env.h> #include <grub/env.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/xnu.h> #include <grub/xnu.h>
#include <grub/mm.h>
#include <grub/cpu/xnu.h> #include <grub/cpu/xnu.h>
#include <grub/machine/vbe.h> #include <grub/machine/vbe.h>
#include <grub/machine/vga.h> #include <grub/machine/vga.h>
@ -26,6 +27,17 @@
#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"
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
grub_xnu_set_video (struct grub_xnu_boot_params *params) grub_xnu_set_video (struct grub_xnu_boot_params *params)
@ -34,8 +46,27 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
struct grub_video_render_target *render_target; struct grub_video_render_target *render_target;
int ret; int ret;
int x,y; int x,y;
char *tmp, *modevar;
grub_err_t err; 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); ret = grub_video_get_info (&mode_info);
if (ret) if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters"); return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");

View file

@ -27,10 +27,7 @@
#include <grub/bitmap.h> #include <grub/bitmap.h>
#include <grub/command.h> #include <grub/command.h>
#define DEFAULT_VIDEO_WIDTH 640 #define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480"
#define DEFAULT_VIDEO_HEIGHT 480
#define DEFAULT_VIDEO_FLAGS 0
#define DEFAULT_BORDER_WIDTH 10 #define DEFAULT_BORDER_WIDTH 10
#define DEFAULT_STANDARD_COLOR 0x07 #define DEFAULT_STANDARD_COLOR 0x07
@ -231,16 +228,22 @@ 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)
{ {
char *font_name; char *font_name;
char *modevar; char *modevar;
int width = DEFAULT_VIDEO_WIDTH; char *tmp;
int height = DEFAULT_VIDEO_HEIGHT;
int depth = -1;
int flags = DEFAULT_VIDEO_FLAGS;
grub_video_color_t color; grub_video_color_t color;
int width;
int height;
grub_err_t err;
/* Select the font to use. */ /* Select the font to use. */
font_name = grub_env_get ("gfxterm_font"); font_name = grub_env_get ("gfxterm_font");
@ -249,231 +252,24 @@ 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) if (! modevar || *modevar == 0)
{ err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
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 else
{ {
/* We have optional color depth value. */ tmp = grub_malloc (grub_strlen (modevar)
*param = 0; + sizeof (DEFAULT_VIDEO_MODE) + 1);
param++; grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, video_hook);
height = grub_strtoul (value, 0, 0); grub_free (tmp);
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. */ if (err)
value = param; return err;
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;
}
err = grub_video_get_info (&mode_info);
/* Figure out what mode we ended up. */ /* Figure out what mode we ended up. */
if (grub_video_get_info (&mode_info) != GRUB_ERR_NONE) if (err)
{ return err;
/* 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 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;
/* 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. */ /* Make sure screen is black. */
color = grub_video_map_rgb (0, 0, 0); color = grub_video_map_rgb (0, 0, 0);

View file

@ -90,9 +90,6 @@ EOF
menuentry "${LONGNAME} (on ${DEVICE})" { menuentry "${LONGNAME} (on ${DEVICE})" {
set root=${OSXROOT} set root=${OSXROOT}
insmod vbe insmod vbe
insmod gfxterm
gfxmode="1024x768x32;800x600x32"
terminal_output gfxterm
do_resume=0 do_resume=0
if [ /var/vm/sleepimage -nt10 / ]; then if [ /var/vm/sleepimage -nt10 / ]; then
if xnu_resume /var/vm/sleepimage; then if xnu_resume /var/vm/sleepimage; then

View file

@ -19,6 +19,8 @@
#include <grub/video.h> #include <grub/video.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
/* The list of video adapters registered to system. */ /* The list of video adapters registered to system. */
static grub_video_adapter_t grub_video_adapter_list; static grub_video_adapter_t grub_video_adapter_list;
@ -59,59 +61,6 @@ grub_video_iterate (int (*hook) (grub_video_adapter_t adapter))
break; 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). */ /* Restore back to initial mode (where applicable). */
grub_err_t grub_err_t
grub_video_restore (void) grub_video_restore (void)
@ -430,6 +379,319 @@ 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);
} }
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. */ /* Initialize Video API module. */
GRUB_MOD_INIT(video_video) GRUB_MOD_INIT(video_video)
{ {