+2008-01-01 Vesa Jaaskelainen <chaac@nic.fi>
+
+ * include/grub/video.h: Added grub_video_unmap_color and
+ grub_video_get_active_render_target.
+ (grub_video_adapter): Added unmap_color and get_active_render_target.
+
+ * video/video.c: Added grub_video_unmap_color and
+ grub_video_get_active_render_target.
+ (grub_video_get_info): Changed method to accept NULL pointer as an
+ argument to allow detection of active video adapter.
+
+ * video/i386/pc/vbe.c: Renamed grub_video_vbe_unmap_color as
+ grub_video_vbe_unmap_color_int.
+ Added grub_video_vbe_unmap_color and
+ grub_video_vbe_get_active_render_target.
+ (grub_video_vbe_adapter): Added unmap_color and
+ get_active_render_target.
+
+ * video/i386/pc/vbeblit.c: Replaced grub_video_vbe_unmap_color usage
+ with grub_video_vbe_unmap_color_int.
+
+ * term/gfxterm.c (DEFAULT_STANDARD_COLOR): Added.
+ (DEFAULT_NORMAL_COLOR): Likewise.
+ (DEFAULT_HIGHLIGHT_COLOR) Likewise.
+ (DEFAULT_FG_COLOR): Removed.
+ (DEFAULT_BG_COLOR): Likewise.
+ (DEFAULT_CURSOR_COLOR): Changed value.
+ (grub_virtual_screen): Added standard_color_setting,
+ normal_color_setting, highlight_color_setting and term_color.
+ (grub_virtual_screen): Removed fg_color_setting and bg_color_setting.
+ (bitmap_width): Added.
+ (bitmap_height): Likewise.
+ (bitmap): Likewise.
+ (set_term_color): Likewise.
+ (grub_virtual_screen_setup): Changed to use new terminal coloring
+ settings.
+ (grub_gfxterm_init): Added init for bitmap.
+ (grub_gfxterm_fini): Added destroy for bitmap.
+ (redraw_screen_rect): Updated to use background bitmap and new
+ terminal coloring.
+ (scroll_up): Added optimization for case when there is no bitmap.
+ (grub_gfxterm_cls): Fixed to use correct background color.
+ (grub_virtual_screen_setcolorstate): Changed to use new terminal
+ coloring.
+ (grub_virtual_screen_setcolor): Likewise.
+ (grub_virtual_screen_getcolor): Added.
+ (grub_gfxterm_background_image_cmd): Likewise.
+ (grub_video_term): Added setcolor and getcolor.
+ (MOD_INIT): Added registration of background_image command.
+ (MOD_TERM): Added unregistration for background_image command.
+
2007-12-30 Pavel Roskin <proski@gnu.org>
* loader/multiboot_loader.c: Fix multiboot command
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006,2007,2008 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
grub_uint8_t blue,
grub_uint8_t alpha);
-void grub_video_vbe_unmap_color (struct grub_video_i386_vbeblit_info *source,
- grub_video_color_t color, grub_uint8_t *red,
- grub_uint8_t *green, grub_uint8_t *blue,
- grub_uint8_t *alpha);
+grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color,
+ grub_uint8_t *red,
+ grub_uint8_t *green,
+ grub_uint8_t *blue,
+ grub_uint8_t *alpha);
+
+void grub_video_vbe_unmap_color_int (struct grub_video_i386_vbeblit_info *source,
+ grub_video_color_t color,
+ grub_uint8_t *red,
+ grub_uint8_t *green,
+ grub_uint8_t *blue,
+ grub_uint8_t *alpha);
#endif /* ! GRUB_VBE_MACHINE_HEADER */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2008 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
grub_video_color_t (*map_rgba) (grub_uint8_t red, grub_uint8_t green,
grub_uint8_t blue, grub_uint8_t alpha);
+ grub_err_t (*unmap_color) (grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha);
+
grub_err_t (*fill_rect) (grub_video_color_t color, int x, int y,
unsigned int width, unsigned int height);
grub_err_t (*set_active_render_target) (struct grub_video_render_target *target);
+ grub_err_t (*get_active_render_target) (struct grub_video_render_target **target);
+
/* The next video adapter. */
struct grub_video_adapter *next;
};
grub_video_color_t grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green,
grub_uint8_t blue, grub_uint8_t alpha);
+grub_err_t grub_video_unmap_color (grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha);
+
grub_err_t grub_video_fill_rect (grub_video_color_t color, int x, int y,
unsigned int width, unsigned int height);
grub_err_t grub_video_set_active_render_target (struct grub_video_render_target *target);
+grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
+
#endif /* ! GRUB_VIDEO_HEADER */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2008 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
#include <grub/mm.h>
#include <grub/env.h>
#include <grub/video.h>
+#include <grub/bitmap.h>
#define DEFAULT_VIDEO_WIDTH 640
#define DEFAULT_VIDEO_HEIGHT 480
#define DEFAULT_BORDER_WIDTH 10
-#define DEFAULT_FG_COLOR 0x0a
-#define DEFAULT_BG_COLOR 0x00
-#define DEFAULT_CURSOR_COLOR 0x0f
+#define DEFAULT_STANDARD_COLOR 0x07
+#define DEFAULT_NORMAL_COLOR 0x07
+#define DEFAULT_HIGHLIGHT_COLOR 0x70
+#define DEFAULT_CURSOR_COLOR 0x07
struct grub_dirty_region
{
unsigned int cursor_y;
int cursor_state;
+ /* Terminal color settings. */
+ grub_uint8_t standard_color_setting;
+ grub_uint8_t normal_color_setting;
+ grub_uint8_t highlight_color_setting;
+ grub_uint8_t term_color;
+
/* Color settings. */
- grub_video_color_t fg_color_setting;
- grub_video_color_t bg_color_setting;
grub_video_color_t fg_color;
grub_video_color_t bg_color;
grub_video_color_t cursor_color;
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 struct grub_dirty_region dirty_region;
static void dirty_region_reset (void);
static void dirty_region_add (int x, int y,
unsigned int width, unsigned int height);
+static void
+set_term_color (grub_uint8_t term_color)
+{
+ struct grub_video_render_target *old_target;
+
+ /* Save previous target and switch to text layer. */
+ grub_video_get_active_render_target (&old_target);
+ grub_video_set_active_render_target (text_layer);
+
+ /* Map terminal color to text layer compatible video colors. */
+ virtual_screen.fg_color = grub_video_map_color(term_color & 0x0f);
+
+ /* Special case: use black as transparent color. */
+ if (((term_color >> 4) & 0x0f) == 0)
+ {
+ virtual_screen.bg_color = grub_video_map_rgba(0, 0, 0, 0);
+ }
+ else
+ {
+ virtual_screen.bg_color = grub_video_map_color((term_color >> 4) & 0x0f);
+ }
+
+ /* Restore previous target. */
+ grub_video_set_active_render_target (old_target);
+}
+
static void
grub_virtual_screen_free (void)
{
we can only have those after mode is initialized. */
grub_video_set_active_render_target (text_layer);
- virtual_screen.fg_color_setting = grub_video_map_color (DEFAULT_FG_COLOR);
- virtual_screen.bg_color_setting = grub_video_map_color (DEFAULT_BG_COLOR);
- virtual_screen.fg_color = virtual_screen.fg_color_setting;
- virtual_screen.bg_color = virtual_screen.bg_color_setting;
+ virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR;
+ virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR;
+ virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR;
+
+ virtual_screen.term_color = virtual_screen.normal_color_setting;
+
+ set_term_color (virtual_screen.term_color);
+
virtual_screen.cursor_color = grub_video_map_color (DEFAULT_CURSOR_COLOR);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
/* Make sure screen is black. */
color = grub_video_map_rgb (0, 0, 0);
grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
+ bitmap = 0;
/* Leave borders for virtual screen. */
width = mode_info.width - (2 * DEFAULT_BORDER_WIDTH);
static grub_err_t
grub_gfxterm_fini (void)
{
+ if (bitmap)
+ {
+ grub_video_bitmap_destroy (bitmap);
+ bitmap = 0;
+ }
+
grub_virtual_screen_free ();
grub_video_restore ();
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
- /* Render background layer. */
- color = virtual_screen.bg_color;
- grub_video_fill_rect (color, x, y, width, height);
- /* Render text layer. */
- grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y,
- x - virtual_screen.offset_x,
- y - virtual_screen.offset_y,
- width, height);
+ if (bitmap)
+ {
+ /* Render bitmap as background. */
+ grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y,
+ x, y,
+ width, height);
+
+ /* If bitmap is smaller than requested blit area, use background
+ color. */
+ color = virtual_screen.bg_color;
+
+ /* Fill right side of the bitmap if needed. */
+ if ((x + width >= bitmap_width) && (y < bitmap_height))
+ {
+ int w = (x + width) - bitmap_width;
+ int h = height;
+ unsigned int tx = x;
+
+ if (y + height >= bitmap_height)
+ {
+ h = bitmap_height - y;
+ }
+
+ if (bitmap_width > tx)
+ {
+ tx = bitmap_width;
+ }
+
+ /* Render background layer. */
+ grub_video_fill_rect (color, tx, y, w, h);
+ }
+
+ /* Fill bottom side of the bitmap if needed. */
+ if (y + height >= bitmap_height)
+ {
+ int h = (y + height) - bitmap_height;
+ unsigned int ty = y;
+
+ if (bitmap_height > ty)
+ {
+ ty = bitmap_height;
+ }
+
+ /* Render background layer. */
+ grub_video_fill_rect (color, x, ty, width, h);
+ }
+
+ /* Render text layer as blended. */
+ grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y,
+ x - virtual_screen.offset_x,
+ y - virtual_screen.offset_y,
+ width, height);
+ }
+ else
+ {
+ /* Render background layer. */
+ color = virtual_screen.bg_color;
+ grub_video_fill_rect (color, x, y, width, height);
+
+ /* Render text layer as replaced (to get texts background color). */
+ grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_REPLACE, x, y,
+ x - virtual_screen.offset_x,
+ y - virtual_screen.offset_y,
+ width, height);
+ }
}
static void
unsigned int i;
grub_video_color_t color;
+ /* If we don't have background bitmap, remove cursor. */
+ if (!bitmap)
+ {
+ /* Remove cursor. */
+ write_char ();
+
+ /* Redraw only changed regions. */
+ dirty_region_redraw ();
+ }
+
/* Scroll text buffer with one line to up. */
grub_memmove (virtual_screen.text_buffer,
virtual_screen.text_buffer + virtual_screen.columns,
color = virtual_screen.bg_color;
grub_video_scroll (color, 0, -virtual_screen.char_height);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+ /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */
+ if (bitmap)
+ {
+ /* Mark virtual screen to be redrawn. */
+ dirty_region_add_virtualscreen ();
+ }
+ else
+ {
+ /* Clear new border area. */
+ grub_video_fill_rect (color,
+ virtual_screen.offset_x, virtual_screen.offset_y,
+ virtual_screen.width, virtual_screen.char_height);
+
+ /* Scroll physical screen. */
+ grub_video_scroll (color, 0, -virtual_screen.char_height);
- /* Mark virtual screen to be redrawn. */
- dirty_region_add_virtualscreen ();
+ /* Draw cursor if visible. */
+ if (virtual_screen.cursor_state)
+ write_cursor ();
+ }
}
static void
/* Clear text layer. */
grub_video_set_active_render_target (text_layer);
- color = virtual_screen.bg_color_setting;
+ color = virtual_screen.bg_color;
grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
switch (state)
{
case GRUB_TERM_COLOR_STANDARD:
+ virtual_screen.term_color = virtual_screen.standard_color_setting;
+ break;
+
case GRUB_TERM_COLOR_NORMAL:
- virtual_screen.fg_color = virtual_screen.fg_color_setting;
- virtual_screen.bg_color = virtual_screen.bg_color_setting;
+ virtual_screen.term_color = virtual_screen.normal_color_setting;
break;
+
case GRUB_TERM_COLOR_HIGHLIGHT:
- virtual_screen.fg_color = virtual_screen.bg_color_setting;
- virtual_screen.bg_color = virtual_screen.fg_color_setting;
+ virtual_screen.term_color = virtual_screen.highlight_color_setting;
break;
+
default:
break;
}
+
+ /* Change color to virtual terminal. */
+ set_term_color (virtual_screen.term_color);
+}
+
+static void
+grub_virtual_screen_setcolor (grub_uint8_t normal_color,
+ grub_uint8_t highlight_color)
+{
+ virtual_screen.normal_color_setting = normal_color;
+ virtual_screen.highlight_color_setting = highlight_color;
+}
+
+static void
+grub_virtual_screen_getcolor (grub_uint8_t *normal_color,
+ grub_uint8_t *highlight_color)
+{
+ *normal_color = virtual_screen.normal_color_setting;
+ *highlight_color = virtual_screen.highlight_color_setting;
}
static void
dirty_region_redraw ();
}
+static grub_err_t
+grub_gfxterm_background_image_cmd (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc,
+ char **args)
+{
+ /* 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;
+
+ /* Mark whole screen as dirty. */
+ dirty_region_reset ();
+ dirty_region_add (0, 0, mode_info.width, mode_info.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;
+
+ /* If bitmap was loaded correctly, display it. */
+ if (bitmap)
+ {
+ /* Determine bitmap dimensions. */
+ bitmap_width = grub_video_bitmap_get_width (bitmap);
+ bitmap_height = grub_video_bitmap_get_width (bitmap);
+
+ /* Mark whole screen as dirty. */
+ dirty_region_reset ();
+ dirty_region_add (0, 0, mode_info.width, mode_info.height);
+ }
+ }
+
+ /* All was ok. */
+ grub_errno = GRUB_ERR_NONE;
+ return grub_errno;
+}
+
static struct grub_term grub_video_term =
{
.name = "gfxterm",
.gotoxy = grub_gfxterm_gotoxy,
.cls = grub_gfxterm_cls,
.setcolorstate = grub_virtual_screen_setcolorstate,
+ .setcolor = grub_virtual_screen_setcolor,
+ .getcolor = grub_virtual_screen_getcolor,
.setcursor = grub_gfxterm_setcursor,
.refresh = grub_gfxterm_refresh,
.flags = 0,
{
my_mod = mod;
grub_term_register (&grub_video_term);
+
+ grub_register_command ("background_image",
+ grub_gfxterm_background_image_cmd,
+ GRUB_COMMAND_FLAG_BOTH,
+ "background_image",
+ "Load background image for active terminal",
+ 0);
}
GRUB_MOD_FINI(term_gfxterm)
{
+ grub_unregister_command ("bgimage");
grub_term_unregister (&grub_video_term);
}
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006,2007,2008 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
}
}
+grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+ struct grub_video_i386_vbeblit_info target_info;
+
+ target_info.mode_info = &render_target->mode_info;
+ target_info.data = render_target->data;
+
+ grub_video_vbe_unmap_color_int (&target_info, color, red, green, blue, alpha);
+
+ return GRUB_ERR_NONE;
+}
+
void
-grub_video_vbe_unmap_color (struct grub_video_i386_vbeblit_info * source,
- grub_video_color_t color,
- grub_uint8_t *red, grub_uint8_t *green,
- grub_uint8_t *blue, grub_uint8_t *alpha)
+grub_video_vbe_unmap_color_int (struct grub_video_i386_vbeblit_info * source,
+ grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha)
{
struct grub_video_mode_info *mode_info;
mode_info = source->mode_info;
return GRUB_ERR_NONE;
}
+static grub_err_t
+grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
+{
+ *target = render_target;
+
+ return GRUB_ERR_NONE;
+}
+
static struct grub_video_adapter grub_video_vbe_adapter =
{
.name = "VESA BIOS Extension Video Driver",
.map_color = grub_video_vbe_map_color,
.map_rgb = grub_video_vbe_map_rgb,
.map_rgba = grub_video_vbe_map_rgba,
+ .unmap_color = grub_video_vbe_unmap_color,
.fill_rect = grub_video_vbe_fill_rect,
.blit_glyph = grub_video_vbe_blit_glyph,
.blit_bitmap = grub_video_vbe_blit_bitmap,
.create_render_target = grub_video_vbe_create_render_target,
.delete_render_target = grub_video_vbe_delete_render_target,
.set_active_render_target = grub_video_vbe_set_active_render_target,
+ .get_active_render_target = grub_video_vbe_get_active_render_target,
.next = 0
};
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2008 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
continue;
}
- grub_video_vbe_unmap_color (dst, *dstptr, &dr, &dg, &db, &da);
+ grub_video_vbe_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
dr = (dr * (255 - a) + sr * a) / 255;
dg = (dg * (255 - a) + sg * a) / 255;
grub_video_color_t dst_color;
src_color = get_pixel (src, i + offset_x, j + offset_y);
- grub_video_vbe_unmap_color (src, src_color, &src_red, &src_green,
+ grub_video_vbe_unmap_color_int (src, src_color, &src_red, &src_green,
&src_blue, &src_alpha);
if (src_alpha == 0)
dst_color = get_pixel (dst, x + i, y + j);
- grub_video_vbe_unmap_color (dst, dst_color, &dst_red,
+ grub_video_vbe_unmap_color_int (dst, dst_color, &dst_red,
&dst_green, &dst_blue, &dst_alpha);
dst_red = (((src_red * src_alpha)
for (i = 0; i < width; i++)
{
src_color = get_pixel (src, i + offset_x, j + offset_y);
- grub_video_vbe_unmap_color (src, src_color, &src_red, &src_green,
+ grub_video_vbe_unmap_color_int (src, src_color, &src_red, &src_green,
&src_blue, &src_alpha);
dst_color = grub_video_vbe_map_rgba (src_red, src_green,
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2008 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
if (! grub_video_adapter_active)
return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+ /* If mode_info is NULL just report that video adapter is active. */
+ if (! mode_info)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return grub_errno;
+ }
+
return grub_video_adapter_active->get_info (mode_info);
}
return grub_video_adapter_active->map_rgba (red, green, blue, alpha);
}
+/* Unmap video color back to RGBA components. */
+grub_err_t
+grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red,
+ grub_uint8_t *green, grub_uint8_t *blue,
+ grub_uint8_t *alpha)
+{
+ if (! grub_video_adapter_active)
+ return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+ return grub_video_adapter_active->unmap_color (color,
+ red,
+ green,
+ blue,
+ alpha);
+}
+
/* Fill rectangle using specified color. */
grub_err_t
grub_video_fill_rect (grub_video_color_t color, int x, int y,
return grub_video_adapter_active->set_active_render_target (target);
}
+/* Get active render target. */
+grub_err_t
+grub_video_get_active_render_target (struct grub_video_render_target **target)
+{
+ if (! grub_video_adapter_active)
+ return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+ return grub_video_adapter_active->get_active_render_target (target);
+}
+
/* Initialize Video API module. */
GRUB_MOD_INIT(video_video)
{