From fc4c4fddf68fc6704648a8ea53140dc56cbc5611 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 31 May 2013 00:42:33 +0200 Subject: [PATCH] Detach optional parts of gfxterm and integrate in with coreboot init. --- ChangeLog | 4 + gentpl.py | 2 +- grub-core/Makefile.am | 9 +- grub-core/Makefile.core.def | 36 +++-- grub-core/font/font_cmd.c | 4 +- grub-core/gfxmenu/gui_label.c | 1 + grub-core/gfxmenu/gui_list.c | 1 + grub-core/gfxmenu/gui_progress_bar.c | 1 + grub-core/gfxmenu/theme_loader.c | 1 + grub-core/kern/i386/coreboot/init.c | 8 + grub-core/kern/mips/qemu_mips/init.c | 2 - grub-core/term/gfxterm.c | 230 +++++---------------------- grub-core/term/gfxterm_background.c | 190 ++++++++++++++++++++++ grub-core/term/i386/pc/mda_text.c | 10 ++ grub-core/term/i386/pc/vga_text.c | 25 +-- grub-core/video/bitmap.c | 20 --- grub-core/video/colors.c | 1 + grub-core/video/fb/fbutil.c | 35 ---- grub-core/video/i386/coreboot/cbfb.c | 53 +++--- include/grub/bitmap.h | 21 ++- include/grub/color.h | 30 ++++ include/grub/fbutil.h | 11 +- include/grub/gfxterm.h | 18 ++- include/grub/i386/coreboot/console.h | 7 + include/grub/video.h | 6 - util/grub-render-label.c | 1 + 26 files changed, 410 insertions(+), 317 deletions(-) create mode 100644 grub-core/term/gfxterm_background.c create mode 100644 include/grub/color.h diff --git a/ChangeLog b/ChangeLog index 056d1a4fe..0da4f9e34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-05-30 Vladimir Serbinenko + + Detach optional parts of gfxterm and integrate in with coreboot init. + 2013-05-30 Vladimir Serbinenko Move blit and fill dispatcher to appropriate files to decrease export diff --git a/gentpl.py b/gentpl.py index cc56f7d97..776b4067e 100644 --- a/gentpl.py +++ b/gentpl.py @@ -52,7 +52,7 @@ GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] GROUPS["usb"] = GROUPS["pci"] # If gfxterm is main output console integrate it into kernel -GROUPS["videoinkernel"] = ["mips_loongson", "mips_qemu_mips"] +GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot" ] GROUPS["videomodules"] = GRUB_PLATFORMS[:]; for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index bc63a55a8..f71e05c5d 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -112,6 +112,11 @@ if COND_i386_coreboot KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h endif if COND_i386_multiboot @@ -158,12 +163,10 @@ if COND_mips_qemu_mips KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap_scale.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h @@ -177,12 +180,10 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/time.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap_scale.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index b63d33d0f..ba77a21c9 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -138,6 +138,7 @@ kernel = { i386_multiboot = kern/i386/coreboot/init.c; i386_qemu = kern/i386/qemu/init.c; i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c; + i386_coreboot = video/i386/coreboot/cbfb.c; efi = disk/efi/efidisk.c; efi = kern/efi/efi.c; @@ -180,6 +181,7 @@ kernel = { mips_qemu_mips = term/ns8250.c; mips_qemu_mips = term/serial.c; mips_qemu_mips = term/at_keyboard.c; + mips_qemu_mips = commands/boot.c; mips_qemu_mips = commands/keylayouts.c; mips_qemu_mips = term/i386/pc/vga_text.c; mips_qemu_mips = kern/vga_init.c; @@ -194,6 +196,7 @@ kernel = { mips_loongson = bus/pci.c; mips_loongson = kern/mips/loongson/init.c; mips_loongson = term/at_keyboard.c; + mips_loongson = commands/boot.c; mips_loongson = term/serial.c; mips_loongson = video/sm712.c; mips_loongson = video/sis315pro.c; @@ -227,17 +230,12 @@ kernel = { videoinkernel = font/font.c; videoinkernel = font/font_cmd.c; videoinkernel = io/bufio.c; - videoinkernel = video/bitmap.c; - videoinkernel = video/bitmap_scale.c; - videoinkernel = video/colors.c; videoinkernel = video/fb/fbblit.c; videoinkernel = video/fb/fbfill.c; videoinkernel = video/fb/fbutil.c; videoinkernel = video/fb/video_fb.c; videoinkernel = video/video.c; - videoinkernel = commands/boot.c; - extra_dist = kern/i386/int.S; extra_dist = kern/i386/realmode.S; extra_dist = boot/i386/pc/lzma_decode.S; @@ -656,7 +654,12 @@ module = { name = boot; common = commands/boot.c; i386_pc = lib/i386/pc/biosnum.c; - enable = videomodules; + enable = x86; + enable = emu; + enable = sparc64_ieee1275; + enable = powerpc_ieee1275; + enable = mips_arc; + enable = ia64_efi; }; module = { @@ -1674,6 +1677,11 @@ module = { enable = videomodules; }; +module = { + name = gfxterm_background; + common = term/gfxterm_background.c; +}; + module = { name = serial; common = term/serial.c; @@ -1775,13 +1783,11 @@ module = { module = { name = bitmap; common = video/bitmap.c; - enable = videomodules; }; module = { name = bitmap_scale; common = video/bitmap_scale.c; - enable = videomodules; }; module = { @@ -1830,22 +1836,20 @@ module = { module = { name = video; common = video/video.c; - common = video/colors.c; enable = videomodules; }; +module = { + name = video_colors; + common = video/colors.c; +}; + module = { name = ieee1275_fb; ieee1275 = video/ieee1275.c; enable = powerpc_ieee1275; }; -module = { - name = coreboot_fb; - common = video/i386/coreboot/cbfb.c; - enable = i386_coreboot; -}; - module = { name = sdl; emu = video/emu/sdl.c; @@ -1959,7 +1963,7 @@ module = { module = { name = keylayouts; common = commands/keylayouts.c; - enable = videomodules; + enable = x86; }; module = { diff --git a/grub-core/font/font_cmd.c b/grub-core/font/font_cmd.c index 1d9ddea54..f3b36f2d6 100644 --- a/grub-core/font/font_cmd.c +++ b/grub-core/font/font_cmd.c @@ -61,7 +61,7 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), static grub_command_t cmd_loadfont, cmd_lsfonts; -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) +#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_COREBOOT) void grub_font_init (void) #else GRUB_MOD_INIT(font) @@ -78,7 +78,7 @@ GRUB_MOD_INIT(font) 0, N_("List the loaded fonts.")); } -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) +#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_COREBOOT) void grub_font_fini (void) #else GRUB_MOD_FINI(font) diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c index 637578f77..507c01014 100644 --- a/grub-core/gfxmenu/gui_label.c +++ b/grub-core/gfxmenu/gui_label.c @@ -23,6 +23,7 @@ #include #include #include +#include static const char *align_options[] = { diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index 3d227eec4..12c352863 100644 --- a/grub-core/gfxmenu/gui_list.c +++ b/grub-core/gfxmenu/gui_list.c @@ -23,6 +23,7 @@ #include #include #include +#include struct grub_gui_list_impl { diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c index b29efc016..4294b7beb 100644 --- a/grub-core/gfxmenu/gui_progress_bar.c +++ b/grub-core/gfxmenu/gui_progress_bar.c @@ -25,6 +25,7 @@ #include #include #include +#include struct grub_gui_progress_bar { diff --git a/grub-core/gfxmenu/theme_loader.c b/grub-core/gfxmenu/theme_loader.c index f9c711d3e..4aaa35219 100644 --- a/grub-core/gfxmenu/theme_loader.c +++ b/grub-core/gfxmenu/theme_loader.c @@ -30,6 +30,7 @@ #include #include #include +#include /* Construct a new box widget using ABSPATTERN to find the pixmap files for it, storing the new box instance at *BOXPTR. diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index 7cd530db8..9385411ca 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -34,6 +34,7 @@ #include #include #include +#include extern grub_uint8_t _start[]; extern grub_uint8_t _end[]; @@ -89,6 +90,8 @@ grub_machine_init (void) { modend = grub_modules_get_end (); + grub_video_coreboot_fb_early_init (); + grub_vga_text_init (); #ifdef GRUB_MACHINE_MULTIBOOT @@ -96,6 +99,11 @@ grub_machine_init (void) #endif grub_machine_mmap_iterate (heap_init, NULL); + grub_video_coreboot_fb_late_init (); + + grub_font_init (); + grub_gfxterm_init (); + grub_tsc_init (); } diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index 050f19f6a..e003976ef 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -69,8 +69,6 @@ grub_machine_init (void) grub_serial_init (); grub_boot_init (); - - grub_gfxterm_init (); } void diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 0e5bcd95f..ae4a39030 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -28,7 +28,6 @@ #include #include #include -#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -113,7 +112,6 @@ static struct grub_video_render_target *render_target; void (*grub_gfxterm_decorator_hook) (void) = NULL; static struct grub_gfxterm_window window; static struct grub_virtual_screen virtual_screen; -static grub_gfxterm_repaint_callback_t repaint_callback; static int repaint_scheduled = 0; static int repaint_was_scheduled = 0; @@ -121,11 +119,7 @@ static void destroy_window (void); static struct grub_video_render_target *text_layer; -static unsigned int bitmap_width; -static unsigned int bitmap_height; -static struct grub_video_bitmap *bitmap; -static int blend_text_bg; -static grub_video_rgba_color_t default_bg_color = { 0, 0, 0, 0 }; +struct grub_gfxterm_background grub_gfxterm_background; static struct grub_dirty_region dirty_region; @@ -262,7 +256,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, grub_video_set_active_render_target (render_target); virtual_screen.bg_color_display = - grub_video_map_rgba_color (default_bg_color); + grub_video_map_rgba_color (grub_gfxterm_background.default_bg_color); /* Clear out text buffer. */ for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) @@ -336,7 +330,7 @@ grub_gfxterm_fullscreen (void) && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); /* Make sure screen is set to the default background color. */ - color = grub_video_map_rgba_color (default_bg_color); + color = grub_video_map_rgba_color (grub_gfxterm_background.default_bg_color); grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); if (double_redraw) { @@ -395,7 +389,6 @@ grub_gfxterm_term_init (struct grub_term_output *term __attribute__ ((unused))) static void destroy_window (void) { - repaint_callback = 0; grub_virtual_screen_free (); } @@ -433,10 +426,11 @@ redraw_screen_rect (unsigned int x, unsigned int y, (unsigned *) &saved_view.height); grub_video_set_viewport (window.x, window.y, window.width, window.height); - if (bitmap) + if (grub_gfxterm_background.bitmap) { /* Render bitmap as background. */ - grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y, + grub_video_blit_bitmap (grub_gfxterm_background.bitmap, + GRUB_VIDEO_BLIT_REPLACE, x, y, x, y, width, height); @@ -445,20 +439,21 @@ redraw_screen_rect (unsigned int x, unsigned int y, color = virtual_screen.bg_color_display; /* Fill right side of the bitmap if needed. */ - if ((x + width >= bitmap_width) && (y < bitmap_height)) + if ((x + width >= grub_gfxterm_background.bitmap->mode_info.width) + && (y < grub_gfxterm_background.bitmap->mode_info.height)) { - int w = (x + width) - bitmap_width; + int w = (x + width) - grub_gfxterm_background.bitmap->mode_info.width; int h = height; unsigned int tx = x; - if (y + height >= bitmap_height) + if (y + height >= grub_gfxterm_background.bitmap->mode_info.height) { - h = bitmap_height - y; + h = grub_gfxterm_background.bitmap->mode_info.height - y; } - if (bitmap_width > tx) + if (grub_gfxterm_background.bitmap->mode_info.width > tx) { - tx = bitmap_width; + tx = grub_gfxterm_background.bitmap->mode_info.width; } /* Render background layer. */ @@ -466,14 +461,14 @@ redraw_screen_rect (unsigned int x, unsigned int y, } /* Fill bottom side of the bitmap if needed. */ - if (y + height >= bitmap_height) + if (y + height >= grub_gfxterm_background.bitmap->mode_info.height) { - int h = (y + height) - bitmap_height; + int h = (y + height) - grub_gfxterm_background.bitmap->mode_info.height; unsigned int ty = y; - if (bitmap_height > ty) + if (grub_gfxterm_background.bitmap->mode_info.height > ty) { - ty = bitmap_height; + ty = grub_gfxterm_background.bitmap->mode_info.height; } /* Render background layer. */ @@ -487,7 +482,7 @@ redraw_screen_rect (unsigned int x, unsigned int y, grub_video_fill_rect (color, x, y, width, height); } - if (blend_text_bg) + if (grub_gfxterm_background.blend_text_bg) /* Render text layer as blended. */ grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y, x - virtual_screen.offset_x, @@ -504,9 +499,6 @@ redraw_screen_rect (unsigned int x, unsigned int y, grub_video_set_viewport (saved_view.x, saved_view.y, saved_view.width, saved_view.height); grub_video_set_active_render_target (render_target); - - if (repaint_callback) - repaint_callback (x, y, width, height); } static void @@ -561,8 +553,8 @@ dirty_region_add (int x, int y, unsigned int width, unsigned int height) if (repaint_scheduled) { - dirty_region_add_real (virtual_screen.offset_x, virtual_screen.offset_y, - virtual_screen.width, virtual_screen.height); + dirty_region_add_real (0, 0, + window.width, window.height); repaint_scheduled = 0; repaint_was_scheduled = 1; } @@ -707,7 +699,7 @@ real_scroll (void) return; /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */ - if (bitmap) + if (grub_gfxterm_background.bitmap) { /* Scroll physical screen. */ grub_video_set_active_render_target (text_layer); @@ -791,9 +783,6 @@ real_scroll (void) /* Draw cursor if visible. */ if (virtual_screen.cursor_state) draw_cursor (1); - - if (repaint_callback) - repaint_callback (window.x, window.y, window.width, window.height); } static void @@ -1092,145 +1081,6 @@ grub_gfxterm_refresh (struct grub_term_output *term __attribute__ ((unused))) dirty_region_reset (); } -void -grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func) -{ - repaint_callback = func; -} - -/* Option array indices. */ -#define BACKGROUND_CMD_ARGINDEX_MODE 0 - -static const struct grub_arg_option background_image_cmd_options[] = - { - {"mode", 'm', 0, N_("Background image mode."), - /* TRANSLATORS: This refers to background image mode (stretched or - in left-top corner). Note that GRUB will accept only original - keywords stretch and normal, not the translated ones. - So please put both in translation - e.g. stretch(=%STRETCH%)|normal(=%NORMAL%). - The percents mark the translated version. Since many people - may not know the word stretch or normal I recommend - putting the translation either here or in "Background image mode." - string. */ - N_("stretch|normal"), - ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, - int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - - /* Check that we have video adapter active. */ - if (grub_video_get_info(NULL) != GRUB_ERR_NONE) - return grub_errno; - - /* Destroy existing background bitmap if loaded. */ - if (bitmap) - { - grub_video_bitmap_destroy (bitmap); - bitmap = 0; - blend_text_bg = 0; - - /* Mark whole screen as dirty. */ - dirty_region_add (0, 0, window.width, window.height); - } - - /* If filename was provided, try to load that. */ - if (argc >= 1) - { - /* Try to load new one. */ - grub_video_bitmap_load (&bitmap, args[0]); - if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - - /* Determine if the bitmap should be scaled to fit the screen. */ - if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set - || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg, - "stretch") == 0) - { - if (window.width != grub_video_bitmap_get_width (bitmap) - || window.height != grub_video_bitmap_get_height (bitmap)) - { - struct grub_video_bitmap *scaled_bitmap; - grub_video_bitmap_create_scaled (&scaled_bitmap, - window.width, - window.height, - bitmap, - GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); - if (grub_errno == GRUB_ERR_NONE) - { - /* Replace the original bitmap with the scaled one. */ - grub_video_bitmap_destroy (bitmap); - bitmap = scaled_bitmap; - } - } - } - - /* If bitmap was loaded correctly, display it. */ - if (bitmap) - { - blend_text_bg = 1; - - /* Determine bitmap dimensions. */ - bitmap_width = grub_video_bitmap_get_width (bitmap); - bitmap_height = grub_video_bitmap_get_height (bitmap); - - /* Mark whole screen as dirty. */ - dirty_region_add (0, 0, window.width, window.height); - } - } - - /* All was ok. */ - grub_errno = GRUB_ERR_NONE; - return grub_errno; -} - -static grub_err_t -grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_video_render_target *old_target; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - /* Check that we have video adapter active. */ - if (grub_video_get_info (NULL) != GRUB_ERR_NONE) - return grub_errno; - - if (grub_video_parse_color (args[0], &default_bg_color) != GRUB_ERR_NONE) - return grub_errno; - - /* Destroy existing background bitmap if loaded. */ - if (bitmap) - { - grub_video_bitmap_destroy (bitmap); - bitmap = 0; - - /* Mark whole screen as dirty. */ - dirty_region_add (0, 0, window.width, window.height); - } - - /* Set the background and border colors. The background color needs to be - compatible with the text layer. */ - grub_video_get_active_render_target (&old_target); - grub_video_set_active_render_target (text_layer); - virtual_screen.bg_color = grub_video_map_rgba_color (default_bg_color); - grub_video_set_active_render_target (old_target); - virtual_screen.bg_color_display = - grub_video_map_rgba_color (default_bg_color); - blend_text_bg = 1; - - /* Mark whole screen as dirty. */ - dirty_region_add (0, 0, window.width, window.height); - - return GRUB_ERR_NONE; -} - static struct grub_term_output grub_video_term = { .name = "gfxterm", @@ -1250,36 +1100,40 @@ static struct grub_term_output grub_video_term = .next = 0 }; -static grub_extcmd_t background_image_cmd_handle; -static grub_command_t background_color_cmd_handle; +void +grub_gfxterm_video_update_color (void) +{ + struct grub_video_render_target *old_target; -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) + grub_video_get_active_render_target (&old_target); + grub_video_set_active_render_target (text_layer); + virtual_screen.bg_color = grub_video_map_rgba_color (grub_gfxterm_background.default_bg_color); + grub_video_set_active_render_target (old_target); + virtual_screen.bg_color_display = + grub_video_map_rgba_color (grub_gfxterm_background.default_bg_color); +} + +void +grub_gfxterm_get_dimensions (unsigned *width, unsigned *height) +{ + *width = window.width; + *height = window.height; +} + +#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_COREBOOT) void grub_gfxterm_init (void) #else GRUB_MOD_INIT(gfxterm) #endif { grub_term_register_output ("gfxterm", &grub_video_term); - background_image_cmd_handle = - grub_register_extcmd ("background_image", - grub_gfxterm_background_image_cmd, 0, - N_("[-m (stretch|normal)] FILE"), - N_("Load background image for active terminal."), - background_image_cmd_options); - background_color_cmd_handle = - grub_register_command ("background_color", - grub_gfxterm_background_color_cmd, - N_("COLOR"), - N_("Set background color for active terminal.")); } -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) +#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_COEBOOT) void grub_gfxterm_fini (void) #else GRUB_MOD_FINI(gfxterm) #endif { - grub_unregister_command (background_color_cmd_handle); - grub_unregister_extcmd (background_image_cmd_handle); grub_term_unregister_output (&grub_video_term); } diff --git a/grub-core/term/gfxterm_background.c b/grub-core/term/gfxterm_background.c new file mode 100644 index 000000000..8da71a8c8 --- /dev/null +++ b/grub-core/term/gfxterm_background.c @@ -0,0 +1,190 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009,2013 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Option array indices. */ +enum + { + BACKGROUND_CMD_ARGINDEX_MODE = 0 + }; + +static const struct grub_arg_option background_image_cmd_options[] = + { + {"mode", 'm', 0, N_("Background image mode."), + /* TRANSLATORS: This refers to background image mode (stretched or + in left-top corner). Note that GRUB will accept only original + keywords stretch and normal, not the translated ones. + So please put both in translation + e.g. stretch(=%STRETCH%)|normal(=%NORMAL%). + The percents mark the translated version. Since many people + may not know the word stretch or normal I recommend + putting the translation either here or in "Background image mode." + string. */ + N_("stretch|normal"), + ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, + int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + + /* Check that we have video adapter active. */ + if (grub_video_get_info(NULL) != GRUB_ERR_NONE) + return grub_errno; + + /* Destroy existing background bitmap if loaded. */ + if (grub_gfxterm_background.bitmap) + { + grub_video_bitmap_destroy (grub_gfxterm_background.bitmap); + grub_gfxterm_background.bitmap = 0; + grub_gfxterm_background.blend_text_bg = 0; + + /* Mark whole screen as dirty. */ + grub_gfxterm_schedule_repaint (); + } + + /* If filename was provided, try to load that. */ + if (argc >= 1) + { + /* Try to load new one. */ + grub_video_bitmap_load (&grub_gfxterm_background.bitmap, args[0]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Determine if the bitmap should be scaled to fit the screen. */ + if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set + || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg, + "stretch") == 0) + { + unsigned int width, height; + grub_gfxterm_get_dimensions (&width, &height); + if (width + != grub_video_bitmap_get_width (grub_gfxterm_background.bitmap) + || height + != grub_video_bitmap_get_height (grub_gfxterm_background.bitmap)) + { + struct grub_video_bitmap *scaled_bitmap; + grub_video_bitmap_create_scaled (&scaled_bitmap, + width, + height, + grub_gfxterm_background.bitmap, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + if (grub_errno == GRUB_ERR_NONE) + { + /* Replace the original bitmap with the scaled one. */ + grub_video_bitmap_destroy (grub_gfxterm_background.bitmap); + grub_gfxterm_background.bitmap = scaled_bitmap; + } + } + } + + /* If bitmap was loaded correctly, display it. */ + if (grub_gfxterm_background.bitmap) + { + grub_gfxterm_background.blend_text_bg = 1; + + /* Mark whole screen as dirty. */ + grub_gfxterm_schedule_repaint (); + } + } + + /* All was ok. */ + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + +static grub_err_t +grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + /* Check that we have video adapter active. */ + if (grub_video_get_info (NULL) != GRUB_ERR_NONE) + return grub_errno; + + if (grub_video_parse_color (args[0], + &grub_gfxterm_background.default_bg_color) + != GRUB_ERR_NONE) + return grub_errno; + + /* Destroy existing background bitmap if loaded. */ + if (grub_gfxterm_background.bitmap) + { + grub_video_bitmap_destroy (grub_gfxterm_background.bitmap); + grub_gfxterm_background.bitmap = 0; + + /* Mark whole screen as dirty. */ + grub_gfxterm_schedule_repaint (); + } + + /* Set the background and border colors. The background color needs to be + compatible with the text layer. */ + grub_gfxterm_video_update_color (); + grub_gfxterm_background.blend_text_bg = 1; + + /* Mark whole screen as dirty. */ + grub_gfxterm_schedule_repaint (); + + return GRUB_ERR_NONE; +} + +static grub_extcmd_t background_image_cmd_handle; +static grub_command_t background_color_cmd_handle; + +GRUB_MOD_INIT(gfxterm_background) +{ + background_image_cmd_handle = + grub_register_extcmd ("background_image", + grub_gfxterm_background_image_cmd, 0, + N_("[-m (stretch|normal)] FILE"), + N_("Load background image for active terminal."), + background_image_cmd_options); + background_color_cmd_handle = + grub_register_command ("background_color", + grub_gfxterm_background_color_cmd, + N_("COLOR"), + N_("Set background color for active terminal.")); +} + +GRUB_MOD_FINI(gfxterm_background) +{ + grub_unregister_command (background_color_cmd_handle); + grub_unregister_extcmd (background_image_cmd_handle); +} diff --git a/grub-core/term/i386/pc/mda_text.c b/grub-core/term/i386/pc/mda_text.c index 907a36ebb..c3a5a1788 100644 --- a/grub-core/term/i386/pc/mda_text.c +++ b/grub-core/term/i386/pc/mda_text.c @@ -1,3 +1,13 @@ #define MODE_MDA 1 #include "vga_text.c" +GRUB_MOD_INIT(mda_text) +{ + grub_term_register_output ("mda_text", &grub_vga_text_term); +} + +GRUB_MOD_FINI(mda_text) +{ + grub_term_unregister_output (&grub_vga_text_term); +} + diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c index e976aec9b..06850ac40 100644 --- a/grub-core/term/i386/pc/vga_text.c +++ b/grub-core/term/i386/pc/vga_text.c @@ -22,6 +22,10 @@ #include #include +#if defined (GRUB_MACHINE_COREBOOT) +#include +#endif + /* MODESET is used for testing to force monochrome or colour mode. You shouldn't use mda_text on vga. */ @@ -267,24 +271,23 @@ static struct grub_term_output grub_vga_text_term = .flags = GRUB_TERM_CODE_TYPE_CP437, }; -#ifdef MODE_MDA -GRUB_MOD_INIT(mda_text) -#elif defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) +/* FIXME: this is was too spaghetti. */ + +#ifndef MODE_MDA + +#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) void grub_vga_text_init (void) #else GRUB_MOD_INIT(vga_text) #endif { -#ifdef MODE_MDA - grub_term_register_output ("mda_text", &grub_vga_text_term); -#else - grub_term_register_output ("vga_text", &grub_vga_text_term); +#ifdef GRUB_MACHINE_COREBOOT + if (!grub_video_coreboot_fbtable) #endif + grub_term_register_output ("vga_text", &grub_vga_text_term); } -#ifdef MODE_MDA -GRUB_MOD_FINI(mda_text) -#elif defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) +#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) void grub_vga_text_fini (void) #else GRUB_MOD_FINI(vga_text) @@ -292,3 +295,5 @@ GRUB_MOD_FINI(vga_text) { grub_term_unregister_output (&grub_vga_text_term); } + +#endif diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c index bb41d10cb..b2e031566 100644 --- a/grub-core/video/bitmap.c +++ b/grub-core/video/bitmap.c @@ -210,26 +210,6 @@ grub_video_bitmap_load (struct grub_video_bitmap **bitmap, " unsupported format"), filename); } -/* Return bitmap width. */ -unsigned int -grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap) -{ - if (!bitmap) - return 0; - - return bitmap->mode_info.width; -} - -/* Return bitmap height. */ -unsigned int -grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) -{ - if (!bitmap) - return 0; - - return bitmap->mode_info.height; -} - /* Return mode info for bitmap. */ void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, struct grub_video_mode_info *mode_info) diff --git a/grub-core/video/colors.c b/grub-core/video/colors.c index 76359eaf0..485ebb4ab 100644 --- a/grub-core/video/colors.c +++ b/grub-core/video/colors.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c index 81b3860ac..b98bb51fe 100644 --- a/grub-core/video/fb/fbutil.c +++ b/grub-core/video/fb/fbutil.c @@ -31,41 +31,6 @@ #include #include -void * -grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, - unsigned int x, unsigned int y) -{ - grub_uint8_t *ptr = 0; - - switch (source->mode_info->bpp) - { - case 32: - ptr = source->data + y * source->mode_info->pitch + x * 4; - break; - - case 24: - ptr = source->data + y * source->mode_info->pitch + x * 3; - break; - - case 16: - case 15: - ptr = source->data + y * source->mode_info->pitch + x * 2; - break; - - case 8: - ptr = source->data + y * source->mode_info->pitch + x; - break; - - case 1: - /* For 1-bit bitmaps, addressing needs to be done at the bit level - and it doesn't make sense, in general, to ask for a pointer - to a particular pixel's data. */ - break; - } - - return ptr; -} - grub_video_color_t get_pixel (struct grub_video_fbblit_info *source, unsigned int x, unsigned int y) diff --git a/grub-core/video/i386/coreboot/cbfb.c b/grub-core/video/i386/coreboot/cbfb.c index 984b5943e..62b86db2b 100644 --- a/grub-core/video/i386/coreboot/cbfb.c +++ b/grub-core/video/i386/coreboot/cbfb.c @@ -26,10 +26,9 @@ #include #include #include +#include -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct grub_linuxbios_table_framebuffer *cbfb; +struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; static struct { @@ -50,22 +49,22 @@ grub_video_cbfb_fill_mode_info (struct grub_video_mode_info *out) { grub_memset (out, 0, sizeof (*out)); - out->width = cbfb->width; - out->height = cbfb->height; - out->pitch = cbfb->pitch; + out->width = grub_video_coreboot_fbtable->width; + out->height = grub_video_coreboot_fbtable->height; + out->pitch = grub_video_coreboot_fbtable->pitch; - out->red_field_pos = cbfb->red_field_pos; - out->red_mask_size = cbfb->red_mask_size; - out->green_field_pos = cbfb->green_field_pos; - out->green_mask_size = cbfb->green_mask_size; - out->blue_field_pos = cbfb->blue_field_pos; - out->blue_mask_size = cbfb->blue_mask_size; - out->reserved_field_pos = cbfb->reserved_field_pos; - out->reserved_mask_size = cbfb->reserved_mask_size; + out->red_field_pos = grub_video_coreboot_fbtable->red_field_pos; + out->red_mask_size = grub_video_coreboot_fbtable->red_mask_size; + out->green_field_pos = grub_video_coreboot_fbtable->green_field_pos; + out->green_mask_size = grub_video_coreboot_fbtable->green_mask_size; + out->blue_field_pos = grub_video_coreboot_fbtable->blue_field_pos; + out->blue_mask_size = grub_video_coreboot_fbtable->blue_mask_size; + out->reserved_field_pos = grub_video_coreboot_fbtable->reserved_field_pos; + out->reserved_mask_size = grub_video_coreboot_fbtable->reserved_mask_size; out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB; - out->bpp = cbfb->bpp; - out->bytes_per_pixel = (cbfb->bpp + 7) / 8; + out->bpp = grub_video_coreboot_fbtable->bpp; + out->bytes_per_pixel = (grub_video_coreboot_fbtable->bpp + 7) / 8; out->number_of_colors = 256; out->blit_format = grub_video_get_blit_format (out); @@ -79,10 +78,10 @@ grub_video_cbfb_setup (unsigned int width, unsigned int height, { grub_err_t err; - if (!cbfb) + if (!grub_video_coreboot_fbtable) return grub_error (GRUB_ERR_IO, "Couldn't find display device."); - if (!((width == cbfb->width && height == cbfb->height) + if (!((width == grub_video_coreboot_fbtable->width && height == grub_video_coreboot_fbtable->height) || (width == 0 && height == 0))) return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height); @@ -93,7 +92,7 @@ grub_video_cbfb_setup (unsigned int width, unsigned int height, return err; } - framebuffer.ptr = (void *) (grub_addr_t) cbfb->lfb; + framebuffer.ptr = (void *) (grub_addr_t) grub_video_coreboot_fbtable->lfb; grub_dprintf ("video", "CBFB: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, @@ -162,20 +161,26 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, { if (table_item->tag != GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER) return 0; - cbfb = (struct grub_linuxbios_table_framebuffer *) (table_item + 1); + grub_video_coreboot_fbtable = (struct grub_linuxbios_table_framebuffer *) (table_item + 1); return 1; } -GRUB_MOD_INIT(coreboot_fb) +void +grub_video_coreboot_fb_early_init (void) { grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); +} - if (cbfb) +void +grub_video_coreboot_fb_late_init (void) +{ + if (grub_video_coreboot_fbtable) grub_video_register (&grub_video_cbfb_adapter); } -GRUB_MOD_FINI(coreboot_fb) +void +grub_video_coreboot_fb_fini (void) { - if (cbfb) + if (grub_video_coreboot_fbtable) grub_video_unregister (&grub_video_cbfb_adapter); } diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h index 6e300391a..5728f8ca3 100644 --- a/include/grub/bitmap.h +++ b/include/grub/bitmap.h @@ -59,8 +59,25 @@ grub_err_t EXPORT_FUNC (grub_video_bitmap_destroy) (struct grub_video_bitmap *bi grub_err_t EXPORT_FUNC (grub_video_bitmap_load) (struct grub_video_bitmap **bitmap, const char *filename); -unsigned int EXPORT_FUNC (grub_video_bitmap_get_width) (struct grub_video_bitmap *bitmap); -unsigned int EXPORT_FUNC (grub_video_bitmap_get_height) (struct grub_video_bitmap *bitmap); +/* Return bitmap width. */ +static inline unsigned int +grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap) +{ + if (!bitmap) + return 0; + + return bitmap->mode_info.width; +} + +/* Return bitmap height. */ +static inline unsigned int +grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) +{ + if (!bitmap) + return 0; + + return bitmap->mode_info.height; +} void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap, struct grub_video_mode_info *mode_info); diff --git a/include/grub/color.h b/include/grub/color.h new file mode 100644 index 000000000..cb004a9a1 --- /dev/null +++ b/include/grub/color.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,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 . + */ + +#ifndef GRUB_VIDEO_COLOR_HEADER +#define GRUB_VIDEO_COLOR_HEADER 1 + +#include + +int grub_video_get_named_color (const char *name, + grub_video_rgba_color_t *color); + +grub_err_t grub_video_parse_color (const char *s, + grub_video_rgba_color_t *color); + +#endif diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h index f68db43b1..4205eb917 100644 --- a/include/grub/fbutil.h +++ b/include/grub/fbutil.h @@ -31,8 +31,15 @@ struct grub_video_fbblit_info grub_uint8_t *data; }; -void *grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, - unsigned int x, unsigned int y); +/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level + and it doesn't make sense, in general, to ask for a pointer + to a particular pixel's data. */ +static inline void * +grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, + unsigned int x, unsigned int y) +{ + return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel; +} /* Advance pointer by VAL bytes. If there is no unaligned access available, VAL has to be divisible by size of pointed type. diff --git a/include/grub/gfxterm.h b/include/grub/gfxterm.h index 361f73e50..7e1ff6dfc 100644 --- a/include/grub/gfxterm.h +++ b/include/grub/gfxterm.h @@ -31,13 +31,21 @@ EXPORT_FUNC (grub_gfxterm_set_window) (struct grub_video_render_target *target, int double_repaint, grub_font_t font, int border_width); -typedef void (*grub_gfxterm_repaint_callback_t)(int x, int y, - int width, int height); - -void grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func); - void EXPORT_FUNC (grub_gfxterm_schedule_repaint) (void); extern void (*EXPORT_VAR (grub_gfxterm_decorator_hook)) (void); +struct grub_gfxterm_background +{ + struct grub_video_bitmap *bitmap; + int blend_text_bg; + grub_video_rgba_color_t default_bg_color; +}; + +extern struct grub_gfxterm_background EXPORT_VAR (grub_gfxterm_background); + +void EXPORT_FUNC (grub_gfxterm_video_update_color) (void); +void +EXPORT_FUNC (grub_gfxterm_get_dimensions) (unsigned *width, unsigned *height); + #endif /* ! GRUB_GFXTERM_HEADER */ diff --git a/include/grub/i386/coreboot/console.h b/include/grub/i386/coreboot/console.h index 2ffef7300..9cfa24759 100644 --- a/include/grub/i386/coreboot/console.h +++ b/include/grub/i386/coreboot/console.h @@ -22,4 +22,11 @@ void grub_vga_text_init (void); void grub_vga_text_fini (void); +void grub_video_coreboot_fb_init (void); +void grub_video_coreboot_fb_early_init (void); +void grub_video_coreboot_fb_late_init (void); +void grub_video_coreboot_fb_fini (void); + +extern struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; + #endif /* ! GRUB_MACHINE_CONSOLE_HEADER */ diff --git a/include/grub/video.h b/include/grub/video.h index b2d145812..c444536bf 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -531,12 +531,6 @@ grub_video_map_rgba_color (grub_video_rgba_color_t c) return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); } -int EXPORT_FUNC (grub_video_get_named_color) (const char *name, - grub_video_rgba_color_t *color); - -grub_err_t EXPORT_FUNC (grub_video_parse_color) (const char *s, - grub_video_rgba_color_t *color); - #ifndef GRUB_MACHINE_EMU extern void grub_font_init (void); extern void grub_font_fini (void); diff --git a/util/grub-render-label.c b/util/grub-render-label.c index 325af6d69..2af7eff13 100644 --- a/util/grub-render-label.c +++ b/util/grub-render-label.c @@ -24,6 +24,7 @@ #include #include #include +#include #define _GNU_SOURCE 1