merge efigfx into newreloc
This commit is contained in:
commit
d1b3ffe8ce
16 changed files with 258 additions and 464 deletions
10
ChangeLog.videomask
Normal file
10
ChangeLog.videomask
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
2009-11-20 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.
|
|
@ -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 ();
|
||||||
|
|
|
@ -154,7 +154,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
pkglib_MODULES += xnu.mod
|
pkglib_MODULES += xnu.mod
|
||||||
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \
|
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
|
||||||
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
|
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
|
||||||
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
|
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
|
@ -180,7 +180,7 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
pkglib_MODULES += xnu.mod
|
pkglib_MODULES += xnu.mod
|
||||||
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \
|
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
|
||||||
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
|
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
|
||||||
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
|
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
|
@ -155,7 +155,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
pkglib_MODULES += xnu.mod
|
pkglib_MODULES += xnu.mod
|
||||||
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \
|
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
|
||||||
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
|
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
|
||||||
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
|
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
|
@ -114,7 +114,5 @@ extern grub_uint32_t grub_xnu_stack;
|
||||||
extern grub_uint32_t grub_xnu_arg1;
|
extern grub_uint32_t grub_xnu_arg1;
|
||||||
extern char grub_xnu_cmdline[1024];
|
extern char grub_xnu_cmdline[1024];
|
||||||
grub_err_t grub_xnu_boot (void);
|
grub_err_t grub_xnu_boot (void);
|
||||||
grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc);
|
grub_err_t grub_cpu_xnu_fill_devicetree (void);
|
||||||
grub_err_t
|
|
||||||
grub_cpu_xnu_fill_devicetree (void);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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,17 @@ 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);
|
||||||
grub_video_driver_id_t grub_video_get_driver_id (void);
|
|
||||||
|
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_get_driver_id (void);
|
||||||
|
|
||||||
#endif /* ! GRUB_VIDEO_HEADER */
|
#endif /* ! GRUB_VIDEO_HEADER */
|
||||||
|
|
|
@ -1,178 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GRUB is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <grub/env.h>
|
|
||||||
#include <grub/xnu.h>
|
|
||||||
#include <grub/cpu/xnu.h>
|
|
||||||
#include <grub/efi/api.h>
|
|
||||||
#include <grub/efi/efi.h>
|
|
||||||
#include <grub/efi/uga_draw.h>
|
|
||||||
#include <grub/pci.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
|
|
||||||
/* Setup video for xnu. Big parts are copied from linux.c. */
|
|
||||||
|
|
||||||
static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
|
|
||||||
|
|
||||||
#define RGB_MASK 0xffffff
|
|
||||||
#define RGB_MAGIC 0x121314
|
|
||||||
#define LINE_MIN 800
|
|
||||||
#define LINE_MAX 4096
|
|
||||||
#define FBTEST_STEP (0x10000 >> 2)
|
|
||||||
#define FBTEST_COUNT 8
|
|
||||||
|
|
||||||
static int
|
|
||||||
find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
|
|
||||||
{
|
|
||||||
grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
|
|
||||||
{
|
|
||||||
if ((*base & RGB_MASK) == RGB_MAGIC)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
|
|
||||||
for (j = LINE_MIN; j <= LINE_MAX; j++)
|
|
||||||
{
|
|
||||||
if ((base[j] & RGB_MASK) == RGB_MAGIC)
|
|
||||||
{
|
|
||||||
*fb_base = (grub_uint32_t) (grub_target_addr_t) base;
|
|
||||||
*line_len = j << 2;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
|
|
||||||
{
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
|
|
||||||
grub_pci_id_t pciid);
|
|
||||||
|
|
||||||
int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
|
|
||||||
grub_pci_id_t pciid)
|
|
||||||
{
|
|
||||||
grub_pci_address_t addr;
|
|
||||||
|
|
||||||
addr = grub_pci_make_address (dev, 2);
|
|
||||||
if (grub_pci_read (addr) >> 24 == 0x3)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
|
|
||||||
grub_pci_get_bus (dev), grub_pci_get_device (dev),
|
|
||||||
grub_pci_get_function (dev), pciid);
|
|
||||||
addr += 8;
|
|
||||||
for (i = 0; i < 6; i++, addr += 4)
|
|
||||||
{
|
|
||||||
grub_uint32_t old_bar1, old_bar2, type;
|
|
||||||
grub_uint64_t base64;
|
|
||||||
|
|
||||||
old_bar1 = grub_pci_read (addr);
|
|
||||||
if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
|
|
||||||
if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
|
|
||||||
{
|
|
||||||
if (i == 5)
|
|
||||||
break;
|
|
||||||
|
|
||||||
old_bar2 = grub_pci_read (addr + 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
old_bar2 = 0;
|
|
||||||
|
|
||||||
base64 = old_bar2;
|
|
||||||
base64 <<= 32;
|
|
||||||
base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
|
|
||||||
|
|
||||||
grub_printf ("%s(%d): 0x%llx\n",
|
|
||||||
((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
|
|
||||||
"VMEM" : "MMIO"), i,
|
|
||||||
(unsigned long long) base64);
|
|
||||||
|
|
||||||
if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
|
|
||||||
{
|
|
||||||
*fb_base = base64;
|
|
||||||
if (find_line_len (fb_base, line_len))
|
|
||||||
found++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
addr += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_pci_iterate (find_card);
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_err_t
|
|
||||||
grub_xnu_set_video (struct grub_xnu_boot_params *params)
|
|
||||||
{
|
|
||||||
grub_efi_uga_draw_protocol_t *c;
|
|
||||||
grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
c = grub_efi_locate_protocol (&uga_draw_guid, 0);
|
|
||||||
if (! c)
|
|
||||||
return grub_error (GRUB_ERR_IO, "couldn't find UGADraw");
|
|
||||||
|
|
||||||
if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
|
|
||||||
return grub_error (GRUB_ERR_IO, "couldn't retrieve video mode");
|
|
||||||
|
|
||||||
grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
|
|
||||||
|
|
||||||
grub_efi_set_text_mode (0);
|
|
||||||
pixel = RGB_MAGIC;
|
|
||||||
efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
|
|
||||||
GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
|
|
||||||
ret = find_framebuf (&fb_base, &line_len);
|
|
||||||
grub_efi_set_text_mode (1);
|
|
||||||
|
|
||||||
if (! ret)
|
|
||||||
return grub_error (GRUB_ERR_IO, "can\'t find frame buffer address");
|
|
||||||
|
|
||||||
grub_printf ("Frame buffer base: 0x%x\n", fb_base);
|
|
||||||
grub_printf ("Video line length: %d\n", line_len);
|
|
||||||
|
|
||||||
params->lfb_width = width;
|
|
||||||
params->lfb_height = height;
|
|
||||||
params->lfb_depth = depth;
|
|
||||||
params->lfb_line_len = line_len;
|
|
||||||
params->lfb_mode = GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
|
|
||||||
params->lfb_base = fb_base;
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
|
@ -597,11 +597,11 @@ grub_linux_boot (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 (DEFAULT_VIDEO_MODE, 0);
|
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GRUB is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <grub/env.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/xnu.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/cpu/xnu.h>
|
|
||||||
#include <grub/video_fb.h>
|
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
struct grub_video_mode_info mode_info;
|
|
||||||
int ret;
|
|
||||||
char *tmp, *modevar;
|
|
||||||
void *framebuffer;
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (grub_xnu_bitmap)
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
x = mode_info.width - grub_xnu_bitmap->mode_info.width;
|
|
||||||
x /= 2;
|
|
||||||
y = mode_info.height - grub_xnu_bitmap->mode_info.height;
|
|
||||||
y /= 2;
|
|
||||||
err = grub_video_blit_bitmap (grub_xnu_bitmap,
|
|
||||||
GRUB_VIDEO_BLIT_REPLACE,
|
|
||||||
x > 0 ? x : 0,
|
|
||||||
y > 0 ? y : 0,
|
|
||||||
x < 0 ? -x : 0,
|
|
||||||
y < 0 ? -y : 0,
|
|
||||||
min (grub_xnu_bitmap->mode_info.width,
|
|
||||||
mode_info.width),
|
|
||||||
min (grub_xnu_bitmap->mode_info.height,
|
|
||||||
mode_info.height));
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
grub_print_error ();
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
grub_xnu_bitmap = 0;
|
|
||||||
}
|
|
||||||
err = GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
|
|
||||||
if (ret)
|
|
||||||
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
|
|
||||||
|
|
||||||
params->lfb_width = mode_info.width;
|
|
||||||
params->lfb_height = mode_info.height;
|
|
||||||
params->lfb_depth = mode_info.bpp;
|
|
||||||
params->lfb_line_len = mode_info.pitch;
|
|
||||||
|
|
||||||
params->lfb_base = PTR_TO_UINT32 (framebuffer);
|
|
||||||
params->lfb_mode = grub_xnu_bitmap
|
|
||||||
? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -34,6 +34,11 @@
|
||||||
#include <grub/gzio.h>
|
#include <grub/gzio.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
#define DEFAULT_VIDEO_MODE "auto"
|
||||||
|
|
||||||
char grub_xnu_cmdline[1024];
|
char grub_xnu_cmdline[1024];
|
||||||
grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
|
grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
|
||||||
|
|
||||||
|
@ -834,6 +839,84 @@ grub_xnu_boot_resume (void)
|
||||||
return grub_relocator32_boot (grub_xnu_relocator, state);
|
return grub_relocator32_boot (grub_xnu_relocator, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Setup video for xnu. */
|
||||||
|
static grub_err_t
|
||||||
|
grub_xnu_set_video (struct grub_xnu_boot_params *params)
|
||||||
|
{
|
||||||
|
struct grub_video_mode_info mode_info;
|
||||||
|
int ret;
|
||||||
|
char *tmp, *modevar;
|
||||||
|
void *framebuffer;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
modevar = grub_env_get ("gfxpayload");
|
||||||
|
/* Consider only graphical 32-bit deep modes. */
|
||||||
|
if (! modevar || *modevar == 0)
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
|
||||||
|
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
|
||||||
|
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
|
||||||
|
grub_free (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (grub_xnu_bitmap)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
x = mode_info.width - grub_xnu_bitmap->mode_info.width;
|
||||||
|
x /= 2;
|
||||||
|
y = mode_info.height - grub_xnu_bitmap->mode_info.height;
|
||||||
|
y /= 2;
|
||||||
|
err = grub_video_blit_bitmap (grub_xnu_bitmap,
|
||||||
|
GRUB_VIDEO_BLIT_REPLACE,
|
||||||
|
x > 0 ? x : 0,
|
||||||
|
y > 0 ? y : 0,
|
||||||
|
x < 0 ? -x : 0,
|
||||||
|
y < 0 ? -y : 0,
|
||||||
|
min (grub_xnu_bitmap->mode_info.width,
|
||||||
|
mode_info.width),
|
||||||
|
min (grub_xnu_bitmap->mode_info.height,
|
||||||
|
mode_info.height));
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
grub_xnu_bitmap = 0;
|
||||||
|
}
|
||||||
|
err = GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
|
||||||
|
if (ret)
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
|
||||||
|
|
||||||
|
params->lfb_width = mode_info.width;
|
||||||
|
params->lfb_height = mode_info.height;
|
||||||
|
params->lfb_depth = mode_info.bpp;
|
||||||
|
params->lfb_line_len = mode_info.pitch;
|
||||||
|
|
||||||
|
params->lfb_base = PTR_TO_UINT32 (framebuffer);
|
||||||
|
params->lfb_mode = grub_xnu_bitmap
|
||||||
|
? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Boot xnu. */
|
/* Boot xnu. */
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_xnu_boot (void)
|
grub_xnu_boot (void)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
245
video/video.c
245
video/video.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue