* [PATCH] background_color command
@ 2010-12-10 12:39 Colin Watson
2010-12-10 17:53 ` Colin Watson
0 siblings, 1 reply; 6+ messages in thread
From: Colin Watson @ 2010-12-10 12:39 UTC (permalink / raw)
To: grub-devel
This patch adds a background_color command to gfxterm, which is useful
if you just want a simple background fill and don't want to have to
worry about scaling a background image to the right size.
2010-12-10 Colin Watson <cjwatson@ubuntu.com>
* grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New
function.
(GRUB_MOD_INIT): Register background_color command.
(GRUB_MOD_FINI): Unregister background_color command.
=== modified file 'grub-core/term/gfxterm.c'
--- grub-core/term/gfxterm.c 2010-09-14 21:06:01 +0000
+++ grub-core/term/gfxterm.c 2010-12-10 11:22:37 +0000
@@ -1180,6 +1180,76 @@ grub_gfxterm_background_image_cmd (grub_
return grub_errno;
}
+static grub_err_t
+grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ int i;
+ unsigned int j;
+ unsigned long raw_color;
+ grub_uint8_t red, green, blue;
+ grub_uint8_t *data;
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand");
+
+ /* Check that we have video adapter active. */
+ if (grub_video_get_info(NULL) != GRUB_ERR_NONE)
+ return grub_errno;
+
+ for (i = 0; i < 7 && args[0][i]; i++)
+ if ((args[0][i] < '0' || args[0][i] > '9')
+ && (args[0][i] < 'a' || args[0][i] > 'f')
+ && (args[0][i] < 'A' || args[0][i] > 'F'))
+ break;
+
+ if (i != 6)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "color `%s' is not in RRGGBB form", args[0]);
+
+ raw_color = grub_strtoul (args[0], 0, 16);
+ red = (raw_color >> 16) & 0xFF;
+ green = (raw_color >> 8) & 0xFF;
+ blue = raw_color & 0xFF;
+
+ /* 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);
+ }
+
+ /* Create a filled bitmap so that we get suitable text blending. */
+ grub_video_bitmap_create (&bitmap, window.width, window.height,
+ GRUB_VIDEO_BLIT_FORMAT_RGB_888);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
+
+ data = bitmap->data;
+ for (j = 0; j < window.height * window.width; j++)
+ {
+ *data++ = red;
+ *data++ = green;
+ *data++ = blue;
+ }
+
+ bitmap_width = window.width;
+ bitmap_height = window.height;
+
+ /* Set the border color. */
+ virtual_screen.bg_color_display = grub_video_map_rgb (red, green, blue);
+
+ /* 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 struct grub_term_output grub_video_term =
{
.name = "gfxterm",
@@ -1201,6 +1271,7 @@ static struct grub_term_output grub_vide
};
static grub_extcmd_t background_image_cmd_handle;
+static grub_command_t background_color_cmd_handle;
GRUB_MOD_INIT(gfxterm)
{
@@ -1211,10 +1282,16 @@ GRUB_MOD_INIT(gfxterm)
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_("RRGGBB"),
+ N_("Set background color for active terminal."));
}
GRUB_MOD_FINI(gfxterm)
{
+ grub_unregister_command (background_color_cmd_handle);
grub_unregister_extcmd (background_image_cmd_handle);
grub_term_unregister_output (&grub_video_term);
}
Thanks,
--
Colin Watson [cjwatson@ubuntu.com]
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] background_color command 2010-12-10 12:39 [PATCH] background_color command Colin Watson @ 2010-12-10 17:53 ` Colin Watson 2010-12-13 14:00 ` Colin Watson 2010-12-18 19:46 ` Vladimir 'φ-coder/phcoder' Serbinenko 0 siblings, 2 replies; 6+ messages in thread From: Colin Watson @ 2010-12-10 17:53 UTC (permalink / raw) To: grub-devel On Fri, Dec 10, 2010 at 12:39:42PM +0000, Colin Watson wrote: > This patch adds a background_color command to gfxterm, which is useful > if you just want a simple background fill and don't want to have to > worry about scaling a background image to the right size. > > 2010-12-10 Colin Watson <cjwatson@ubuntu.com> > > * grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New > function. > (GRUB_MOD_INIT): Register background_color command. > (GRUB_MOD_FINI): Unregister background_color command. Vladimir suggested on IRC that I should generalise the gfxmenu colour parsing code instead. Here's a patch that does this. I've pushed this to the parse-color branch here: bzr+ssh://bzr.sv.gnu.org/grub/branches/parse-color/ 2010-12-10 Colin Watson <cjwatson@ubuntu.com> Move gfxmenu color handling to video, so that gfxterm can use it too. * grub-core/gfxmenu/named_colors.c: Move to ... * grub-core/video/colors.c: ... here. Rename grub_gui_get_named_color to grub_video_get_named_color. * grub-core/gfxmenu/gui_string_util.c (my_isxdigit): Move to ... * grub-core/video/colors.c (my_isxdigit): ... here. * grub-core/gfxmenu/gui_string_util.c (parse_hex_color_component): Move to ... * grub-core/video/colors.c (parse_hex_color_component): ... here. * grub-core/gfxmenu/gui_string_util.c (grub_gui_parse_color): Move to ... * grub-core/video/colors.c (grub_video_parse_color): ... here. * include/grub/gui.h (grub_gui_color_t): Move to ... * include/grub/video.h (grub_video_rgba_color_t): ... here. * include/grub/gui.h (grub_gui_color_rgb): Move to ... * include/grub/video.h (grub_video_rgba_color_rgb): ... here. * include/grub/gui.h (grub_gui_map_color): Move to ... * include/grub/video.h (grub_video_map_rgba_color): ... here. * include/grub/gui_string_util.h (grub_gui_get_named_color): Move to ... * include/grub/video.h (grub_video_get_named_color): ... here. * include/grub/gui_string_util.h (grub_gui_parse_color): Move to ... * include/grub/video.h (grub_video_parse_color): ... here. * grub-core/Makefile.core.def (kernel) [videoinkernel]: Add video/colors.c. (gfxmenu): Remove gfxmenu/named_colors.c. (video_colors) [videomodules]: New module, containing video/colors.c. Add a background_color command. * grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New function. (GRUB_MOD_INIT): Register background_color command. (GRUB_MOD_FINI): Unregister background_color command. === modified file 'grub-core/Makefile.core.def' --- grub-core/Makefile.core.def 2010-12-01 21:42:11 +0000 +++ grub-core/Makefile.core.def 2010-12-10 15:34:05 +0000 @@ -178,6 +178,7 @@ kernel = { 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; @@ -1049,7 +1050,6 @@ module = { common = gfxmenu/gui_progress_bar.c; common = gfxmenu/gui_util.c; common = gfxmenu/gui_string_util.c; - common = gfxmenu/named_colors.c; }; module = { @@ -1443,6 +1443,12 @@ module = { }; module = { + name = video_colors; + common = video/colors.c; + enable = videomodules; +}; + +module = { name = video_fb; common = video/fb/video_fb.c; common = video/fb/fbblit.c; === modified file 'grub-core/gfxmenu/gui_label.c' --- grub-core/gfxmenu/gui_label.c 2010-05-13 01:56:14 +0000 +++ grub-core/gfxmenu/gui_label.c 2010-12-10 15:32:01 +0000 @@ -48,7 +48,7 @@ struct grub_gui_label char *text; char *template; grub_font_t font; - grub_gui_color_t color; + grub_video_rgba_color_t color; int value; enum align_mode align; }; @@ -107,7 +107,7 @@ label_paint (void *vself, const grub_vid grub_gui_set_viewport (&self->bounds, &vpsave); grub_font_draw_string (self->text, self->font, - grub_gui_map_color (self->color), + grub_video_map_rgba_color (self->color), left_x, grub_font_get_ascent (self->font)); grub_gui_restore_viewport (&vpsave); @@ -186,7 +186,7 @@ label_set_property (void *vself, const c } else if (grub_strcmp (name, "color") == 0) { - grub_gui_parse_color (value, &self->color); + grub_video_parse_color (value, &self->color); } else if (grub_strcmp (name, "align") == 0) { === modified file 'grub-core/gfxmenu/gui_list.c' --- grub-core/gfxmenu/gui_list.c 2010-10-16 20:16:52 +0000 +++ grub-core/gfxmenu/gui_list.c 2010-12-10 15:40:32 +0000 @@ -41,9 +41,9 @@ struct grub_gui_list_impl int item_spacing; grub_font_t item_font; grub_font_t selected_item_font; - grub_gui_color_t item_color; + grub_video_rgba_color_t item_color; int selected_item_color_set; - grub_gui_color_t selected_item_color; + grub_video_rgba_color_t selected_item_color; int draw_scrollbar; int need_to_recreate_scrollbar; @@ -267,13 +267,13 @@ draw_menu (list_impl_t self, int num_sho (is_selected && self->selected_item_font ? self->selected_item_font : self->item_font); - grub_gui_color_t text_color = + grub_video_rgba_color_t text_color = ((is_selected && self->selected_item_color_set) ? self->selected_item_color : self->item_color); grub_font_draw_string (item_title, font, - grub_gui_map_color (text_color), + grub_video_map_rgba_color (text_color), sel_leftpad + self->icon_width + icon_text_space, (item_top + (item_height - (ascent + descent)) / 2 + ascent)); @@ -429,7 +429,7 @@ list_set_property (void *vself, const ch } else if (grub_strcmp (name, "item_color") == 0) { - grub_gui_parse_color (value, &self->item_color); + grub_video_parse_color (value, &self->item_color); } else if (grub_strcmp (name, "selected_item_color") == 0) { @@ -439,7 +439,7 @@ list_set_property (void *vself, const ch } else { - if (grub_gui_parse_color (value, &self->selected_item_color) + if (grub_video_parse_color (value, &self->selected_item_color) == GRUB_ERR_NONE) self->selected_item_color_set = 1; } @@ -562,7 +562,7 @@ grub_gui_list_new (void) { list_impl_t self; grub_font_t default_font; - grub_gui_color_t default_fg_color; + grub_video_rgba_color_t default_fg_color; self = grub_zalloc (sizeof (*self)); if (! self) @@ -574,7 +574,7 @@ grub_gui_list_new (void) self->visible = 1; default_font = grub_font_get ("Unknown Regular 16"); - default_fg_color = grub_gui_color_rgb (0, 0, 0); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); self->icon_width = 32; self->icon_height = 32; === modified file 'grub-core/gfxmenu/gui_progress_bar.c' --- grub-core/gfxmenu/gui_progress_bar.c 2010-05-13 01:56:14 +0000 +++ grub-core/gfxmenu/gui_progress_bar.c 2010-12-10 15:31:57 +0000 @@ -40,10 +40,10 @@ struct grub_gui_progress_bar int show_text; char *template; grub_font_t font; - grub_gui_color_t text_color; - grub_gui_color_t border_color; - grub_gui_color_t bg_color; - grub_gui_color_t fg_color; + grub_video_rgba_color_t text_color; + grub_video_rgba_color_t border_color; + grub_video_rgba_color_t bg_color; + grub_video_rgba_color_t fg_color; char *theme_dir; int need_to_recreate_pixmaps; @@ -109,7 +109,7 @@ draw_filled_rect_bar (grub_gui_progress_ f.height = self->bounds.height - 2; /* Border. */ - grub_video_fill_rect (grub_gui_map_color (self->border_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->border_color), f.x - 1, f.y - 1, f.width + 2, f.height + 2); @@ -117,12 +117,12 @@ draw_filled_rect_bar (grub_gui_progress_ int barwidth = (f.width * (self->value - self->start) / (self->end - self->start)); - grub_video_fill_rect (grub_gui_map_color (self->bg_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->bg_color), f.x + barwidth, f.y, f.width - barwidth, f.height); /* Bar foreground. */ - grub_video_fill_rect (grub_gui_map_color (self->fg_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->fg_color), f.x, f.y, barwidth, f.height); } @@ -161,7 +161,8 @@ draw_text (grub_gui_progress_bar_t self) if (self->template) { grub_font_t font = self->font; - grub_video_color_t text_color = grub_gui_map_color (self->text_color); + grub_video_color_t text_color = + grub_video_map_rgba_color (self->text_color); int width = self->bounds.width; int height = self->bounds.height; char *text; @@ -298,19 +299,19 @@ progress_bar_set_property (void *vself, } else if (grub_strcmp (name, "text_color") == 0) { - grub_gui_parse_color (value, &self->text_color); + grub_video_parse_color (value, &self->text_color); } else if (grub_strcmp (name, "border_color") == 0) { - grub_gui_parse_color (value, &self->border_color); + grub_video_parse_color (value, &self->border_color); } else if (grub_strcmp (name, "bg_color") == 0) { - grub_gui_parse_color (value, &self->bg_color); + grub_video_parse_color (value, &self->bg_color); } else if (grub_strcmp (name, "fg_color") == 0) { - grub_gui_parse_color (value, &self->fg_color); + grub_video_parse_color (value, &self->fg_color); } else if (grub_strcmp (name, "bar_style") == 0) { @@ -379,9 +380,9 @@ grub_gui_progress_bar_new (void) self->progress.component.ops = &progress_bar_ops; self->visible = 1; self->font = grub_font_get ("Unknown Regular 16"); - grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; - grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; - grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; + grub_video_rgba_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; + grub_video_rgba_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; + grub_video_rgba_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; self->text_color = black; self->border_color = black; self->bg_color = gray; === modified file 'grub-core/gfxmenu/gui_string_util.c' --- grub-core/gfxmenu/gui_string_util.c 2009-12-29 16:31:02 +0000 +++ grub-core/gfxmenu/gui_string_util.c 2010-12-10 15:30:31 +0000 @@ -204,124 +204,3 @@ grub_get_dirname (const char *file_path) return grub_new_substring (file_path, 0, last_slash + 1); } - -static __inline int -my_isxdigit (char c) -{ - return ((c >= '0' && c <= '9') - || (c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F')); -} - -static int -parse_hex_color_component (const char *s, unsigned start, unsigned end) -{ - unsigned len; - char buf[3]; - - len = end - start; - /* Check the limits so we don't overrun the buffer. */ - if (len < 1 || len > 2) - return 0; - - if (len == 1) - { - buf[0] = s[start]; /* Get the first and only hex digit. */ - buf[1] = buf[0]; /* Duplicate the hex digit. */ - } - else if (len == 2) - { - buf[0] = s[start]; - buf[1] = s[start + 1]; - } - - buf[2] = '\0'; - - return grub_strtoul (buf, 0, 16); -} - -/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", - "#RRGGBB", or "#RRGGBBAA". */ -grub_err_t -grub_gui_parse_color (const char *s, grub_gui_color_t *color) -{ - grub_gui_color_t c; - - /* Skip whitespace. */ - while (*s && grub_isspace (*s)) - s++; - - if (*s == '#') - { - /* HTML-style. Number if hex digits: - [6] #RRGGBB [3] #RGB - [8] #RRGGBBAA [4] #RGBA */ - - s++; /* Skip the '#'. */ - /* Count the hexits to determine the format. */ - int hexits = 0; - const char *end = s; - while (my_isxdigit (*end)) - { - end++; - hexits++; - } - - /* Parse the color components based on the format. */ - if (hexits == 3 || hexits == 4) - { - c.red = parse_hex_color_component (s, 0, 1); - c.green = parse_hex_color_component (s, 1, 2); - c.blue = parse_hex_color_component (s, 2, 3); - if (hexits == 4) - c.alpha = parse_hex_color_component (s, 3, 4); - else - c.alpha = 255; - } - else if (hexits == 6 || hexits == 8) - { - c.red = parse_hex_color_component (s, 0, 2); - c.green = parse_hex_color_component (s, 2, 4); - c.blue = parse_hex_color_component (s, 4, 6); - if (hexits == 8) - c.alpha = parse_hex_color_component (s, 6, 8); - else - c.alpha = 255; - } - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid HTML-type color string `%s'", s); - } - else if (grub_isdigit (*s)) - { - /* Comma separated decimal values. */ - c.red = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing 1st comma separator in color `%s'", s); - s++; - c.green = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing 2nd comma separator in color `%s'", s); - s++; - c.blue = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - c.alpha = 255; - else - { - s++; - c.alpha = grub_strtoul (s, 0, 0); - } - } - else - { - if (! grub_gui_get_named_color (s, &c)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid named color `%s'", s); - } - - if (grub_errno == GRUB_ERR_NONE) - *color = c; - return grub_errno; -} === modified file 'grub-core/gfxmenu/theme_loader.c' --- grub-core/gfxmenu/theme_loader.c 2010-01-05 20:06:27 +0000 +++ grub-core/gfxmenu/theme_loader.c 2010-12-10 15:32:00 +0000 @@ -135,11 +135,11 @@ theme_set_string (grub_gfxmenu_view_t vi return grub_errno; } else if (! grub_strcmp ("title-color", name)) - grub_gui_parse_color (value, &view->title_color); + grub_video_parse_color (value, &view->title_color); else if (! grub_strcmp ("message-color", name)) - grub_gui_parse_color (value, &view->message_color); + grub_video_parse_color (value, &view->message_color); else if (! grub_strcmp ("message-bg-color", name)) - grub_gui_parse_color (value, &view->message_bg_color); + grub_video_parse_color (value, &view->message_bg_color); else if (! grub_strcmp ("desktop-image", name)) { struct grub_video_bitmap *raw_bitmap; @@ -170,7 +170,7 @@ theme_set_string (grub_gfxmenu_view_t vi view->desktop_image = scaled_bitmap; } else if (! grub_strcmp ("desktop-color", name)) - grub_gui_parse_color (value, &view->desktop_color); + grub_video_parse_color (value, &view->desktop_color); else if (! grub_strcmp ("terminal-box", name)) { grub_err_t err; === modified file 'grub-core/gfxmenu/view.c' --- grub-core/gfxmenu/view.c 2010-10-16 20:16:52 +0000 +++ grub-core/gfxmenu/view.c 2010-12-10 15:29:48 +0000 @@ -50,8 +50,8 @@ grub_gfxmenu_view_new (const char *theme { grub_gfxmenu_view_t view; grub_font_t default_font; - grub_gui_color_t default_fg_color; - grub_gui_color_t default_bg_color; + grub_video_rgba_color_t default_fg_color; + grub_video_rgba_color_t default_bg_color; view = grub_malloc (sizeof (*view)); if (! view) @@ -63,8 +63,8 @@ grub_gfxmenu_view_new (const char *theme view->screen.height = height; default_font = grub_font_get ("Unknown Regular 16"); - default_fg_color = grub_gui_color_rgb (0, 0, 0); - default_bg_color = grub_gui_color_rgb (255, 255, 255); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); + default_bg_color = grub_video_rgba_color_rgb (255, 255, 255); view->canvas = 0; @@ -131,7 +131,7 @@ redraw_background (grub_gfxmenu_view_t v } else { - grub_video_fill_rect (grub_gui_map_color (view->desktop_color), + grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color), bounds->x, bounds->y, bounds->width, bounds->height); } @@ -150,7 +150,7 @@ draw_title (grub_gfxmenu_view_t view) int y = 40 + grub_font_get_ascent (view->title_font); grub_font_draw_string (view->title_text, view->title_font, - grub_gui_map_color (view->title_color), + grub_video_map_rgba_color (view->title_color), x, y); } @@ -244,13 +244,13 @@ draw_message (grub_gfxmenu_view_t view) return; grub_font_t font = view->message_font; - grub_video_color_t color = grub_gui_map_color (view->message_color); + grub_video_color_t color = grub_video_map_rgba_color (view->message_color); /* Border. */ grub_video_fill_rect (color, f.x-1, f.y-1, f.width+2, f.height+2); /* Fill. */ - grub_video_fill_rect (grub_gui_map_color (view->message_bg_color), + grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color), f.x, f.y, f.width, f.height); /* Center the text. */ === modified file 'grub-core/term/gfxterm.c' --- grub-core/term/gfxterm.c 2010-09-14 21:06:01 +0000 +++ grub-core/term/gfxterm.c 2010-12-10 17:37:47 +0000 @@ -1180,6 +1180,62 @@ grub_gfxterm_background_image_cmd (grub_ return grub_errno; } +static grub_err_t +grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + grub_video_rgba_color_t color; + grub_uint8_t *data; + unsigned int i; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); + + /* 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], &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); + } + + /* Create a filled bitmap so that we get suitable text blending. */ + grub_video_bitmap_create (&bitmap, window.width, window.height, + GRUB_VIDEO_BLIT_FORMAT_RGB_888); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + data = bitmap->data; + for (i = 0; i < window.height * window.width; i++) + { + *data++ = color.red; + *data++ = color.green; + *data++ = color.blue; + } + + bitmap_width = window.width; + bitmap_height = window.height; + + /* Set the border color. */ + virtual_screen.bg_color_display = grub_video_map_rgba_color (color); + + /* 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 struct grub_term_output grub_video_term = { .name = "gfxterm", @@ -1201,6 +1257,7 @@ static struct grub_term_output grub_vide }; static grub_extcmd_t background_image_cmd_handle; +static grub_command_t background_color_cmd_handle; GRUB_MOD_INIT(gfxterm) { @@ -1211,10 +1268,16 @@ GRUB_MOD_INIT(gfxterm) 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) { + grub_unregister_command (background_color_cmd_handle); grub_unregister_extcmd (background_image_cmd_handle); grub_term_unregister_output (&grub_video_term); } === renamed file 'grub-core/gfxmenu/named_colors.c' => 'grub-core/video/colors.c' --- grub-core/gfxmenu/named_colors.c 2009-11-20 15:02:58 +0000 +++ grub-core/video/colors.c 2010-12-10 15:31:32 +0000 @@ -25,7 +25,7 @@ struct named_color { const char *name; - grub_gui_color_t color; + grub_video_rgba_color_t color; }; /* @@ -193,8 +193,8 @@ static struct named_color named_colors[] stores the color into *COLOR. If the color was not found, returns 0 and does not modify *COLOR. */ int -grub_gui_get_named_color (const char *name, - grub_gui_color_t *color) +grub_video_get_named_color (const char *name, + grub_video_rgba_color_t *color) { int i; for (i = 0; named_colors[i].name; i++) @@ -207,3 +207,124 @@ grub_gui_get_named_color (const char *na } return 0; } + +static __inline int +my_isxdigit (char c) +{ + return ((c >= '0' && c <= '9') + || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')); +} + +static int +parse_hex_color_component (const char *s, unsigned start, unsigned end) +{ + unsigned len; + char buf[3]; + + len = end - start; + /* Check the limits so we don't overrun the buffer. */ + if (len < 1 || len > 2) + return 0; + + if (len == 1) + { + buf[0] = s[start]; /* Get the first and only hex digit. */ + buf[1] = buf[0]; /* Duplicate the hex digit. */ + } + else if (len == 2) + { + buf[0] = s[start]; + buf[1] = s[start + 1]; + } + + buf[2] = '\0'; + + return grub_strtoul (buf, 0, 16); +} + +/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", + "#RRGGBB", or "#RRGGBBAA". */ +grub_err_t +grub_video_parse_color (const char *s, grub_video_rgba_color_t *color) +{ + grub_video_rgba_color_t c; + + /* Skip whitespace. */ + while (*s && grub_isspace (*s)) + s++; + + if (*s == '#') + { + /* HTML-style. Number if hex digits: + [6] #RRGGBB [3] #RGB + [8] #RRGGBBAA [4] #RGBA */ + + s++; /* Skip the '#'. */ + /* Count the hexits to determine the format. */ + int hexits = 0; + const char *end = s; + while (my_isxdigit (*end)) + { + end++; + hexits++; + } + + /* Parse the color components based on the format. */ + if (hexits == 3 || hexits == 4) + { + c.red = parse_hex_color_component (s, 0, 1); + c.green = parse_hex_color_component (s, 1, 2); + c.blue = parse_hex_color_component (s, 2, 3); + if (hexits == 4) + c.alpha = parse_hex_color_component (s, 3, 4); + else + c.alpha = 255; + } + else if (hexits == 6 || hexits == 8) + { + c.red = parse_hex_color_component (s, 0, 2); + c.green = parse_hex_color_component (s, 2, 4); + c.blue = parse_hex_color_component (s, 4, 6); + if (hexits == 8) + c.alpha = parse_hex_color_component (s, 6, 8); + else + c.alpha = 255; + } + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid HTML-type color string `%s'", s); + } + else if (grub_isdigit (*s)) + { + /* Comma separated decimal values. */ + c.red = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 1st comma separator in color `%s'", s); + s++; + c.green = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 2nd comma separator in color `%s'", s); + s++; + c.blue = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + c.alpha = 255; + else + { + s++; + c.alpha = grub_strtoul (s, 0, 0); + } + } + else + { + if (! grub_video_get_named_color (s, &c)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid named color `%s'", s); + } + + if (grub_errno == GRUB_ERR_NONE) + *color = c; + return grub_errno; +} === modified file 'include/grub/gfxmenu_view.h' --- include/grub/gfxmenu_view.h 2010-03-23 17:17:54 +0000 +++ include/grub/gfxmenu_view.h 2010-12-10 15:28:54 +0000 @@ -87,11 +87,11 @@ struct grub_gfxmenu_view grub_font_t title_font; grub_font_t message_font; char *terminal_font_name; - grub_gui_color_t title_color; - grub_gui_color_t message_color; - grub_gui_color_t message_bg_color; + grub_video_rgba_color_t title_color; + grub_video_rgba_color_t message_color; + grub_video_rgba_color_t message_bg_color; struct grub_video_bitmap *desktop_image; - grub_gui_color_t desktop_color; + grub_video_rgba_color_t desktop_color; grub_gfxmenu_box_t terminal_box; char *title_text; char *progress_message_text; === modified file 'include/grub/gui.h' --- include/grub/gui.h 2010-05-13 01:56:14 +0000 +++ include/grub/gui.h 2010-12-10 15:27:20 +0000 @@ -31,16 +31,6 @@ status changes. */ #define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" -/* A representation of a color. Unlike grub_video_color_t, this - representation is independent of any video mode specifics. */ -typedef struct grub_gui_color -{ - grub_uint8_t red; - grub_uint8_t green; - grub_uint8_t blue; - grub_uint8_t alpha; -} grub_gui_color_t; - typedef struct grub_gui_component *grub_gui_component_t; typedef struct grub_gui_container *grub_gui_container_t; typedef struct grub_gui_list *grub_gui_list_t; @@ -242,23 +232,6 @@ grub_gui_set_viewport (const grub_video_ r->height); } -static __inline grub_gui_color_t -grub_gui_color_rgb (int r, int g, int b) -{ - grub_gui_color_t c; - c.red = r; - c.green = g; - c.blue = b; - c.alpha = 255; - return c; -} - -static __inline grub_video_color_t -grub_gui_map_color (grub_gui_color_t c) -{ - return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); -} - static inline int grub_video_have_common_points (const grub_video_rect_t *a, const grub_video_rect_t *b) === modified file 'include/grub/gui_string_util.h' --- include/grub/gui_string_util.h 2009-12-29 16:31:02 +0000 +++ include/grub/gui_string_util.h 2010-12-10 15:25:37 +0000 @@ -30,8 +30,4 @@ char *grub_resolve_relative_path (const char *grub_get_dirname (const char *file_path); -int grub_gui_get_named_color (const char *name, grub_gui_color_t *color); - -grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color); - #endif /* GRUB_GUI_STRING_UTIL_HEADER */ === modified file 'include/grub/video.h' --- include/grub/video.h 2010-09-12 00:09:09 +0000 +++ include/grub/video.h 2010-12-10 15:35:07 +0000 @@ -27,6 +27,15 @@ specific coding format. */ typedef grub_uint32_t grub_video_color_t; +/* Video color in hardware independent format. */ +typedef struct grub_video_rgba_color +{ + grub_uint8_t red; + grub_uint8_t green; + grub_uint8_t blue; + grub_uint8_t alpha; +} grub_video_rgba_color_t; + /* This structure is driver specific and should not be accessed directly by outside code. */ struct grub_video_render_target; @@ -428,4 +437,27 @@ grub_video_check_mode_flag (grub_video_m grub_video_driver_id_t EXPORT_FUNC (grub_video_get_driver_id) (void); +static __inline grub_video_rgba_color_t +grub_video_rgba_color_rgb (int r, int g, int b) +{ + grub_video_rgba_color_t c; + c.red = r; + c.green = g; + c.blue = b; + c.alpha = 255; + return c; +} + +static __inline grub_video_color_t +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); + #endif /* ! GRUB_VIDEO_HEADER */ Thanks, -- Colin Watson [cjwatson@ubuntu.com] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] background_color command 2010-12-10 17:53 ` Colin Watson @ 2010-12-13 14:00 ` Colin Watson 2010-12-18 19:46 ` Vladimir 'φ-coder/phcoder' Serbinenko 1 sibling, 0 replies; 6+ messages in thread From: Colin Watson @ 2010-12-13 14:00 UTC (permalink / raw) To: grub-devel On Fri, Dec 10, 2010 at 05:53:42PM +0000, Colin Watson wrote: > Vladimir suggested on IRC that I should generalise the gfxmenu colour > parsing code instead. Here's a patch that does this. I've pushed this > to the parse-color branch here: > > bzr+ssh://bzr.sv.gnu.org/grub/branches/parse-color/ I applied an additional change on top of this, also pushed to that branch. This means that this sequence in grub.cfg works as intended: terminal_output gfxterm background_color 44,0,30 === modified file 'ChangeLog.parse-color' --- ChangeLog.parse-color 2010-12-10 17:47:38 +0000 +++ ChangeLog.parse-color 2010-12-13 13:58:53 +0000 @@ -39,3 +39,9 @@ function. (GRUB_MOD_INIT): Register background_color command. (GRUB_MOD_FINI): Unregister background_color command. + + Fix border repainting. + + * grub-core/term/gfxterm.c (dirty_region_add): When a repaint is + already scheduled, merge the virtual screen with the requested + region rather than repainting only the virtual screen. === modified file 'grub-core/term/gfxterm.c' --- grub-core/term/gfxterm.c 2010-12-10 17:47:38 +0000 +++ grub-core/term/gfxterm.c 2010-12-13 13:58:53 +0000 @@ -539,10 +539,20 @@ dirty_region_add (int x, int y, unsigned if (repaint_scheduled) { - x = virtual_screen.offset_x; - y = virtual_screen.offset_y; - width = virtual_screen.width; - height = virtual_screen.height; + if (x > (int)virtual_screen.offset_x) + { + width += virtual_screen.offset_x - x; + x = virtual_screen.offset_x; + } + if (y > (int)virtual_screen.offset_y) + { + height += virtual_screen.offset_y - y; + y = virtual_screen.offset_y; + } + if (width < virtual_screen.width) + width = virtual_screen.width; + if (height < virtual_screen.height) + height = virtual_screen.height; repaint_scheduled = 0; repaint_was_scheduled = 1; } -- Colin Watson [cjwatson@ubuntu.com] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] background_color command 2010-12-10 17:53 ` Colin Watson 2010-12-13 14:00 ` Colin Watson @ 2010-12-18 19:46 ` Vladimir 'φ-coder/phcoder' Serbinenko 2010-12-23 12:21 ` Colin Watson 1 sibling, 1 reply; 6+ messages in thread From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-12-18 19:46 UTC (permalink / raw) To: grub-devel [-- Attachment #1: Type: text/plain, Size: 1769 bytes --] On 12/10/2010 06:53 PM, Colin Watson wrote: > > module = { > + name = video_colors; > + common = video/colors.c; > + enable = videomodules; > +}; > Both main users of video (gfxmenu and gfxterm) use color routines. So I feel like video/colors.c can go into video.mod > > + /* Create a filled bitmap so that we get suitable text blending. */ > + grub_video_bitmap_create (&bitmap, window.width, window.height, > + GRUB_VIDEO_BLIT_FORMAT_RGB_888); > + if (grub_errno != GRUB_ERR_NONE) > + return grub_errno; > You should check the return value and not grub_errno. > + > It would be more optimal if in this case the image would be saved simply as the color rather than a filled array and use grub_video_fill_rect when this image is supposed to be blitted. also it would be neat to be able to specify the bgcolor around non-stretched image. > + data = bitmap->data; > + for (i = 0; i < window.height * window.width; i++) > + { > + *data++ = color.red; > + *data++ = color.green; > + *data++ = color.blue; > + } > + > grub_video_fill_rect is the function for such kind of operations. > + bitmap_width = window.width; > + bitmap_height = window.height; > + > + /* Set the border color. */ > + virtual_screen.bg_color_display = grub_video_map_rgba_color (color); > + > + /* Mark whole screen as dirty. */ > + dirty_region_add (0, 0, window.width, window.height); > + > + /* All was ok. */ > + grub_errno = GRUB_ERR_NONE; > You shouldn't discard grub_errno manually unless there is an error you want to ignore. > + return grub_errno; > I'd rather use return GRUB_ERR_NONE; -- Regards Vladimir 'φ-coder/phcoder' Serbinenko [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 294 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] background_color command 2010-12-18 19:46 ` Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-12-23 12:21 ` Colin Watson 2010-12-25 11:26 ` Vladimir 'φ-coder/phcoder' Serbinenko 0 siblings, 1 reply; 6+ messages in thread From: Colin Watson @ 2010-12-23 12:21 UTC (permalink / raw) To: The development of GNU GRUB On Sat, Dec 18, 2010 at 08:46:46PM +0100, Vladimir 'φ-coder/phcoder' Serbinenko wrote: > On 12/10/2010 06:53 PM, Colin Watson wrote: > > module = { > > + name = video_colors; > > + common = video/colors.c; > > + enable = videomodules; > > +}; > > Both main users of video (gfxmenu and gfxterm) use color routines. So I > feel like video/colors.c can go into video.mod Fixed. > > + /* Create a filled bitmap so that we get suitable text blending. */ > > + grub_video_bitmap_create (&bitmap, window.width, window.height, > > + GRUB_VIDEO_BLIT_FORMAT_RGB_888); > > + if (grub_errno != GRUB_ERR_NONE) > > + return grub_errno; > > > You should check the return value and not grub_errno. > > + > > > It would be more optimal if in this case the image would be saved simply > as the color rather than a filled array and use grub_video_fill_rect > when this image is supposed to be blitted. also it would be neat to be > able to specify the bgcolor around non-stretched image. > > + data = bitmap->data; > > + for (i = 0; i < window.height * window.width; i++) > > + { > > + *data++ = color.red; > > + *data++ = color.green; > > + *data++ = color.blue; > > + } > > + > > > grub_video_fill_rect is the function for such kind of operations. This was all fixed in r2981 on the parse-color branch, which now just sets virtual_screen.bg_color and virtual_screen.bg_color_display and handles that appropriately. > > + /* All was ok. */ > > + grub_errno = GRUB_ERR_NONE; > > > You shouldn't discard grub_errno manually unless there is an error you > want to ignore. > > + return grub_errno; > > > I'd rather use return GRUB_ERR_NONE; Fixed. Updated patch follows: 2010-12-23 Colin Watson <cjwatson@ubuntu.com> Move gfxmenu color handling to video, so that gfxterm can use it too. * grub-core/gfxmenu/named_colors.c: Move to ... * grub-core/video/colors.c: ... here. Rename grub_gui_get_named_color to grub_video_get_named_color. * grub-core/gfxmenu/gui_string_util.c (my_isxdigit): Move to ... * grub-core/video/colors.c (my_isxdigit): ... here. * grub-core/gfxmenu/gui_string_util.c (parse_hex_color_component): Move to ... * grub-core/video/colors.c (parse_hex_color_component): ... here. * grub-core/gfxmenu/gui_string_util.c (grub_gui_parse_color): Move to ... * grub-core/video/colors.c (grub_video_parse_color): ... here. * include/grub/gui.h (grub_gui_color_t): Move to ... * include/grub/video.h (grub_video_rgba_color_t): ... here. * include/grub/gui.h (grub_gui_color_rgb): Move to ... * include/grub/video.h (grub_video_rgba_color_rgb): ... here. * include/grub/gui.h (grub_gui_map_color): Move to ... * include/grub/video.h (grub_video_map_rgba_color): ... here. * include/grub/gui_string_util.h (grub_gui_get_named_color): Move to ... * include/grub/video.h (grub_video_get_named_color): ... here. * include/grub/gui_string_util.h (grub_gui_parse_color): Move to ... * include/grub/video.h (grub_video_parse_color): ... here. * grub-core/Makefile.core.def (kernel) [videoinkernel]: Add video/colors.c. (gfxmenu): Remove gfxmenu/named_colors.c. (video) [videomodules]: Add video/colors.c. Add a background_color command. * grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New function. (GRUB_MOD_INIT): Register background_color command. (GRUB_MOD_FINI): Unregister background_color command. (redraw_screen_rect): Allow blend/replace of text layer to be controlled independently from whether there is a background bitmap. (grub_gfxterm_fullscreen): Change blend_text_bg when changing bitmap. (destroy_window): Likewise. (grub_gfxterm_background_image_cmd): Likewise. Fix border repainting. * grub-core/term/gfxterm.c (dirty_region_add): When a repaint is already scheduled, merge the virtual screen with the requested region rather than repainting only the virtual screen. === modified file 'grub-core/Makefile.core.def' --- grub-core/Makefile.core.def 2010-12-01 21:42:11 +0000 +++ grub-core/Makefile.core.def 2010-12-23 12:10:37 +0000 @@ -178,6 +178,7 @@ kernel = { 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; @@ -1049,7 +1050,6 @@ module = { common = gfxmenu/gui_progress_bar.c; common = gfxmenu/gui_util.c; common = gfxmenu/gui_string_util.c; - common = gfxmenu/named_colors.c; }; module = { @@ -1454,6 +1454,7 @@ module = { module = { name = video; common = video/video.c; + common = video/colors.c; enable = videomodules; }; === modified file 'grub-core/gfxmenu/gui_label.c' --- grub-core/gfxmenu/gui_label.c 2010-05-13 01:56:14 +0000 +++ grub-core/gfxmenu/gui_label.c 2010-12-10 15:32:01 +0000 @@ -48,7 +48,7 @@ struct grub_gui_label char *text; char *template; grub_font_t font; - grub_gui_color_t color; + grub_video_rgba_color_t color; int value; enum align_mode align; }; @@ -107,7 +107,7 @@ label_paint (void *vself, const grub_vid grub_gui_set_viewport (&self->bounds, &vpsave); grub_font_draw_string (self->text, self->font, - grub_gui_map_color (self->color), + grub_video_map_rgba_color (self->color), left_x, grub_font_get_ascent (self->font)); grub_gui_restore_viewport (&vpsave); @@ -186,7 +186,7 @@ label_set_property (void *vself, const c } else if (grub_strcmp (name, "color") == 0) { - grub_gui_parse_color (value, &self->color); + grub_video_parse_color (value, &self->color); } else if (grub_strcmp (name, "align") == 0) { === modified file 'grub-core/gfxmenu/gui_list.c' --- grub-core/gfxmenu/gui_list.c 2010-10-16 20:16:52 +0000 +++ grub-core/gfxmenu/gui_list.c 2010-12-10 15:40:32 +0000 @@ -41,9 +41,9 @@ struct grub_gui_list_impl int item_spacing; grub_font_t item_font; grub_font_t selected_item_font; - grub_gui_color_t item_color; + grub_video_rgba_color_t item_color; int selected_item_color_set; - grub_gui_color_t selected_item_color; + grub_video_rgba_color_t selected_item_color; int draw_scrollbar; int need_to_recreate_scrollbar; @@ -267,13 +267,13 @@ draw_menu (list_impl_t self, int num_sho (is_selected && self->selected_item_font ? self->selected_item_font : self->item_font); - grub_gui_color_t text_color = + grub_video_rgba_color_t text_color = ((is_selected && self->selected_item_color_set) ? self->selected_item_color : self->item_color); grub_font_draw_string (item_title, font, - grub_gui_map_color (text_color), + grub_video_map_rgba_color (text_color), sel_leftpad + self->icon_width + icon_text_space, (item_top + (item_height - (ascent + descent)) / 2 + ascent)); @@ -429,7 +429,7 @@ list_set_property (void *vself, const ch } else if (grub_strcmp (name, "item_color") == 0) { - grub_gui_parse_color (value, &self->item_color); + grub_video_parse_color (value, &self->item_color); } else if (grub_strcmp (name, "selected_item_color") == 0) { @@ -439,7 +439,7 @@ list_set_property (void *vself, const ch } else { - if (grub_gui_parse_color (value, &self->selected_item_color) + if (grub_video_parse_color (value, &self->selected_item_color) == GRUB_ERR_NONE) self->selected_item_color_set = 1; } @@ -562,7 +562,7 @@ grub_gui_list_new (void) { list_impl_t self; grub_font_t default_font; - grub_gui_color_t default_fg_color; + grub_video_rgba_color_t default_fg_color; self = grub_zalloc (sizeof (*self)); if (! self) @@ -574,7 +574,7 @@ grub_gui_list_new (void) self->visible = 1; default_font = grub_font_get ("Unknown Regular 16"); - default_fg_color = grub_gui_color_rgb (0, 0, 0); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); self->icon_width = 32; self->icon_height = 32; === modified file 'grub-core/gfxmenu/gui_progress_bar.c' --- grub-core/gfxmenu/gui_progress_bar.c 2010-05-13 01:56:14 +0000 +++ grub-core/gfxmenu/gui_progress_bar.c 2010-12-10 15:31:57 +0000 @@ -40,10 +40,10 @@ struct grub_gui_progress_bar int show_text; char *template; grub_font_t font; - grub_gui_color_t text_color; - grub_gui_color_t border_color; - grub_gui_color_t bg_color; - grub_gui_color_t fg_color; + grub_video_rgba_color_t text_color; + grub_video_rgba_color_t border_color; + grub_video_rgba_color_t bg_color; + grub_video_rgba_color_t fg_color; char *theme_dir; int need_to_recreate_pixmaps; @@ -109,7 +109,7 @@ draw_filled_rect_bar (grub_gui_progress_ f.height = self->bounds.height - 2; /* Border. */ - grub_video_fill_rect (grub_gui_map_color (self->border_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->border_color), f.x - 1, f.y - 1, f.width + 2, f.height + 2); @@ -117,12 +117,12 @@ draw_filled_rect_bar (grub_gui_progress_ int barwidth = (f.width * (self->value - self->start) / (self->end - self->start)); - grub_video_fill_rect (grub_gui_map_color (self->bg_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->bg_color), f.x + barwidth, f.y, f.width - barwidth, f.height); /* Bar foreground. */ - grub_video_fill_rect (grub_gui_map_color (self->fg_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->fg_color), f.x, f.y, barwidth, f.height); } @@ -161,7 +161,8 @@ draw_text (grub_gui_progress_bar_t self) if (self->template) { grub_font_t font = self->font; - grub_video_color_t text_color = grub_gui_map_color (self->text_color); + grub_video_color_t text_color = + grub_video_map_rgba_color (self->text_color); int width = self->bounds.width; int height = self->bounds.height; char *text; @@ -298,19 +299,19 @@ progress_bar_set_property (void *vself, } else if (grub_strcmp (name, "text_color") == 0) { - grub_gui_parse_color (value, &self->text_color); + grub_video_parse_color (value, &self->text_color); } else if (grub_strcmp (name, "border_color") == 0) { - grub_gui_parse_color (value, &self->border_color); + grub_video_parse_color (value, &self->border_color); } else if (grub_strcmp (name, "bg_color") == 0) { - grub_gui_parse_color (value, &self->bg_color); + grub_video_parse_color (value, &self->bg_color); } else if (grub_strcmp (name, "fg_color") == 0) { - grub_gui_parse_color (value, &self->fg_color); + grub_video_parse_color (value, &self->fg_color); } else if (grub_strcmp (name, "bar_style") == 0) { @@ -379,9 +380,9 @@ grub_gui_progress_bar_new (void) self->progress.component.ops = &progress_bar_ops; self->visible = 1; self->font = grub_font_get ("Unknown Regular 16"); - grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; - grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; - grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; + grub_video_rgba_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; + grub_video_rgba_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; + grub_video_rgba_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; self->text_color = black; self->border_color = black; self->bg_color = gray; === modified file 'grub-core/gfxmenu/gui_string_util.c' --- grub-core/gfxmenu/gui_string_util.c 2009-12-29 16:31:02 +0000 +++ grub-core/gfxmenu/gui_string_util.c 2010-12-10 15:30:31 +0000 @@ -204,124 +204,3 @@ grub_get_dirname (const char *file_path) return grub_new_substring (file_path, 0, last_slash + 1); } - -static __inline int -my_isxdigit (char c) -{ - return ((c >= '0' && c <= '9') - || (c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F')); -} - -static int -parse_hex_color_component (const char *s, unsigned start, unsigned end) -{ - unsigned len; - char buf[3]; - - len = end - start; - /* Check the limits so we don't overrun the buffer. */ - if (len < 1 || len > 2) - return 0; - - if (len == 1) - { - buf[0] = s[start]; /* Get the first and only hex digit. */ - buf[1] = buf[0]; /* Duplicate the hex digit. */ - } - else if (len == 2) - { - buf[0] = s[start]; - buf[1] = s[start + 1]; - } - - buf[2] = '\0'; - - return grub_strtoul (buf, 0, 16); -} - -/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", - "#RRGGBB", or "#RRGGBBAA". */ -grub_err_t -grub_gui_parse_color (const char *s, grub_gui_color_t *color) -{ - grub_gui_color_t c; - - /* Skip whitespace. */ - while (*s && grub_isspace (*s)) - s++; - - if (*s == '#') - { - /* HTML-style. Number if hex digits: - [6] #RRGGBB [3] #RGB - [8] #RRGGBBAA [4] #RGBA */ - - s++; /* Skip the '#'. */ - /* Count the hexits to determine the format. */ - int hexits = 0; - const char *end = s; - while (my_isxdigit (*end)) - { - end++; - hexits++; - } - - /* Parse the color components based on the format. */ - if (hexits == 3 || hexits == 4) - { - c.red = parse_hex_color_component (s, 0, 1); - c.green = parse_hex_color_component (s, 1, 2); - c.blue = parse_hex_color_component (s, 2, 3); - if (hexits == 4) - c.alpha = parse_hex_color_component (s, 3, 4); - else - c.alpha = 255; - } - else if (hexits == 6 || hexits == 8) - { - c.red = parse_hex_color_component (s, 0, 2); - c.green = parse_hex_color_component (s, 2, 4); - c.blue = parse_hex_color_component (s, 4, 6); - if (hexits == 8) - c.alpha = parse_hex_color_component (s, 6, 8); - else - c.alpha = 255; - } - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid HTML-type color string `%s'", s); - } - else if (grub_isdigit (*s)) - { - /* Comma separated decimal values. */ - c.red = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing 1st comma separator in color `%s'", s); - s++; - c.green = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing 2nd comma separator in color `%s'", s); - s++; - c.blue = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - c.alpha = 255; - else - { - s++; - c.alpha = grub_strtoul (s, 0, 0); - } - } - else - { - if (! grub_gui_get_named_color (s, &c)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid named color `%s'", s); - } - - if (grub_errno == GRUB_ERR_NONE) - *color = c; - return grub_errno; -} === modified file 'grub-core/gfxmenu/theme_loader.c' --- grub-core/gfxmenu/theme_loader.c 2010-01-05 20:06:27 +0000 +++ grub-core/gfxmenu/theme_loader.c 2010-12-10 15:32:00 +0000 @@ -135,11 +135,11 @@ theme_set_string (grub_gfxmenu_view_t vi return grub_errno; } else if (! grub_strcmp ("title-color", name)) - grub_gui_parse_color (value, &view->title_color); + grub_video_parse_color (value, &view->title_color); else if (! grub_strcmp ("message-color", name)) - grub_gui_parse_color (value, &view->message_color); + grub_video_parse_color (value, &view->message_color); else if (! grub_strcmp ("message-bg-color", name)) - grub_gui_parse_color (value, &view->message_bg_color); + grub_video_parse_color (value, &view->message_bg_color); else if (! grub_strcmp ("desktop-image", name)) { struct grub_video_bitmap *raw_bitmap; @@ -170,7 +170,7 @@ theme_set_string (grub_gfxmenu_view_t vi view->desktop_image = scaled_bitmap; } else if (! grub_strcmp ("desktop-color", name)) - grub_gui_parse_color (value, &view->desktop_color); + grub_video_parse_color (value, &view->desktop_color); else if (! grub_strcmp ("terminal-box", name)) { grub_err_t err; === modified file 'grub-core/gfxmenu/view.c' --- grub-core/gfxmenu/view.c 2010-10-16 20:16:52 +0000 +++ grub-core/gfxmenu/view.c 2010-12-10 15:29:48 +0000 @@ -50,8 +50,8 @@ grub_gfxmenu_view_new (const char *theme { grub_gfxmenu_view_t view; grub_font_t default_font; - grub_gui_color_t default_fg_color; - grub_gui_color_t default_bg_color; + grub_video_rgba_color_t default_fg_color; + grub_video_rgba_color_t default_bg_color; view = grub_malloc (sizeof (*view)); if (! view) @@ -63,8 +63,8 @@ grub_gfxmenu_view_new (const char *theme view->screen.height = height; default_font = grub_font_get ("Unknown Regular 16"); - default_fg_color = grub_gui_color_rgb (0, 0, 0); - default_bg_color = grub_gui_color_rgb (255, 255, 255); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); + default_bg_color = grub_video_rgba_color_rgb (255, 255, 255); view->canvas = 0; @@ -131,7 +131,7 @@ redraw_background (grub_gfxmenu_view_t v } else { - grub_video_fill_rect (grub_gui_map_color (view->desktop_color), + grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color), bounds->x, bounds->y, bounds->width, bounds->height); } @@ -150,7 +150,7 @@ draw_title (grub_gfxmenu_view_t view) int y = 40 + grub_font_get_ascent (view->title_font); grub_font_draw_string (view->title_text, view->title_font, - grub_gui_map_color (view->title_color), + grub_video_map_rgba_color (view->title_color), x, y); } @@ -244,13 +244,13 @@ draw_message (grub_gfxmenu_view_t view) return; grub_font_t font = view->message_font; - grub_video_color_t color = grub_gui_map_color (view->message_color); + grub_video_color_t color = grub_video_map_rgba_color (view->message_color); /* Border. */ grub_video_fill_rect (color, f.x-1, f.y-1, f.width+2, f.height+2); /* Fill. */ - grub_video_fill_rect (grub_gui_map_color (view->message_bg_color), + grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color), f.x, f.y, f.width, f.height); /* Center the text. */ === modified file 'grub-core/term/gfxterm.c' --- grub-core/term/gfxterm.c 2010-09-14 21:06:01 +0000 +++ grub-core/term/gfxterm.c 2010-12-23 12:15:40 +0000 @@ -128,6 +128,7 @@ static struct grub_video_render_target * static unsigned int bitmap_width; static unsigned int bitmap_height; static struct grub_video_bitmap *bitmap; +static int blend_text_bg; static struct grub_dirty_region dirty_region; @@ -344,6 +345,7 @@ grub_gfxterm_fullscreen (void) grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); } bitmap = 0; + blend_text_bg = 0; /* Select the font to use. */ font_name = grub_env_get ("gfxterm_font"); @@ -396,6 +398,7 @@ destroy_window (void) { grub_video_bitmap_destroy (bitmap); bitmap = 0; + blend_text_bg = 0; } repaint_callback = 0; @@ -481,26 +484,27 @@ redraw_screen_rect (unsigned int x, unsi /* 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_display; 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); } + if (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, + y - virtual_screen.offset_y, + width, height); + else + /* 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); + /* Restore saved viewport. */ grub_video_set_viewport (saved_view.x, saved_view.y, saved_view.width, saved_view.height); @@ -539,10 +543,20 @@ dirty_region_add (int x, int y, unsigned if (repaint_scheduled) { - x = virtual_screen.offset_x; - y = virtual_screen.offset_y; - width = virtual_screen.width; - height = virtual_screen.height; + if (x > (int)virtual_screen.offset_x) + { + width += virtual_screen.offset_x - x; + x = virtual_screen.offset_x; + } + if (y > (int)virtual_screen.offset_y) + { + height += virtual_screen.offset_y - y; + y = virtual_screen.offset_y; + } + if (width < virtual_screen.width) + width = virtual_screen.width; + if (height < virtual_screen.height) + height = virtual_screen.height; repaint_scheduled = 0; repaint_was_scheduled = 1; } @@ -1127,6 +1141,7 @@ grub_gfxterm_background_image_cmd (grub_ { 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); @@ -1159,6 +1174,7 @@ grub_gfxterm_background_image_cmd (grub_ /* Replace the original bitmap with the scaled one. */ grub_video_bitmap_destroy (bitmap); bitmap = scaled_bitmap; + blend_text_bg = 1; } } } @@ -1180,6 +1196,48 @@ grub_gfxterm_background_image_cmd (grub_ return grub_errno; } +static grub_err_t +grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + grub_video_rgba_color_t color; + struct grub_video_render_target *old_target; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); + + /* 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], &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 (color); + grub_video_set_active_render_target (old_target); + virtual_screen.bg_color_display = grub_video_map_rgba_color (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", @@ -1201,6 +1259,7 @@ static struct grub_term_output grub_vide }; static grub_extcmd_t background_image_cmd_handle; +static grub_command_t background_color_cmd_handle; GRUB_MOD_INIT(gfxterm) { @@ -1211,10 +1270,16 @@ GRUB_MOD_INIT(gfxterm) 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) { + grub_unregister_command (background_color_cmd_handle); grub_unregister_extcmd (background_image_cmd_handle); grub_term_unregister_output (&grub_video_term); } === renamed file 'grub-core/gfxmenu/named_colors.c' => 'grub-core/video/colors.c' --- grub-core/gfxmenu/named_colors.c 2009-11-20 15:02:58 +0000 +++ grub-core/video/colors.c 2010-12-10 15:31:32 +0000 @@ -25,7 +25,7 @@ struct named_color { const char *name; - grub_gui_color_t color; + grub_video_rgba_color_t color; }; /* @@ -193,8 +193,8 @@ static struct named_color named_colors[] stores the color into *COLOR. If the color was not found, returns 0 and does not modify *COLOR. */ int -grub_gui_get_named_color (const char *name, - grub_gui_color_t *color) +grub_video_get_named_color (const char *name, + grub_video_rgba_color_t *color) { int i; for (i = 0; named_colors[i].name; i++) @@ -207,3 +207,124 @@ grub_gui_get_named_color (const char *na } return 0; } + +static __inline int +my_isxdigit (char c) +{ + return ((c >= '0' && c <= '9') + || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')); +} + +static int +parse_hex_color_component (const char *s, unsigned start, unsigned end) +{ + unsigned len; + char buf[3]; + + len = end - start; + /* Check the limits so we don't overrun the buffer. */ + if (len < 1 || len > 2) + return 0; + + if (len == 1) + { + buf[0] = s[start]; /* Get the first and only hex digit. */ + buf[1] = buf[0]; /* Duplicate the hex digit. */ + } + else if (len == 2) + { + buf[0] = s[start]; + buf[1] = s[start + 1]; + } + + buf[2] = '\0'; + + return grub_strtoul (buf, 0, 16); +} + +/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", + "#RRGGBB", or "#RRGGBBAA". */ +grub_err_t +grub_video_parse_color (const char *s, grub_video_rgba_color_t *color) +{ + grub_video_rgba_color_t c; + + /* Skip whitespace. */ + while (*s && grub_isspace (*s)) + s++; + + if (*s == '#') + { + /* HTML-style. Number if hex digits: + [6] #RRGGBB [3] #RGB + [8] #RRGGBBAA [4] #RGBA */ + + s++; /* Skip the '#'. */ + /* Count the hexits to determine the format. */ + int hexits = 0; + const char *end = s; + while (my_isxdigit (*end)) + { + end++; + hexits++; + } + + /* Parse the color components based on the format. */ + if (hexits == 3 || hexits == 4) + { + c.red = parse_hex_color_component (s, 0, 1); + c.green = parse_hex_color_component (s, 1, 2); + c.blue = parse_hex_color_component (s, 2, 3); + if (hexits == 4) + c.alpha = parse_hex_color_component (s, 3, 4); + else + c.alpha = 255; + } + else if (hexits == 6 || hexits == 8) + { + c.red = parse_hex_color_component (s, 0, 2); + c.green = parse_hex_color_component (s, 2, 4); + c.blue = parse_hex_color_component (s, 4, 6); + if (hexits == 8) + c.alpha = parse_hex_color_component (s, 6, 8); + else + c.alpha = 255; + } + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid HTML-type color string `%s'", s); + } + else if (grub_isdigit (*s)) + { + /* Comma separated decimal values. */ + c.red = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 1st comma separator in color `%s'", s); + s++; + c.green = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 2nd comma separator in color `%s'", s); + s++; + c.blue = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + c.alpha = 255; + else + { + s++; + c.alpha = grub_strtoul (s, 0, 0); + } + } + else + { + if (! grub_video_get_named_color (s, &c)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid named color `%s'", s); + } + + if (grub_errno == GRUB_ERR_NONE) + *color = c; + return grub_errno; +} === modified file 'include/grub/gfxmenu_view.h' --- include/grub/gfxmenu_view.h 2010-03-23 17:17:54 +0000 +++ include/grub/gfxmenu_view.h 2010-12-10 15:28:54 +0000 @@ -87,11 +87,11 @@ struct grub_gfxmenu_view grub_font_t title_font; grub_font_t message_font; char *terminal_font_name; - grub_gui_color_t title_color; - grub_gui_color_t message_color; - grub_gui_color_t message_bg_color; + grub_video_rgba_color_t title_color; + grub_video_rgba_color_t message_color; + grub_video_rgba_color_t message_bg_color; struct grub_video_bitmap *desktop_image; - grub_gui_color_t desktop_color; + grub_video_rgba_color_t desktop_color; grub_gfxmenu_box_t terminal_box; char *title_text; char *progress_message_text; === modified file 'include/grub/gui.h' --- include/grub/gui.h 2010-05-13 01:56:14 +0000 +++ include/grub/gui.h 2010-12-10 15:27:20 +0000 @@ -31,16 +31,6 @@ status changes. */ #define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" -/* A representation of a color. Unlike grub_video_color_t, this - representation is independent of any video mode specifics. */ -typedef struct grub_gui_color -{ - grub_uint8_t red; - grub_uint8_t green; - grub_uint8_t blue; - grub_uint8_t alpha; -} grub_gui_color_t; - typedef struct grub_gui_component *grub_gui_component_t; typedef struct grub_gui_container *grub_gui_container_t; typedef struct grub_gui_list *grub_gui_list_t; @@ -242,23 +232,6 @@ grub_gui_set_viewport (const grub_video_ r->height); } -static __inline grub_gui_color_t -grub_gui_color_rgb (int r, int g, int b) -{ - grub_gui_color_t c; - c.red = r; - c.green = g; - c.blue = b; - c.alpha = 255; - return c; -} - -static __inline grub_video_color_t -grub_gui_map_color (grub_gui_color_t c) -{ - return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); -} - static inline int grub_video_have_common_points (const grub_video_rect_t *a, const grub_video_rect_t *b) === modified file 'include/grub/gui_string_util.h' --- include/grub/gui_string_util.h 2009-12-29 16:31:02 +0000 +++ include/grub/gui_string_util.h 2010-12-10 15:25:37 +0000 @@ -30,8 +30,4 @@ char *grub_resolve_relative_path (const char *grub_get_dirname (const char *file_path); -int grub_gui_get_named_color (const char *name, grub_gui_color_t *color); - -grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color); - #endif /* GRUB_GUI_STRING_UTIL_HEADER */ === modified file 'include/grub/video.h' --- include/grub/video.h 2010-09-12 00:09:09 +0000 +++ include/grub/video.h 2010-12-10 15:35:07 +0000 @@ -27,6 +27,15 @@ specific coding format. */ typedef grub_uint32_t grub_video_color_t; +/* Video color in hardware independent format. */ +typedef struct grub_video_rgba_color +{ + grub_uint8_t red; + grub_uint8_t green; + grub_uint8_t blue; + grub_uint8_t alpha; +} grub_video_rgba_color_t; + /* This structure is driver specific and should not be accessed directly by outside code. */ struct grub_video_render_target; @@ -428,4 +437,27 @@ grub_video_check_mode_flag (grub_video_m grub_video_driver_id_t EXPORT_FUNC (grub_video_get_driver_id) (void); +static __inline grub_video_rgba_color_t +grub_video_rgba_color_rgb (int r, int g, int b) +{ + grub_video_rgba_color_t c; + c.red = r; + c.green = g; + c.blue = b; + c.alpha = 255; + return c; +} + +static __inline grub_video_color_t +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); + #endif /* ! GRUB_VIDEO_HEADER */ Thanks, -- Colin Watson [cjwatson@ubuntu.com] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] background_color command 2010-12-23 12:21 ` Colin Watson @ 2010-12-25 11:26 ` Vladimir 'φ-coder/phcoder' Serbinenko 0 siblings, 0 replies; 6+ messages in thread From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-12-25 11:26 UTC (permalink / raw) To: grub-devel [-- Attachment #1: Type: text/plain, Size: 36880 bytes --] Go ahead for experimental On 12/23/2010 01:21 PM, Colin Watson wrote: > On Sat, Dec 18, 2010 at 08:46:46PM +0100, Vladimir 'φ-coder/phcoder' Serbinenko wrote: > >> On 12/10/2010 06:53 PM, Colin Watson wrote: >> >>> module = { >>> + name = video_colors; >>> + common = video/colors.c; >>> + enable = videomodules; >>> +}; >>> >> Both main users of video (gfxmenu and gfxterm) use color routines. So I >> feel like video/colors.c can go into video.mod >> > Fixed. > > >>> + /* Create a filled bitmap so that we get suitable text blending. */ >>> + grub_video_bitmap_create (&bitmap, window.width, window.height, >>> + GRUB_VIDEO_BLIT_FORMAT_RGB_888); >>> + if (grub_errno != GRUB_ERR_NONE) >>> + return grub_errno; >>> >>> >> You should check the return value and not grub_errno. >> >>> + >>> >>> >> It would be more optimal if in this case the image would be saved simply >> as the color rather than a filled array and use grub_video_fill_rect >> when this image is supposed to be blitted. also it would be neat to be >> able to specify the bgcolor around non-stretched image. >> >>> + data = bitmap->data; >>> + for (i = 0; i < window.height * window.width; i++) >>> + { >>> + *data++ = color.red; >>> + *data++ = color.green; >>> + *data++ = color.blue; >>> + } >>> + >>> >>> >> grub_video_fill_rect is the function for such kind of operations. >> > This was all fixed in r2981 on the parse-color branch, which now just > sets virtual_screen.bg_color and virtual_screen.bg_color_display and > handles that appropriately. > > >>> + /* All was ok. */ >>> + grub_errno = GRUB_ERR_NONE; >>> >>> >> You shouldn't discard grub_errno manually unless there is an error you >> want to ignore. >> >>> + return grub_errno; >>> >>> >> I'd rather use return GRUB_ERR_NONE; >> > Fixed. > > Updated patch follows: > > 2010-12-23 Colin Watson <cjwatson@ubuntu.com> > > Move gfxmenu color handling to video, so that gfxterm can use it > too. > > * grub-core/gfxmenu/named_colors.c: Move to ... > * grub-core/video/colors.c: ... here. Rename > grub_gui_get_named_color to grub_video_get_named_color. > * grub-core/gfxmenu/gui_string_util.c (my_isxdigit): Move to ... > * grub-core/video/colors.c (my_isxdigit): ... here. > * grub-core/gfxmenu/gui_string_util.c (parse_hex_color_component): > Move to ... > * grub-core/video/colors.c (parse_hex_color_component): ... here. > * grub-core/gfxmenu/gui_string_util.c (grub_gui_parse_color): Move > to ... > * grub-core/video/colors.c (grub_video_parse_color): ... here. > > * include/grub/gui.h (grub_gui_color_t): Move to ... > * include/grub/video.h (grub_video_rgba_color_t): ... here. > * include/grub/gui.h (grub_gui_color_rgb): Move to ... > * include/grub/video.h (grub_video_rgba_color_rgb): ... here. > * include/grub/gui.h (grub_gui_map_color): Move to ... > * include/grub/video.h (grub_video_map_rgba_color): ... here. > * include/grub/gui_string_util.h (grub_gui_get_named_color): Move > to ... > * include/grub/video.h (grub_video_get_named_color): ... here. > * include/grub/gui_string_util.h (grub_gui_parse_color): Move to ... > * include/grub/video.h (grub_video_parse_color): ... here. > > * grub-core/Makefile.core.def (kernel) [videoinkernel]: Add > video/colors.c. > (gfxmenu): Remove gfxmenu/named_colors.c. > (video) [videomodules]: Add video/colors.c. > > Add a background_color command. > > * grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New > function. > (GRUB_MOD_INIT): Register background_color command. > (GRUB_MOD_FINI): Unregister background_color command. > (redraw_screen_rect): Allow blend/replace of text layer to be > controlled independently from whether there is a background bitmap. > (grub_gfxterm_fullscreen): Change blend_text_bg when changing > bitmap. > (destroy_window): Likewise. > (grub_gfxterm_background_image_cmd): Likewise. > > Fix border repainting. > > * grub-core/term/gfxterm.c (dirty_region_add): When a repaint is > already scheduled, merge the virtual screen with the requested > region rather than repainting only the virtual screen. > > === modified file 'grub-core/Makefile.core.def' > --- grub-core/Makefile.core.def 2010-12-01 21:42:11 +0000 > +++ grub-core/Makefile.core.def 2010-12-23 12:10:37 +0000 > @@ -178,6 +178,7 @@ kernel = { > 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; > @@ -1049,7 +1050,6 @@ module = { > common = gfxmenu/gui_progress_bar.c; > common = gfxmenu/gui_util.c; > common = gfxmenu/gui_string_util.c; > - common = gfxmenu/named_colors.c; > }; > > module = { > @@ -1454,6 +1454,7 @@ module = { > module = { > name = video; > common = video/video.c; > + common = video/colors.c; > enable = videomodules; > }; > > > === modified file 'grub-core/gfxmenu/gui_label.c' > --- grub-core/gfxmenu/gui_label.c 2010-05-13 01:56:14 +0000 > +++ grub-core/gfxmenu/gui_label.c 2010-12-10 15:32:01 +0000 > @@ -48,7 +48,7 @@ struct grub_gui_label > char *text; > char *template; > grub_font_t font; > - grub_gui_color_t color; > + grub_video_rgba_color_t color; > int value; > enum align_mode align; > }; > @@ -107,7 +107,7 @@ label_paint (void *vself, const grub_vid > grub_gui_set_viewport (&self->bounds, &vpsave); > grub_font_draw_string (self->text, > self->font, > - grub_gui_map_color (self->color), > + grub_video_map_rgba_color (self->color), > left_x, > grub_font_get_ascent (self->font)); > grub_gui_restore_viewport (&vpsave); > @@ -186,7 +186,7 @@ label_set_property (void *vself, const c > } > else if (grub_strcmp (name, "color") == 0) > { > - grub_gui_parse_color (value, &self->color); > + grub_video_parse_color (value, &self->color); > } > else if (grub_strcmp (name, "align") == 0) > { > > === modified file 'grub-core/gfxmenu/gui_list.c' > --- grub-core/gfxmenu/gui_list.c 2010-10-16 20:16:52 +0000 > +++ grub-core/gfxmenu/gui_list.c 2010-12-10 15:40:32 +0000 > @@ -41,9 +41,9 @@ struct grub_gui_list_impl > int item_spacing; > grub_font_t item_font; > grub_font_t selected_item_font; > - grub_gui_color_t item_color; > + grub_video_rgba_color_t item_color; > int selected_item_color_set; > - grub_gui_color_t selected_item_color; > + grub_video_rgba_color_t selected_item_color; > > int draw_scrollbar; > int need_to_recreate_scrollbar; > @@ -267,13 +267,13 @@ draw_menu (list_impl_t self, int num_sho > (is_selected && self->selected_item_font > ? self->selected_item_font > : self->item_font); > - grub_gui_color_t text_color = > + grub_video_rgba_color_t text_color = > ((is_selected && self->selected_item_color_set) > ? self->selected_item_color > : self->item_color); > grub_font_draw_string (item_title, > font, > - grub_gui_map_color (text_color), > + grub_video_map_rgba_color (text_color), > sel_leftpad + self->icon_width + icon_text_space, > (item_top + (item_height - (ascent + descent)) > / 2 + ascent)); > @@ -429,7 +429,7 @@ list_set_property (void *vself, const ch > } > else if (grub_strcmp (name, "item_color") == 0) > { > - grub_gui_parse_color (value, &self->item_color); > + grub_video_parse_color (value, &self->item_color); > } > else if (grub_strcmp (name, "selected_item_color") == 0) > { > @@ -439,7 +439,7 @@ list_set_property (void *vself, const ch > } > else > { > - if (grub_gui_parse_color (value, &self->selected_item_color) > + if (grub_video_parse_color (value, &self->selected_item_color) > == GRUB_ERR_NONE) > self->selected_item_color_set = 1; > } > @@ -562,7 +562,7 @@ grub_gui_list_new (void) > { > list_impl_t self; > grub_font_t default_font; > - grub_gui_color_t default_fg_color; > + grub_video_rgba_color_t default_fg_color; > > self = grub_zalloc (sizeof (*self)); > if (! self) > @@ -574,7 +574,7 @@ grub_gui_list_new (void) > self->visible = 1; > > default_font = grub_font_get ("Unknown Regular 16"); > - default_fg_color = grub_gui_color_rgb (0, 0, 0); > + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); > > self->icon_width = 32; > self->icon_height = 32; > > === modified file 'grub-core/gfxmenu/gui_progress_bar.c' > --- grub-core/gfxmenu/gui_progress_bar.c 2010-05-13 01:56:14 +0000 > +++ grub-core/gfxmenu/gui_progress_bar.c 2010-12-10 15:31:57 +0000 > @@ -40,10 +40,10 @@ struct grub_gui_progress_bar > int show_text; > char *template; > grub_font_t font; > - grub_gui_color_t text_color; > - grub_gui_color_t border_color; > - grub_gui_color_t bg_color; > - grub_gui_color_t fg_color; > + grub_video_rgba_color_t text_color; > + grub_video_rgba_color_t border_color; > + grub_video_rgba_color_t bg_color; > + grub_video_rgba_color_t fg_color; > > char *theme_dir; > int need_to_recreate_pixmaps; > @@ -109,7 +109,7 @@ draw_filled_rect_bar (grub_gui_progress_ > f.height = self->bounds.height - 2; > > /* Border. */ > - grub_video_fill_rect (grub_gui_map_color (self->border_color), > + grub_video_fill_rect (grub_video_map_rgba_color (self->border_color), > f.x - 1, f.y - 1, > f.width + 2, f.height + 2); > > @@ -117,12 +117,12 @@ draw_filled_rect_bar (grub_gui_progress_ > int barwidth = (f.width > * (self->value - self->start) > / (self->end - self->start)); > - grub_video_fill_rect (grub_gui_map_color (self->bg_color), > + grub_video_fill_rect (grub_video_map_rgba_color (self->bg_color), > f.x + barwidth, f.y, > f.width - barwidth, f.height); > > /* Bar foreground. */ > - grub_video_fill_rect (grub_gui_map_color (self->fg_color), > + grub_video_fill_rect (grub_video_map_rgba_color (self->fg_color), > f.x, f.y, > barwidth, f.height); > } > @@ -161,7 +161,8 @@ draw_text (grub_gui_progress_bar_t self) > if (self->template) > { > grub_font_t font = self->font; > - grub_video_color_t text_color = grub_gui_map_color (self->text_color); > + grub_video_color_t text_color = > + grub_video_map_rgba_color (self->text_color); > int width = self->bounds.width; > int height = self->bounds.height; > char *text; > @@ -298,19 +299,19 @@ progress_bar_set_property (void *vself, > } > else if (grub_strcmp (name, "text_color") == 0) > { > - grub_gui_parse_color (value, &self->text_color); > + grub_video_parse_color (value, &self->text_color); > } > else if (grub_strcmp (name, "border_color") == 0) > { > - grub_gui_parse_color (value, &self->border_color); > + grub_video_parse_color (value, &self->border_color); > } > else if (grub_strcmp (name, "bg_color") == 0) > { > - grub_gui_parse_color (value, &self->bg_color); > + grub_video_parse_color (value, &self->bg_color); > } > else if (grub_strcmp (name, "fg_color") == 0) > { > - grub_gui_parse_color (value, &self->fg_color); > + grub_video_parse_color (value, &self->fg_color); > } > else if (grub_strcmp (name, "bar_style") == 0) > { > @@ -379,9 +380,9 @@ grub_gui_progress_bar_new (void) > self->progress.component.ops = &progress_bar_ops; > self->visible = 1; > self->font = grub_font_get ("Unknown Regular 16"); > - grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; > - grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; > - grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; > + grub_video_rgba_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; > + grub_video_rgba_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; > + grub_video_rgba_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; > self->text_color = black; > self->border_color = black; > self->bg_color = gray; > > === modified file 'grub-core/gfxmenu/gui_string_util.c' > --- grub-core/gfxmenu/gui_string_util.c 2009-12-29 16:31:02 +0000 > +++ grub-core/gfxmenu/gui_string_util.c 2010-12-10 15:30:31 +0000 > @@ -204,124 +204,3 @@ grub_get_dirname (const char *file_path) > > return grub_new_substring (file_path, 0, last_slash + 1); > } > - > -static __inline int > -my_isxdigit (char c) > -{ > - return ((c >= '0' && c <= '9') > - || (c >= 'a' && c <= 'f') > - || (c >= 'A' && c <= 'F')); > -} > - > -static int > -parse_hex_color_component (const char *s, unsigned start, unsigned end) > -{ > - unsigned len; > - char buf[3]; > - > - len = end - start; > - /* Check the limits so we don't overrun the buffer. */ > - if (len < 1 || len > 2) > - return 0; > - > - if (len == 1) > - { > - buf[0] = s[start]; /* Get the first and only hex digit. */ > - buf[1] = buf[0]; /* Duplicate the hex digit. */ > - } > - else if (len == 2) > - { > - buf[0] = s[start]; > - buf[1] = s[start + 1]; > - } > - > - buf[2] = '\0'; > - > - return grub_strtoul (buf, 0, 16); > -} > - > -/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", > - "#RRGGBB", or "#RRGGBBAA". */ > -grub_err_t > -grub_gui_parse_color (const char *s, grub_gui_color_t *color) > -{ > - grub_gui_color_t c; > - > - /* Skip whitespace. */ > - while (*s && grub_isspace (*s)) > - s++; > - > - if (*s == '#') > - { > - /* HTML-style. Number if hex digits: > - [6] #RRGGBB [3] #RGB > - [8] #RRGGBBAA [4] #RGBA */ > - > - s++; /* Skip the '#'. */ > - /* Count the hexits to determine the format. */ > - int hexits = 0; > - const char *end = s; > - while (my_isxdigit (*end)) > - { > - end++; > - hexits++; > - } > - > - /* Parse the color components based on the format. */ > - if (hexits == 3 || hexits == 4) > - { > - c.red = parse_hex_color_component (s, 0, 1); > - c.green = parse_hex_color_component (s, 1, 2); > - c.blue = parse_hex_color_component (s, 2, 3); > - if (hexits == 4) > - c.alpha = parse_hex_color_component (s, 3, 4); > - else > - c.alpha = 255; > - } > - else if (hexits == 6 || hexits == 8) > - { > - c.red = parse_hex_color_component (s, 0, 2); > - c.green = parse_hex_color_component (s, 2, 4); > - c.blue = parse_hex_color_component (s, 4, 6); > - if (hexits == 8) > - c.alpha = parse_hex_color_component (s, 6, 8); > - else > - c.alpha = 255; > - } > - else > - return grub_error (GRUB_ERR_BAD_ARGUMENT, > - "invalid HTML-type color string `%s'", s); > - } > - else if (grub_isdigit (*s)) > - { > - /* Comma separated decimal values. */ > - c.red = grub_strtoul (s, 0, 0); > - if ((s = grub_strchr (s, ',')) == 0) > - return grub_error (GRUB_ERR_BAD_ARGUMENT, > - "missing 1st comma separator in color `%s'", s); > - s++; > - c.green = grub_strtoul (s, 0, 0); > - if ((s = grub_strchr (s, ',')) == 0) > - return grub_error (GRUB_ERR_BAD_ARGUMENT, > - "missing 2nd comma separator in color `%s'", s); > - s++; > - c.blue = grub_strtoul (s, 0, 0); > - if ((s = grub_strchr (s, ',')) == 0) > - c.alpha = 255; > - else > - { > - s++; > - c.alpha = grub_strtoul (s, 0, 0); > - } > - } > - else > - { > - if (! grub_gui_get_named_color (s, &c)) > - return grub_error (GRUB_ERR_BAD_ARGUMENT, > - "invalid named color `%s'", s); > - } > - > - if (grub_errno == GRUB_ERR_NONE) > - *color = c; > - return grub_errno; > -} > > === modified file 'grub-core/gfxmenu/theme_loader.c' > --- grub-core/gfxmenu/theme_loader.c 2010-01-05 20:06:27 +0000 > +++ grub-core/gfxmenu/theme_loader.c 2010-12-10 15:32:00 +0000 > @@ -135,11 +135,11 @@ theme_set_string (grub_gfxmenu_view_t vi > return grub_errno; > } > else if (! grub_strcmp ("title-color", name)) > - grub_gui_parse_color (value, &view->title_color); > + grub_video_parse_color (value, &view->title_color); > else if (! grub_strcmp ("message-color", name)) > - grub_gui_parse_color (value, &view->message_color); > + grub_video_parse_color (value, &view->message_color); > else if (! grub_strcmp ("message-bg-color", name)) > - grub_gui_parse_color (value, &view->message_bg_color); > + grub_video_parse_color (value, &view->message_bg_color); > else if (! grub_strcmp ("desktop-image", name)) > { > struct grub_video_bitmap *raw_bitmap; > @@ -170,7 +170,7 @@ theme_set_string (grub_gfxmenu_view_t vi > view->desktop_image = scaled_bitmap; > } > else if (! grub_strcmp ("desktop-color", name)) > - grub_gui_parse_color (value, &view->desktop_color); > + grub_video_parse_color (value, &view->desktop_color); > else if (! grub_strcmp ("terminal-box", name)) > { > grub_err_t err; > > === modified file 'grub-core/gfxmenu/view.c' > --- grub-core/gfxmenu/view.c 2010-10-16 20:16:52 +0000 > +++ grub-core/gfxmenu/view.c 2010-12-10 15:29:48 +0000 > @@ -50,8 +50,8 @@ grub_gfxmenu_view_new (const char *theme > { > grub_gfxmenu_view_t view; > grub_font_t default_font; > - grub_gui_color_t default_fg_color; > - grub_gui_color_t default_bg_color; > + grub_video_rgba_color_t default_fg_color; > + grub_video_rgba_color_t default_bg_color; > > view = grub_malloc (sizeof (*view)); > if (! view) > @@ -63,8 +63,8 @@ grub_gfxmenu_view_new (const char *theme > view->screen.height = height; > > default_font = grub_font_get ("Unknown Regular 16"); > - default_fg_color = grub_gui_color_rgb (0, 0, 0); > - default_bg_color = grub_gui_color_rgb (255, 255, 255); > + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); > + default_bg_color = grub_video_rgba_color_rgb (255, 255, 255); > > view->canvas = 0; > > @@ -131,7 +131,7 @@ redraw_background (grub_gfxmenu_view_t v > } > else > { > - grub_video_fill_rect (grub_gui_map_color (view->desktop_color), > + grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color), > bounds->x, bounds->y, > bounds->width, bounds->height); > } > @@ -150,7 +150,7 @@ draw_title (grub_gfxmenu_view_t view) > int y = 40 + grub_font_get_ascent (view->title_font); > grub_font_draw_string (view->title_text, > view->title_font, > - grub_gui_map_color (view->title_color), > + grub_video_map_rgba_color (view->title_color), > x, y); > } > > @@ -244,13 +244,13 @@ draw_message (grub_gfxmenu_view_t view) > return; > > grub_font_t font = view->message_font; > - grub_video_color_t color = grub_gui_map_color (view->message_color); > + grub_video_color_t color = grub_video_map_rgba_color (view->message_color); > > /* Border. */ > grub_video_fill_rect (color, > f.x-1, f.y-1, f.width+2, f.height+2); > /* Fill. */ > - grub_video_fill_rect (grub_gui_map_color (view->message_bg_color), > + grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color), > f.x, f.y, f.width, f.height); > > /* Center the text. */ > > === modified file 'grub-core/term/gfxterm.c' > --- grub-core/term/gfxterm.c 2010-09-14 21:06:01 +0000 > +++ grub-core/term/gfxterm.c 2010-12-23 12:15:40 +0000 > @@ -128,6 +128,7 @@ static struct grub_video_render_target * > static unsigned int bitmap_width; > static unsigned int bitmap_height; > static struct grub_video_bitmap *bitmap; > +static int blend_text_bg; > > static struct grub_dirty_region dirty_region; > > @@ -344,6 +345,7 @@ grub_gfxterm_fullscreen (void) > grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); > } > bitmap = 0; > + blend_text_bg = 0; > > /* Select the font to use. */ > font_name = grub_env_get ("gfxterm_font"); > @@ -396,6 +398,7 @@ destroy_window (void) > { > grub_video_bitmap_destroy (bitmap); > bitmap = 0; > + blend_text_bg = 0; > } > > repaint_callback = 0; > @@ -481,26 +484,27 @@ redraw_screen_rect (unsigned int x, unsi > /* 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_display; > 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); > } > > + if (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, > + y - virtual_screen.offset_y, > + width, height); > + else > + /* 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); > + > /* Restore saved viewport. */ > grub_video_set_viewport (saved_view.x, saved_view.y, > saved_view.width, saved_view.height); > @@ -539,10 +543,20 @@ dirty_region_add (int x, int y, unsigned > > if (repaint_scheduled) > { > - x = virtual_screen.offset_x; > - y = virtual_screen.offset_y; > - width = virtual_screen.width; > - height = virtual_screen.height; > + if (x > (int)virtual_screen.offset_x) > + { > + width += virtual_screen.offset_x - x; > + x = virtual_screen.offset_x; > + } > + if (y > (int)virtual_screen.offset_y) > + { > + height += virtual_screen.offset_y - y; > + y = virtual_screen.offset_y; > + } > + if (width < virtual_screen.width) > + width = virtual_screen.width; > + if (height < virtual_screen.height) > + height = virtual_screen.height; > repaint_scheduled = 0; > repaint_was_scheduled = 1; > } > @@ -1127,6 +1141,7 @@ grub_gfxterm_background_image_cmd (grub_ > { > 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); > @@ -1159,6 +1174,7 @@ grub_gfxterm_background_image_cmd (grub_ > /* Replace the original bitmap with the scaled one. */ > grub_video_bitmap_destroy (bitmap); > bitmap = scaled_bitmap; > + blend_text_bg = 1; > } > } > } > @@ -1180,6 +1196,48 @@ grub_gfxterm_background_image_cmd (grub_ > return grub_errno; > } > > +static grub_err_t > +grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), > + int argc, char **args) > +{ > + grub_video_rgba_color_t color; > + struct grub_video_render_target *old_target; > + > + if (argc != 1) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); > + > + /* 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], &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 (color); > + grub_video_set_active_render_target (old_target); > + virtual_screen.bg_color_display = grub_video_map_rgba_color (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", > @@ -1201,6 +1259,7 @@ static struct grub_term_output grub_vide > }; > > static grub_extcmd_t background_image_cmd_handle; > +static grub_command_t background_color_cmd_handle; > > GRUB_MOD_INIT(gfxterm) > { > @@ -1211,10 +1270,16 @@ GRUB_MOD_INIT(gfxterm) > 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) > { > + grub_unregister_command (background_color_cmd_handle); > grub_unregister_extcmd (background_image_cmd_handle); > grub_term_unregister_output (&grub_video_term); > } > > === renamed file 'grub-core/gfxmenu/named_colors.c' => 'grub-core/video/colors.c' > --- grub-core/gfxmenu/named_colors.c 2009-11-20 15:02:58 +0000 > +++ grub-core/video/colors.c 2010-12-10 15:31:32 +0000 > @@ -25,7 +25,7 @@ > struct named_color > { > const char *name; > - grub_gui_color_t color; > + grub_video_rgba_color_t color; > }; > > /* > @@ -193,8 +193,8 @@ static struct named_color named_colors[] > stores the color into *COLOR. If the color was not found, returns 0 and > does not modify *COLOR. */ > int > -grub_gui_get_named_color (const char *name, > - grub_gui_color_t *color) > +grub_video_get_named_color (const char *name, > + grub_video_rgba_color_t *color) > { > int i; > for (i = 0; named_colors[i].name; i++) > @@ -207,3 +207,124 @@ grub_gui_get_named_color (const char *na > } > return 0; > } > + > +static __inline int > +my_isxdigit (char c) > +{ > + return ((c >= '0' && c <= '9') > + || (c >= 'a' && c <= 'f') > + || (c >= 'A' && c <= 'F')); > +} > + > +static int > +parse_hex_color_component (const char *s, unsigned start, unsigned end) > +{ > + unsigned len; > + char buf[3]; > + > + len = end - start; > + /* Check the limits so we don't overrun the buffer. */ > + if (len < 1 || len > 2) > + return 0; > + > + if (len == 1) > + { > + buf[0] = s[start]; /* Get the first and only hex digit. */ > + buf[1] = buf[0]; /* Duplicate the hex digit. */ > + } > + else if (len == 2) > + { > + buf[0] = s[start]; > + buf[1] = s[start + 1]; > + } > + > + buf[2] = '\0'; > + > + return grub_strtoul (buf, 0, 16); > +} > + > +/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", > + "#RRGGBB", or "#RRGGBBAA". */ > +grub_err_t > +grub_video_parse_color (const char *s, grub_video_rgba_color_t *color) > +{ > + grub_video_rgba_color_t c; > + > + /* Skip whitespace. */ > + while (*s && grub_isspace (*s)) > + s++; > + > + if (*s == '#') > + { > + /* HTML-style. Number if hex digits: > + [6] #RRGGBB [3] #RGB > + [8] #RRGGBBAA [4] #RGBA */ > + > + s++; /* Skip the '#'. */ > + /* Count the hexits to determine the format. */ > + int hexits = 0; > + const char *end = s; > + while (my_isxdigit (*end)) > + { > + end++; > + hexits++; > + } > + > + /* Parse the color components based on the format. */ > + if (hexits == 3 || hexits == 4) > + { > + c.red = parse_hex_color_component (s, 0, 1); > + c.green = parse_hex_color_component (s, 1, 2); > + c.blue = parse_hex_color_component (s, 2, 3); > + if (hexits == 4) > + c.alpha = parse_hex_color_component (s, 3, 4); > + else > + c.alpha = 255; > + } > + else if (hexits == 6 || hexits == 8) > + { > + c.red = parse_hex_color_component (s, 0, 2); > + c.green = parse_hex_color_component (s, 2, 4); > + c.blue = parse_hex_color_component (s, 4, 6); > + if (hexits == 8) > + c.alpha = parse_hex_color_component (s, 6, 8); > + else > + c.alpha = 255; > + } > + else > + return grub_error (GRUB_ERR_BAD_ARGUMENT, > + "invalid HTML-type color string `%s'", s); > + } > + else if (grub_isdigit (*s)) > + { > + /* Comma separated decimal values. */ > + c.red = grub_strtoul (s, 0, 0); > + if ((s = grub_strchr (s, ',')) == 0) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, > + "missing 1st comma separator in color `%s'", s); > + s++; > + c.green = grub_strtoul (s, 0, 0); > + if ((s = grub_strchr (s, ',')) == 0) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, > + "missing 2nd comma separator in color `%s'", s); > + s++; > + c.blue = grub_strtoul (s, 0, 0); > + if ((s = grub_strchr (s, ',')) == 0) > + c.alpha = 255; > + else > + { > + s++; > + c.alpha = grub_strtoul (s, 0, 0); > + } > + } > + else > + { > + if (! grub_video_get_named_color (s, &c)) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, > + "invalid named color `%s'", s); > + } > + > + if (grub_errno == GRUB_ERR_NONE) > + *color = c; > + return grub_errno; > +} > > === modified file 'include/grub/gfxmenu_view.h' > --- include/grub/gfxmenu_view.h 2010-03-23 17:17:54 +0000 > +++ include/grub/gfxmenu_view.h 2010-12-10 15:28:54 +0000 > @@ -87,11 +87,11 @@ struct grub_gfxmenu_view > grub_font_t title_font; > grub_font_t message_font; > char *terminal_font_name; > - grub_gui_color_t title_color; > - grub_gui_color_t message_color; > - grub_gui_color_t message_bg_color; > + grub_video_rgba_color_t title_color; > + grub_video_rgba_color_t message_color; > + grub_video_rgba_color_t message_bg_color; > struct grub_video_bitmap *desktop_image; > - grub_gui_color_t desktop_color; > + grub_video_rgba_color_t desktop_color; > grub_gfxmenu_box_t terminal_box; > char *title_text; > char *progress_message_text; > > === modified file 'include/grub/gui.h' > --- include/grub/gui.h 2010-05-13 01:56:14 +0000 > +++ include/grub/gui.h 2010-12-10 15:27:20 +0000 > @@ -31,16 +31,6 @@ > status changes. */ > #define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" > > -/* A representation of a color. Unlike grub_video_color_t, this > - representation is independent of any video mode specifics. */ > -typedef struct grub_gui_color > -{ > - grub_uint8_t red; > - grub_uint8_t green; > - grub_uint8_t blue; > - grub_uint8_t alpha; > -} grub_gui_color_t; > - > typedef struct grub_gui_component *grub_gui_component_t; > typedef struct grub_gui_container *grub_gui_container_t; > typedef struct grub_gui_list *grub_gui_list_t; > @@ -242,23 +232,6 @@ grub_gui_set_viewport (const grub_video_ > r->height); > } > > -static __inline grub_gui_color_t > -grub_gui_color_rgb (int r, int g, int b) > -{ > - grub_gui_color_t c; > - c.red = r; > - c.green = g; > - c.blue = b; > - c.alpha = 255; > - return c; > -} > - > -static __inline grub_video_color_t > -grub_gui_map_color (grub_gui_color_t c) > -{ > - return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); > -} > - > static inline int > grub_video_have_common_points (const grub_video_rect_t *a, > const grub_video_rect_t *b) > > === modified file 'include/grub/gui_string_util.h' > --- include/grub/gui_string_util.h 2009-12-29 16:31:02 +0000 > +++ include/grub/gui_string_util.h 2010-12-10 15:25:37 +0000 > @@ -30,8 +30,4 @@ char *grub_resolve_relative_path (const > > char *grub_get_dirname (const char *file_path); > > -int grub_gui_get_named_color (const char *name, grub_gui_color_t *color); > - > -grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color); > - > #endif /* GRUB_GUI_STRING_UTIL_HEADER */ > > === modified file 'include/grub/video.h' > --- include/grub/video.h 2010-09-12 00:09:09 +0000 > +++ include/grub/video.h 2010-12-10 15:35:07 +0000 > @@ -27,6 +27,15 @@ > specific coding format. */ > typedef grub_uint32_t grub_video_color_t; > > +/* Video color in hardware independent format. */ > +typedef struct grub_video_rgba_color > +{ > + grub_uint8_t red; > + grub_uint8_t green; > + grub_uint8_t blue; > + grub_uint8_t alpha; > +} grub_video_rgba_color_t; > + > /* This structure is driver specific and should not be accessed directly by > outside code. */ > struct grub_video_render_target; > @@ -428,4 +437,27 @@ grub_video_check_mode_flag (grub_video_m > > grub_video_driver_id_t EXPORT_FUNC (grub_video_get_driver_id) (void); > > +static __inline grub_video_rgba_color_t > +grub_video_rgba_color_rgb (int r, int g, int b) > +{ > + grub_video_rgba_color_t c; > + c.red = r; > + c.green = g; > + c.blue = b; > + c.alpha = 255; > + return c; > +} > + > +static __inline grub_video_color_t > +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); > + > #endif /* ! GRUB_VIDEO_HEADER */ > > Thanks, > > -- Regards Vladimir 'φ-coder/phcoder' Serbinenko [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 294 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-12-25 11:26 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-12-10 12:39 [PATCH] background_color command Colin Watson 2010-12-10 17:53 ` Colin Watson 2010-12-13 14:00 ` Colin Watson 2010-12-18 19:46 ` Vladimir 'φ-coder/phcoder' Serbinenko 2010-12-23 12:21 ` Colin Watson 2010-12-25 11:26 ` Vladimir 'φ-coder/phcoder' Serbinenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).