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:
parent
fd8c967c29
commit
3eb5ed4ec0
8 changed files with 480 additions and 338 deletions
26
ChangeLog
26
ChangeLog
|
@ -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>
|
||||
|
||||
Avoid calling biosdisk in drivemap
|
||||
|
|
|
@ -30,8 +30,7 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
|
|||
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;
|
||||
|
|
|
@ -34,6 +34,7 @@ struct grub_video_render_target;
|
|||
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_register (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));
|
||||
|
||||
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_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_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 */
|
||||
|
|
|
@ -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 @@ static struct idt_descriptor idt_desc =
|
|||
0
|
||||
};
|
||||
|
||||
static grub_uint16_t vid_mode;
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
struct linux_vesafb_res
|
||||
{
|
||||
grub_uint16_t width;
|
||||
|
@ -262,6 +263,7 @@ struct linux_vesafb_mode linux_vesafb_modes[] =
|
|||
{ 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 @@ grub_linux_boot (void)
|
|||
{
|
||||
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);
|
||||
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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|||
(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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|||
{
|
||||
/* 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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|||
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;
|
||||
}
|
||||
|
||||
if (grub_errno)
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* GRUB_MACHINE_PCBIOS */
|
||||
|
|
|
@ -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 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
|
|||
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");
|
||||
|
|
250
term/gfxterm.c
250
term/gfxterm.c
|
@ -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 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
|
|||
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,231 +252,24 @@ grub_gfxterm_init (void)
|
|||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
if (! modevar || *modevar == 0)
|
||||
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = grub_video_get_info (&mode_info);
|
||||
/* 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 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;
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Make sure screen is black. */
|
||||
color = grub_video_map_rgb (0, 0, 0);
|
||||
|
|
|
@ -90,9 +90,6 @@ EOF
|
|||
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
|
||||
|
|
368
video/video.c
368
video/video.c
|
@ -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 @@ grub_video_iterate (int (*hook) (grub_video_adapter_t adapter))
|
|||
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 @@ grub_video_get_active_render_target (struct grub_video_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. */
|
||||
GRUB_MOD_INIT(video_video)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue