]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2006-07-29 Vesa Jaaskelainen <chaac@nic.fi>
authorchaac <chaac@localhost>
Mon, 31 Jul 2006 14:21:36 +0000 (14:21 +0000)
committerchaac <chaac@localhost>
Mon, 31 Jul 2006 14:21:36 +0000 (14:21 +0000)
* include/grub/bitmap.h: New file.

* include/grub/i386/pc/vbeutil.h: Likewise.

* video/bitmap.c: Likewise.

* video/readers/tga.c: Likewise.

* video/i386/pc/vbeutil.c: Likewise.

* commands/videotest.c: Code cleanup and updated to reflect to new
video API.

* term/gfxterm.c: Likewise.

* video/video.c: Likewise.

* conf/i386-pc.rmk (pkgdata_MODULES): Added tga.mod and bitmap.mod.
(vbe_mod_SOURCES): Added video/i386/pc/vbeutil.c.
(bitmap_mod_SOURCES): New entry.
(bitmap_mod_CFLAGS): Likewise.
(bitmap_mod_LDFLAGS): Likewise.
(tga_mod_SOURCES): Likewise.
(tga_mod_CFLAGS): Likewise.
(tga_mod_LDFLAGS): Likewise.

* include/grub/video.h (grub_video_blit_operators): New enum type.
(grub_video_render_target): Changed as forward declaration and moved
actual definition to be video driver specific.
(grub_video_adapter.blit_bitmap): Added blitting operator.
(grub_video_adapter.blit_render_target): Likewise.
(grub_video_blit_bitmap): Likewise.
(grub_video_blit_render_target): Likewise.

* include/grub/i386/pc/vbe.h (grub_video_render_target): Added
driver specific render target definition.
(grub_video_vbe_map_rgba): Added driver internal helper.
(grub_video_vbe_unmap_color): Updated to use
grub_video_i386_vbeblit_info.
(grub_video_vbe_get_video_ptr): Likewise.

* include/grub/i386/pc/vbeblit.h
(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): Updated to use
grub_video_i386_vbeblit_info.
(grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise.
(grub_video_i386_vbeblit_index_R8G8B8A8): Likewise.
(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise.
(grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise.
(grub_video_i386_vbeblit_index_R8G8B8): Likewise.
(grub_video_i386_vbeblit_index_index): Likewise.
(grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): New blitter function.
(grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise.
(grub_video_i386_vbeblit_index_R8G8B8X8): Likewise.
(grub_video_i386_vbeblit_blend): Added generic blitter for blend
operator.
(grub_video_i386_vbeblit_replace): Added generic blitter for replace
operator.

* video/i386/pc/vbeblit.c: Updated to reflect changes on
include/grub/i386/pc/vbeblit.h.

* include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8):
Updated to use grub_video_i386_vbeblit_info.
(grub_video_i386_vbefill_R8G8B8): Likewise.
(grub_video_i386_vbefill_index): Likewise.
(grub_video_i386_vbefill): Added generic filler.

* video/i386/pc/vbefill.c: Updated to reflect changes on
include/grub/i386/pc/vbefill.h.

* video/i386/pc/vbe.c (grub_video_vbe_get_video_ptr): Updated to use
grub_video_i386_vbeblit_info.
(grub_video_vbe_unmap_color): Likewise.
(grub_video_vbe_blit_glyph): Likewise.
(grub_video_vbe_scroll): Likewise.
(grub_video_vbe_draw_pixel): Removed function.
(grub_video_vbe_get_pixel): Likewise.
(grub_video_vbe_fill_rect): Moved all blitters to vbefill.c and
updated code to use it.
(common_blitter): Added common blitter for render target and bitmap.
(grub_video_vbe_blit_bitmap): Updated to use common_blitter.
(grub_video_vbe_blit_render_target): Likewise.

18 files changed:
ChangeLog
commands/videotest.c
conf/i386-pc.mk
conf/i386-pc.rmk
include/grub/bitmap.h [new file with mode: 0644]
include/grub/i386/pc/vbe.h
include/grub/i386/pc/vbeblit.h
include/grub/i386/pc/vbefill.h
include/grub/i386/pc/vbeutil.h [new file with mode: 0644]
include/grub/video.h
term/gfxterm.c
video/bitmap.c [new file with mode: 0644]
video/i386/pc/vbe.c
video/i386/pc/vbeblit.c
video/i386/pc/vbefill.c
video/i386/pc/vbeutil.c [new file with mode: 0644]
video/readers/tga.c [new file with mode: 0644]
video/video.c

index 31b959586093529ea0a00b6e07251d2879280227..6a4089c8b5b80f1d9992f1d5ca1186f95f73ccad 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,88 @@
+2006-07-29  Vesa Jaaskelainen  <chaac@nic.fi>
+
+       * include/grub/bitmap.h: New file.
+
+       * include/grub/i386/pc/vbeutil.h: Likewise.
+
+       * video/bitmap.c: Likewise.
+
+       * video/readers/tga.c: Likewise.
+
+       * video/i386/pc/vbeutil.c: Likewise.
+
+       * commands/videotest.c: Code cleanup and updated to reflect to new
+       video API.
+
+       * term/gfxterm.c: Likewise.
+
+       * video/video.c: Likewise.
+
+       * conf/i386-pc.rmk (pkgdata_MODULES): Added tga.mod and bitmap.mod.
+       (vbe_mod_SOURCES): Added video/i386/pc/vbeutil.c.
+       (bitmap_mod_SOURCES): New entry.
+       (bitmap_mod_CFLAGS): Likewise.
+       (bitmap_mod_LDFLAGS): Likewise.
+       (tga_mod_SOURCES): Likewise.
+       (tga_mod_CFLAGS): Likewise.
+       (tga_mod_LDFLAGS): Likewise.
+
+       * include/grub/video.h (grub_video_blit_operators): New enum type.
+       (grub_video_render_target): Changed as forward declaration and moved
+       actual definition to be video driver specific.
+       (grub_video_adapter.blit_bitmap): Added blitting operator.
+       (grub_video_adapter.blit_render_target): Likewise.
+       (grub_video_blit_bitmap): Likewise.
+       (grub_video_blit_render_target): Likewise.
+
+       * include/grub/i386/pc/vbe.h (grub_video_render_target): Added
+       driver specific render target definition.
+       (grub_video_vbe_map_rgba): Added driver internal helper.
+       (grub_video_vbe_unmap_color): Updated to use
+       grub_video_i386_vbeblit_info.
+       (grub_video_vbe_get_video_ptr): Likewise.
+
+       * include/grub/i386/pc/vbeblit.h
+       (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): Updated to use
+       grub_video_i386_vbeblit_info.
+       (grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise.
+       (grub_video_i386_vbeblit_index_R8G8B8A8): Likewise.
+       (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise.
+       (grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise.
+       (grub_video_i386_vbeblit_index_R8G8B8): Likewise.
+       (grub_video_i386_vbeblit_index_index): Likewise.
+       (grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): New blitter function.
+       (grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise.
+       (grub_video_i386_vbeblit_index_R8G8B8X8): Likewise.
+       (grub_video_i386_vbeblit_blend): Added generic blitter for blend
+       operator.
+       (grub_video_i386_vbeblit_replace): Added generic blitter for replace
+       operator.
+
+       * video/i386/pc/vbeblit.c: Updated to reflect changes on
+       include/grub/i386/pc/vbeblit.h.
+
+       * include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8):
+       Updated to use grub_video_i386_vbeblit_info.
+       (grub_video_i386_vbefill_R8G8B8): Likewise.
+       (grub_video_i386_vbefill_index): Likewise.
+       (grub_video_i386_vbefill): Added generic filler.
+
+       * video/i386/pc/vbefill.c: Updated to reflect changes on
+       include/grub/i386/pc/vbefill.h.
+
+       * video/i386/pc/vbe.c (grub_video_vbe_get_video_ptr): Updated to use
+       grub_video_i386_vbeblit_info.
+       (grub_video_vbe_unmap_color): Likewise.
+       (grub_video_vbe_blit_glyph): Likewise.
+       (grub_video_vbe_scroll): Likewise.
+       (grub_video_vbe_draw_pixel): Removed function.
+       (grub_video_vbe_get_pixel): Likewise.
+       (grub_video_vbe_fill_rect): Moved all blitters to vbefill.c and
+       updated code to use it.
+       (common_blitter): Added common blitter for render target and bitmap.
+       (grub_video_vbe_blit_bitmap): Updated to use common_blitter.
+       (grub_video_vbe_blit_render_target): Likewise.
+
 2006-07-30  Johan Rydberg  <jrydberg@gnu.org>
 
        * kern/efi/efi.c (grub_efi_set_text_mode): Assume console already
index 2141f9d44ad1a2b0aab163b525f2a56f716e0706..9978e1567e7b16a8ed9995565635f6c5b16792ff 100644 (file)
@@ -36,7 +36,7 @@ grub_cmd_videotest (struct grub_arg_list *state __attribute__ ((unused)),
   if (grub_video_setup (1024, 768,
                         GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != GRUB_ERR_NONE)
     return grub_errno;
-  
+
   grub_getkey ();
 
   grub_video_color_t color;
@@ -48,21 +48,21 @@ grub_cmd_videotest (struct grub_arg_list *state __attribute__ ((unused)),
   struct grub_font_glyph glyph;
   struct grub_video_render_target *text_layer;
   grub_video_color_t palette[16];
-  
+
   grub_video_get_viewport (&x, &y, &width, &height);
 
   grub_video_create_render_target (&text_layer, width, height,
                                    GRUB_VIDEO_MODE_TYPE_RGB
                                    | GRUB_VIDEO_MODE_TYPE_ALPHA);
 
-  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);                                   
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
 
   color = grub_video_map_rgb (0, 0, 0);
   grub_video_fill_rect (color, 0, 0, width, height);
-  
+
   color = grub_video_map_rgb (255, 0, 0);
   grub_video_fill_rect (color, 0, 0, 100, 100);
-  
+
   color = grub_video_map_rgb (0, 255, 255);
   grub_video_fill_rect (color, 100, 100, 100, 100);
 
@@ -73,18 +73,18 @@ grub_cmd_videotest (struct grub_arg_list *state __attribute__ ((unused)),
                            width - 150 * 2, height - 150 * 2);
   color = grub_video_map_rgb (77, 33, 77);
   grub_video_fill_rect (color, 0, 0, width, height);
-  
+
   grub_video_set_active_render_target (text_layer);
-  
+
   color = grub_video_map_rgb (255, 255, 255);
-  
-  grub_font_get_glyph ('A', &glyph);  
+
+  grub_font_get_glyph ('A', &glyph);
   grub_video_blit_glyph (&glyph, color, 16, 16);
-  grub_font_get_glyph ('B', &glyph);  
+  grub_font_get_glyph ('B', &glyph);
   grub_video_blit_glyph (&glyph, color, 16 * 2, 16);
 
-  grub_font_get_glyph ('*', &glyph);  
-  
+  grub_font_get_glyph ('*', &glyph);
+
   for (i = 0; i < 16; i++)
     {
       color = grub_video_map_color (i);
@@ -98,18 +98,19 @@ grub_cmd_videotest (struct grub_arg_list *state __attribute__ ((unused)),
     {
       color = grub_video_map_rgb (i, 33, 77);
       grub_video_fill_rect (color, 0, 0, width, height);
-      grub_video_blit_render_target (text_layer, 0, 0, 0, 0, width, height);
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
+                                     0, 0, width, height);
     }
-  
+
   grub_getkey ();
-  
+
   grub_video_delete_render_target (text_layer);
-  
+
   grub_video_restore ();
-  
+
   for (i = 0; i < 16; i++)
     grub_printf("color %d: %08x\n", i, palette[i]);
-  
+
   grub_errno = GRUB_ERR_NONE;
   return grub_errno;
 }
index 7ed204572d6830b52caaf26e4fb5cf1992afbbf1..13115e122d7b472f6284062a8112b9c4c928d052 100644 (file)
@@ -1336,7 +1336,7 @@ grub-install: util/i386/pc/grub-install.in config.status
 pkgdata_MODULES = _chain.mod _linux.mod linux.mod normal.mod \
        _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod      \
        vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
-       videotest.mod play.mod
+       videotest.mod play.mod bitmap.mod tga.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -2101,13 +2101,13 @@ multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For vbe.mod.
 vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
-                 video/i386/pc/vbefill.c
-CLEANFILES += vbe.mod mod-vbe.o mod-vbe.c pre-vbe.o vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o und-vbe.lst
+                 video/i386/pc/vbefill.c video/i386/pc/vbeutil.c
+CLEANFILES += vbe.mod mod-vbe.o mod-vbe.c pre-vbe.o vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o vbe_mod-video_i386_pc_vbeutil.o und-vbe.lst
 ifneq ($(vbe_mod_EXPORTS),no)
 CLEANFILES += def-vbe.lst
 DEFSYMFILES += def-vbe.lst
 endif
-MOSTLYCLEANFILES += vbe_mod-video_i386_pc_vbe.d vbe_mod-video_i386_pc_vbeblit.d vbe_mod-video_i386_pc_vbefill.d
+MOSTLYCLEANFILES += vbe_mod-video_i386_pc_vbe.d vbe_mod-video_i386_pc_vbeblit.d vbe_mod-video_i386_pc_vbefill.d vbe_mod-video_i386_pc_vbeutil.d
 UNDSYMFILES += und-vbe.lst
 
 vbe.mod: pre-vbe.o mod-vbe.o
@@ -2115,7 +2115,7 @@ vbe.mod: pre-vbe.o mod-vbe.o
        $(TARGET_CC) $(vbe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
        $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
 
-pre-vbe.o: vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o
+pre-vbe.o: vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o vbe_mod-video_i386_pc_vbeutil.o
        -rm -f $@
        $(TARGET_CC) $(vbe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
 
@@ -2191,6 +2191,25 @@ fs-vbe_mod-video_i386_pc_vbefill.lst: video/i386/pc/vbefill.c genfslist.sh
        set -e;           $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $<      | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1)
 
 
+vbe_mod-video_i386_pc_vbeutil.o: video/i386/pc/vbeutil.c
+       $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -c -o $@ $<
+
+vbe_mod-video_i386_pc_vbeutil.d: video/i386/pc/vbeutil.c
+       set -e;           $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -M $<      | sed 's,vbeutil\.o[ :]*,vbe_mod-video_i386_pc_vbeutil.o $@ : ,g' > $@;         [ -s $@ ] || rm -f $@
+
+-include vbe_mod-video_i386_pc_vbeutil.d
+
+CLEANFILES += cmd-vbe_mod-video_i386_pc_vbeutil.lst fs-vbe_mod-video_i386_pc_vbeutil.lst
+COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbeutil.lst
+FSFILES += fs-vbe_mod-video_i386_pc_vbeutil.lst
+
+cmd-vbe_mod-video_i386_pc_vbeutil.lst: video/i386/pc/vbeutil.c gencmdlist.sh
+       set -e;           $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $<      | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1)
+
+fs-vbe_mod-video_i386_pc_vbeutil.lst: video/i386/pc/vbeutil.c genfslist.sh
+       set -e;           $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $<      | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1)
+
+
 vbe_mod_CFLAGS = $(COMMON_CFLAGS)
 vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
@@ -2530,4 +2549,116 @@ fs-videotest_mod-commands_videotest.lst: commands/videotest.c genfslist.sh
 videotest_mod_CFLAGS = $(COMMON_CFLAGS)
 videotest_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For bitmap.mod
+bitmap_mod_SOURCES = video/bitmap.c
+CLEANFILES += bitmap.mod mod-bitmap.o mod-bitmap.c pre-bitmap.o bitmap_mod-video_bitmap.o und-bitmap.lst
+ifneq ($(bitmap_mod_EXPORTS),no)
+CLEANFILES += def-bitmap.lst
+DEFSYMFILES += def-bitmap.lst
+endif
+MOSTLYCLEANFILES += bitmap_mod-video_bitmap.d
+UNDSYMFILES += und-bitmap.lst
+
+bitmap.mod: pre-bitmap.o mod-bitmap.o
+       -rm -f $@
+       $(TARGET_CC) $(bitmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+       $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-bitmap.o: bitmap_mod-video_bitmap.o
+       -rm -f $@
+       $(TARGET_CC) $(bitmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+
+mod-bitmap.o: mod-bitmap.c
+       $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -c -o $@ $<
+
+mod-bitmap.c: moddep.lst genmodsrc.sh
+       sh $(srcdir)/genmodsrc.sh 'bitmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(bitmap_mod_EXPORTS),no)
+def-bitmap.lst: pre-bitmap.o
+       $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bitmap/' > $@
+endif
+
+und-bitmap.lst: pre-bitmap.o
+       echo 'bitmap' > $@
+       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+bitmap_mod-video_bitmap.o: video/bitmap.c
+       $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -c -o $@ $<
+
+bitmap_mod-video_bitmap.d: video/bitmap.c
+       set -e;           $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -M $<           | sed 's,bitmap\.o[ :]*,bitmap_mod-video_bitmap.o $@ : ,g' > $@;        [ -s $@ ] || rm -f $@
+
+-include bitmap_mod-video_bitmap.d
+
+CLEANFILES += cmd-bitmap_mod-video_bitmap.lst fs-bitmap_mod-video_bitmap.lst
+COMMANDFILES += cmd-bitmap_mod-video_bitmap.lst
+FSFILES += fs-bitmap_mod-video_bitmap.lst
+
+cmd-bitmap_mod-video_bitmap.lst: video/bitmap.c gencmdlist.sh
+       set -e;           $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $<           | sh $(srcdir)/gencmdlist.sh bitmap > $@ || (rm -f $@; exit 1)
+
+fs-bitmap_mod-video_bitmap.lst: video/bitmap.c genfslist.sh
+       set -e;           $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $<           | sh $(srcdir)/genfslist.sh bitmap > $@ || (rm -f $@; exit 1)
+
+
+bitmap_mod_CFLAGS = $(COMMON_CFLAGS)
+bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tga.mod
+tga_mod_SOURCES = video/readers/tga.c
+CLEANFILES += tga.mod mod-tga.o mod-tga.c pre-tga.o tga_mod-video_readers_tga.o und-tga.lst
+ifneq ($(tga_mod_EXPORTS),no)
+CLEANFILES += def-tga.lst
+DEFSYMFILES += def-tga.lst
+endif
+MOSTLYCLEANFILES += tga_mod-video_readers_tga.d
+UNDSYMFILES += und-tga.lst
+
+tga.mod: pre-tga.o mod-tga.o
+       -rm -f $@
+       $(TARGET_CC) $(tga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+       $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-tga.o: tga_mod-video_readers_tga.o
+       -rm -f $@
+       $(TARGET_CC) $(tga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+
+mod-tga.o: mod-tga.c
+       $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -c -o $@ $<
+
+mod-tga.c: moddep.lst genmodsrc.sh
+       sh $(srcdir)/genmodsrc.sh 'tga' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(tga_mod_EXPORTS),no)
+def-tga.lst: pre-tga.o
+       $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 tga/' > $@
+endif
+
+und-tga.lst: pre-tga.o
+       echo 'tga' > $@
+       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+tga_mod-video_readers_tga.o: video/readers/tga.c
+       $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -c -o $@ $<
+
+tga_mod-video_readers_tga.d: video/readers/tga.c
+       set -e;           $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -M $<      | sed 's,tga\.o[ :]*,tga_mod-video_readers_tga.o $@ : ,g' > $@;         [ -s $@ ] || rm -f $@
+
+-include tga_mod-video_readers_tga.d
+
+CLEANFILES += cmd-tga_mod-video_readers_tga.lst fs-tga_mod-video_readers_tga.lst
+COMMANDFILES += cmd-tga_mod-video_readers_tga.lst
+FSFILES += fs-tga_mod-video_readers_tga.lst
+
+cmd-tga_mod-video_readers_tga.lst: video/readers/tga.c gencmdlist.sh
+       set -e;           $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $<      | sh $(srcdir)/gencmdlist.sh tga > $@ || (rm -f $@; exit 1)
+
+fs-tga_mod-video_readers_tga.lst: video/readers/tga.c genfslist.sh
+       set -e;           $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $<      | sh $(srcdir)/genfslist.sh tga > $@ || (rm -f $@; exit 1)
+
+
+tga_mod_CFLAGS = $(COMMON_CFLAGS)
+tga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 include $(srcdir)/conf/common.mk
index b2a045fb8ffb698cab151e5edf2d48be145f9db8..dd5117fb621e0606f717a5b8bc439b5172522e69 100644 (file)
@@ -112,7 +112,7 @@ grub_install_SOURCES = util/i386/pc/grub-install.in
 pkgdata_MODULES = _chain.mod _linux.mod linux.mod normal.mod \
        _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod      \
        vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
-       videotest.mod play.mod
+       videotest.mod play.mod bitmap.mod tga.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -171,7 +171,7 @@ multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For vbe.mod.
 vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
-                 video/i386/pc/vbefill.c
+                 video/i386/pc/vbefill.c video/i386/pc/vbeutil.c
 vbe_mod_CFLAGS = $(COMMON_CFLAGS)
 vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
@@ -205,4 +205,14 @@ videotest_mod_SOURCES = commands/videotest.c
 videotest_mod_CFLAGS = $(COMMON_CFLAGS)
 videotest_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For bitmap.mod
+bitmap_mod_SOURCES = video/bitmap.c
+bitmap_mod_CFLAGS = $(COMMON_CFLAGS)
+bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tga.mod
+tga_mod_SOURCES = video/readers/tga.c
+tga_mod_CFLAGS = $(COMMON_CFLAGS)
+tga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 include $(srcdir)/conf/common.mk
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
new file mode 100644 (file)
index 0000000..9efa305
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_BITMAP_HEADER
+#define GRUB_BITMAP_HEADER     1
+
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+struct grub_video_bitmap
+{
+  /* Bitmap format description.  */
+  struct grub_video_mode_info mode_info;
+
+  /* Pointer to bitmap data formatted according to mode_info.  */
+  void *data;
+};
+
+struct grub_video_bitmap_reader
+{
+  /* File extension for this bitmap type (including dot).  */
+  const char *extension;
+
+  /* Reader function to load bitmap.  */
+  grub_err_t (*reader) (struct grub_video_bitmap **bitmap,
+                        const char *filename);
+
+  /* Next reader.  */
+  struct grub_video_bitmap_reader *next;
+};
+typedef struct grub_video_bitmap_reader *grub_video_bitmap_reader_t;
+
+void grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader);
+void grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader);
+
+grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
+                                     unsigned int width, unsigned int height,
+                                     enum grub_video_blit_format blit_format);
+
+grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap);
+
+grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
+                                   const char *filename);
+
+unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap);
+unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap);
+
+void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
+                                      struct grub_video_mode_info *mode_info);
+
+void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap);
+
+#endif /* ! GRUB_BITMAP_HEADER */
index 5cb15bd19fe820bcc0d0cffb2e9aea7c3e980819..3797ee5d1fa35c701708d1de91f6c0fdb47d634e 100644 (file)
@@ -205,13 +205,43 @@ grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode,
                                          struct grub_vbe_mode_info_block *mode_info);
 
 /* VBE module internal prototypes (should not be used from elsewhere).  */
-grub_uint8_t * grub_video_vbe_get_video_ptr (struct grub_video_render_target *source,
+struct grub_video_i386_vbeblit_info;
+
+struct grub_video_render_target
+{
+  /* Copy of the screen's mode info structure, except that width, height and
+     mode_type has been re-adjusted to requested render target settings.  */
+  struct grub_video_mode_info mode_info;
+
+  struct
+  {
+    unsigned int x;
+    unsigned int y;
+    unsigned int width;
+    unsigned int height;
+  } viewport;
+
+  /* Indicates wether the data has been allocated by us and must be freed
+     when render target is destroyed.  */
+  int is_allocated;
+
+  /* Pointer to data.  Can either be in video card memory or in local host's
+     memory.  */
+  void *data;
+};
+
+grub_uint8_t * grub_video_vbe_get_video_ptr (struct grub_video_i386_vbeblit_info *source,
                                              grub_uint32_t x, grub_uint32_t y);
 
 grub_video_color_t grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green,
                                            grub_uint8_t blue);
 
-void grub_video_vbe_unmap_color (struct grub_video_render_target * source,
+grub_video_color_t grub_video_vbe_map_rgba (grub_uint8_t red,
+                                            grub_uint8_t green,
+                                            grub_uint8_t blue,
+                                            grub_uint8_t alpha);
+
+void grub_video_vbe_unmap_color (struct grub_video_i386_vbeblit_info *source,
                                  grub_video_color_t color, grub_uint8_t *red,
                                  grub_uint8_t *green, grub_uint8_t *blue,
                                  grub_uint8_t *alpha);
index 890b57700c7e21d0185d8a2192992d86d1fefebe..d90c5eea4c94666b69881660194b8992e47760a4 100644 (file)
 #ifndef GRUB_VBEBLIT_MACHINE_HEADER
 #define GRUB_VBEBLIT_MACHINE_HEADER    1
 
+/* NOTE: This header is private header for vbe driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_i386_vbeblit_info;
+
 void
-grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_render_target *dst,
-                                           struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
+                                           struct grub_video_i386_vbeblit_info *src,
                                            int x, int y, int width, int height,
                                            int offset_x, int offset_y);
 
 void
-grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_render_target *dst,
-                                         struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8 (struct grub_video_i386_vbeblit_info *dst,
+                                           struct grub_video_i386_vbeblit_info *src,
+                                           int x, int y, int width, int height,
+                                           int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
+                                         struct grub_video_i386_vbeblit_info *src,
                                          int x, int y, int width, int height,
                                          int offset_x, int offset_y);
 
 void
-grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_render_target *dst,
-                                        struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8_R8G8B8X8 (struct grub_video_i386_vbeblit_info *dst,
+                                         struct grub_video_i386_vbeblit_info *src,
+                                         int x, int y, int width, int height,
+                                         int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
+                                        struct grub_video_i386_vbeblit_info *src,
                                         int x, int y, int width, int height,
                                         int offset_x, int offset_y);
 
+void
+grub_video_i386_vbeblit_index_R8G8B8X8 (struct grub_video_i386_vbeblit_info *dst,
+                                        struct grub_video_i386_vbeblit_info *src,
+                                        int x, int y, int width, int height,
+                                        int offset_x, int offset_y);
 
 void
-grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_render_target *dst,
-                                         struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
+                                         struct grub_video_i386_vbeblit_info *src,
                                          int x, int y, int width, int height,
                                          int offset_x, int offset_y);
 
 void
-grub_video_i386_vbeblit_R8G8B8_R8G8B8 (struct grub_video_render_target *dst,
-                                       struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
+                                       struct grub_video_i386_vbeblit_info *src,
                                        int x, int y, int width, int height,
                                        int offset_x, int offset_y);
 
 void
-grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_render_target *dst,
-                                      struct grub_video_render_target *src,
+grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
+                                      struct grub_video_i386_vbeblit_info *src,
                                       int x, int y, int width, int height,
                                       int offset_x, int offset_y);
 
 void
-grub_video_i386_vbeblit_index_index (struct grub_video_render_target *dst,
-                                     struct grub_video_render_target *src,
+grub_video_i386_vbeblit_index_index (struct grub_video_i386_vbeblit_info *dst,
+                                     struct grub_video_i386_vbeblit_info *src,
                                      int x, int y, int width, int height,
                                      int offset_x, int offset_y);
 
+void
+grub_video_i386_vbeblit_blend (struct grub_video_i386_vbeblit_info *dst,
+                               struct grub_video_i386_vbeblit_info *src,
+                               int x, int y, int width, int height,
+                               int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_replace (struct grub_video_i386_vbeblit_info *dst,
+                                 struct grub_video_i386_vbeblit_info *src,
+                                 int x, int y, int width, int height,
+                                 int offset_x, int offset_y);
+
 #endif /* ! GRUB_VBEBLIT_MACHINE_HEADER */
index 14f7b53230374a1a74931cfd728714b3b0359138..604473adfc3f25c0eb4f0dc18a695f6391403dd4 100644 (file)
 #ifndef GRUB_VBEFILL_MACHINE_HEADER
 #define GRUB_VBEFILL_MACHINE_HEADER    1
 
-#include <grub/video.h>
+/* NOTE: This header is private header for vbe driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_i386_vbeblit_info;
 
 void
-grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
                                   grub_video_color_t color,  int x, int y,
                                   int width, int height);
 
 void
-grub_video_i386_vbefill_R8G8B8 (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
                                 grub_video_color_t color, int x, int y,
                                 int width, int height);
 
 void
-grub_video_i386_vbefill_index (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_index (struct grub_video_i386_vbeblit_info *dst,
                                grub_video_color_t color, int x, int y,
                                int width, int height);
 
+void
+grub_video_i386_vbefill (struct grub_video_i386_vbeblit_info *dst,
+                         grub_video_color_t color, int x, int y,
+                         int width, int height);
+
 #endif /* ! GRUB_VBEFILL_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/vbeutil.h b/include/grub/i386/pc/vbeutil.h
new file mode 100644 (file)
index 0000000..9073f24
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* NOTE: This header is private header for vbe driver and should not be used
+   in other parts of the code.  */
+
+#ifndef GRUB_VBEUTIL_MACHINE_HEADER
+#define GRUB_VBEUTIL_MACHINE_HEADER    1
+
+#include <grub/types.h>
+#include <grub/video.h>
+
+struct grub_video_i386_vbeblit_info
+{
+  struct grub_video_mode_info *mode_info;
+  void *data;
+};
+
+grub_uint8_t *get_data_ptr (struct grub_video_i386_vbeblit_info *source,
+                            unsigned int x, unsigned int y);
+
+grub_video_color_t get_pixel (struct grub_video_i386_vbeblit_info *source,
+                              unsigned int x, unsigned int y);
+
+void set_pixel (struct grub_video_i386_vbeblit_info *source,
+                unsigned int x, unsigned int y, grub_video_color_t color);
+
+#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
index 5c99e0d39a6244765fb9dc8ec89f98b3b7b444c6..427cb7c427045673c49ef604bd287a46b0b16baa 100644 (file)
 #include <grub/err.h>
 #include <grub/types.h>
 
+/* Video color in hardware dependant format.  Users should not assume any
+   specific coding format.  */
 typedef grub_uint32_t grub_video_color_t;
 
+/* This structure is driver specific and should not be accessed directly by 
+   outside code.  */
 struct grub_video_render_target;
 
+/* Forward declarations for used data structures.  */
+struct grub_font_glyph;
+struct grub_video_bitmap;
+
 /* Defines used to describe video mode or rendering target.  */
 #define GRUB_VIDEO_MODE_TYPE_ALPHA             0x00000008
 #define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED   0x00000004
@@ -60,6 +68,15 @@ enum grub_video_blit_format
     GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR
   };
 
+/* Define blitting operators.  */
+enum grub_video_blit_operators
+  {
+    /* Replace target bitmap data with source.  */
+    GRUB_VIDEO_BLIT_REPLACE,
+    /* Blend target and source based on source's alpha value.  */
+    GRUB_VIDEO_BLIT_BLEND
+  };
+
 struct grub_video_mode_info
 {
   /* Width of the screen.  */
@@ -113,29 +130,6 @@ struct grub_video_mode_info
   unsigned int reserved_field_pos;
 };
 
-struct grub_video_render_target
-{
-  /* Copy of the screen's mode info structure, except that width, height and
-     mode_type has been re-adjusted to requested render target settings.  */
-  struct grub_video_mode_info mode_info;
-
-  struct
-  {
-    unsigned int x;
-    unsigned int y;
-    unsigned int width;
-    unsigned int height;       
-  } viewport;
-
-  /* Indicates wether the data has been allocated by us and must be freed 
-     when render target is destroyed.  */
-  int is_allocated;
-
-  /* Pointer to data.  Can either be in video card memory or in local host's
-     memory.  */
-  void *data;
-};
-
 struct grub_video_palette_data
 {
   grub_uint8_t r; /* Red color value (0-255).  */
@@ -144,9 +138,6 @@ struct grub_video_palette_data
   grub_uint8_t a; /* Reserved bits value (0-255).  */
 };
 
-struct grub_font_glyph;
-struct grub_video_bitmap;
-
 struct grub_video_adapter
 {
   /* The video adapter name.  */
@@ -190,10 +181,12 @@ struct grub_video_adapter
                             grub_video_color_t color, int x, int y);
 
   grub_err_t (*blit_bitmap) (struct grub_video_bitmap *bitmap,
+                             enum grub_video_blit_operators oper,
                              int x, int y, int offset_x, int offset_y,
                              unsigned int width, unsigned int height);
 
   grub_err_t (*blit_render_target) (struct grub_video_render_target *source,
+                                    enum grub_video_blit_operators oper,
                                     int x, int y, int offset_x, int offset_y,
                                     unsigned int width, unsigned int height);
 
@@ -254,10 +247,12 @@ grub_err_t grub_video_blit_glyph (struct grub_font_glyph *glyph,
                                   grub_video_color_t color, int x, int y);
 
 grub_err_t grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
+                                   enum grub_video_blit_operators oper,
                                    int x, int y, int offset_x, int offset_y,
                                    unsigned int width, unsigned int height);
 
 grub_err_t grub_video_blit_render_target (struct grub_video_render_target *source,
+                                          enum grub_video_blit_operators oper,
                                           int x, int y,
                                           int offset_x, int offset_y,
                                           unsigned int width,
index c30a9086919fcfdce9c833f8006cec067d1d92e1..cfdae3bb89fcb000f077ce8d5d4e9949c8ec40b4 100644 (file)
@@ -89,7 +89,7 @@ struct grub_virtual_screen
   unsigned int cursor_x;
   unsigned int cursor_y;
   int cursor_state;
-  
+
   /* Color settings.  */
   grub_video_color_t fg_color_setting;
   grub_video_color_t bg_color_setting;
@@ -127,7 +127,7 @@ grub_virtual_screen_free (void)
 
   /* Reset virtual screen data.  */
   grub_memset (&virtual_screen, 0, sizeof (virtual_screen));
-  
+
   /* Free render targets.  */
   grub_video_delete_render_target (text_layer);
   text_layer = 0;
@@ -158,8 +158,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
   /* Allocate memory for text buffer.  */
   virtual_screen.text_buffer =
     (struct grub_colored_char *) grub_malloc (virtual_screen.columns
-                                             * virtual_screen.rows
-                                             * sizeof (*virtual_screen.text_buffer));
+                                              * virtual_screen.rows
+                                              * sizeof (*virtual_screen.text_buffer));
   if (grub_errno != GRUB_ERR_NONE)
     return grub_errno;
 
@@ -171,19 +171,19 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
                                    | GRUB_VIDEO_MODE_TYPE_ALPHA);
   if (grub_errno != GRUB_ERR_NONE)
     return grub_errno;
-  
+
   /* As we want to have colors compatible with rendering target,
-     we can only have those after mode is initialized.  */    
+     we can only have those after mode is initialized.  */
   grub_video_set_active_render_target (text_layer);
-  
+
   virtual_screen.fg_color_setting = grub_video_map_color (DEFAULT_FG_COLOR);
   virtual_screen.bg_color_setting = grub_video_map_color (DEFAULT_BG_COLOR);
   virtual_screen.fg_color = virtual_screen.fg_color_setting;
   virtual_screen.bg_color = virtual_screen.bg_color_setting;
   virtual_screen.cursor_color = grub_video_map_color (DEFAULT_CURSOR_COLOR);
-  
+
   grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-  
+
   return grub_errno;
 }
 
@@ -196,7 +196,7 @@ grub_gfxterm_init (void)
   int depth = -1;
   int flags = DEFAULT_VIDEO_FLAGS;
   grub_video_color_t color;
-  
+
   /* Parse gfxmode environment variable if set.  */
   modevar = grub_env_get ("gfxmode");
   if (modevar)
@@ -204,18 +204,18 @@ grub_gfxterm_init (void)
       char *tmp;
       char *param;
       char *value;
-      
+
       /* Take copy of env.var. as we don't want to modify that.  */
       tmp = grub_strdup (modevar);
       modevar = tmp;
-      
+
       if (grub_errno != GRUB_ERR_NONE)
-        return grub_errno;        
-      
+        return grub_errno;
+
       /* Skip whitespace.  */
       while (grub_isspace (*tmp))
         tmp++;
-      
+
       /* Initialize token holders.  */
       param = tmp;
       value = NULL;
@@ -233,10 +233,10 @@ grub_gfxterm_init (void)
                              "Invalid argument: %s\n",
                              param);
         }
-      
+
       *param = 0;
       param++;
-      
+
       width = grub_strtoul (value, 0, 0);
       if (grub_errno != GRUB_ERR_NONE)
         {
@@ -267,7 +267,7 @@ grub_gfxterm_init (void)
           /* We have optional color depth value.  */
           *param = 0;
           param++;
-          
+
           height = grub_strtoul (value, 0, 0);
           if (grub_errno != GRUB_ERR_NONE)
             {
@@ -277,7 +277,7 @@ grub_gfxterm_init (void)
                                  "Invalid argument: %s\n",
                                  param);
             }
-          
+
           /* Convert color depth value.  */
           value = param;
           depth = grub_strtoul (value, 0, 0);
@@ -290,7 +290,7 @@ grub_gfxterm_init (void)
                                  param);
             }
         }
-      
+
       /* Free memory.  */
       grub_free (modevar);
     }
@@ -323,7 +323,7 @@ grub_gfxterm_init (void)
   /* Leave borders for virtual screen.  */
   width = mode_info.width - (2 * DEFAULT_BORDER_WIDTH);
   height = mode_info.height - (2 * DEFAULT_BORDER_WIDTH);
-  
+
   /* Create virtual screen.  */
   if (grub_virtual_screen_setup (DEFAULT_BORDER_WIDTH, DEFAULT_BORDER_WIDTH,
                                  width, height) != GRUB_ERR_NONE)
@@ -333,7 +333,7 @@ grub_gfxterm_init (void)
     }
 
   /* Mark whole screen as dirty.  */
-  dirty_region_reset ();  
+  dirty_region_reset ();
   dirty_region_add (0, 0, mode_info.width, mode_info.height);
 
   return (grub_errno = GRUB_ERR_NONE);
@@ -354,15 +354,15 @@ redraw_screen_rect (unsigned int x, unsigned int y,
                     unsigned int width, unsigned int height)
 {
   grub_video_color_t color;
-  
+
   grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
 
   /* Render background layer.  */
   color = virtual_screen.bg_color;
   grub_video_fill_rect (color, x, y, width, height);
-  
+
   /* Render text layer.  */
-  grub_video_blit_render_target (text_layer, x, y,
+  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);
@@ -393,7 +393,7 @@ dirty_region_add (int x, int y, unsigned int width, unsigned int height)
 {
   if ((width == 0) || (height == 0))
     return;
-    
+
   if (dirty_region_is_empty ())
     {
       dirty_region.top_left_x = x;
@@ -430,18 +430,18 @@ dirty_region_redraw (void)
   int y;
   int width;
   int height;
-  
+
   if (dirty_region_is_empty ())
     return;
-  
+
   x = dirty_region.top_left_x;
   y = dirty_region.top_left_y;
-  
+
   width = dirty_region.bottom_right_x - x + 1;
   height = dirty_region.bottom_right_y - y + 1;
-  
+
   redraw_screen_rect (x, y, width, height);
-  
+
   dirty_region_reset ();
 }
 
@@ -451,7 +451,7 @@ write_char (void)
   struct grub_colored_char *p;
   struct grub_font_glyph glyph;
   grub_video_color_t color;
-  grub_video_color_t bgcolor;    
+  grub_video_color_t bgcolor;
   unsigned int x;
   unsigned int y;
 
@@ -474,7 +474,7 @@ write_char (void)
   /* Render glyph to text layer.  */
   grub_video_set_active_render_target (text_layer);
   grub_video_fill_rect (bgcolor, x, y, glyph.width, glyph.height);
-  grub_video_blit_glyph (&glyph, color, x, y);  
+  grub_video_blit_glyph (&glyph, color, x, y);
   grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
 
   /* Mark character to be drawn.  */
@@ -517,7 +517,7 @@ scroll_up (void)
 
   /* Scroll text buffer with one line to up.  */
   grub_memmove (virtual_screen.text_buffer,
-               virtual_screen.text_buffer + virtual_screen.columns,
+                virtual_screen.text_buffer + virtual_screen.columns,
                 sizeof (*virtual_screen.text_buffer)
                 * virtual_screen.columns
                 * (virtual_screen.rows - 1));
@@ -533,13 +533,13 @@ scroll_up (void)
       virtual_screen.text_buffer[i].width = 0;
       virtual_screen.text_buffer[i].index = 0;
     }
-    
+
   /* Scroll physical screen.  */
   grub_video_set_active_render_target (text_layer);
   color = virtual_screen.bg_color;
   grub_video_scroll (color, 0, -virtual_screen.char_height);
   grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-  
+
   /* Mark virtual screen to be redrawn.  */
   dirty_region_add_virtualscreen ();
 }
@@ -555,47 +555,47 @@ grub_gfxterm_putchar (grub_uint32_t c)
     {
       /* Erase current cursor, if any.  */
       if (virtual_screen.cursor_state)
-       write_char ();
+        write_char ();
 
       switch (c)
-       {
-       case '\b':
-         if (virtual_screen.cursor_x > 0)
-           virtual_screen.cursor_x--;
-         break;
-         
-       case '\n':
-         if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
-           scroll_up ();
-         else
-           virtual_screen.cursor_y++;
-         break;
-         
-       case '\r':
-         virtual_screen.cursor_x = 0;
-         break;
-       }
+        {
+        case '\b':
+          if (virtual_screen.cursor_x > 0)
+            virtual_screen.cursor_x--;
+          break;
+
+        case '\n':
+          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+            scroll_up ();
+          else
+            virtual_screen.cursor_y++;
+          break;
+
+        case '\r':
+          virtual_screen.cursor_x = 0;
+          break;
+        }
 
       /* Redraw cursor if visible.  */
       if (virtual_screen.cursor_state)
-       write_cursor ();
+        write_cursor ();
     }
   else
     {
       struct grub_font_glyph glyph;
       struct grub_colored_char *p;
-  
+
       /* Get properties of the character.  */    
       grub_font_get_glyph (c, &glyph);
 
       /* If we are about to exceed line length, wrap to next line.  */
       if (virtual_screen.cursor_x + glyph.char_width > virtual_screen.columns)
-       grub_putchar ('\n');
+        grub_putchar ('\n');
 
       /* Find position on virtual screen, and fill information.  */
       p = (virtual_screen.text_buffer +
-          virtual_screen.cursor_x +
-          virtual_screen.cursor_y * virtual_screen.columns);
+           virtual_screen.cursor_x +
+           virtual_screen.cursor_y * virtual_screen.columns);
       p->code = c;
       p->fg_color = virtual_screen.fg_color;
       p->bg_color = virtual_screen.bg_color;
@@ -604,35 +604,35 @@ grub_gfxterm_putchar (grub_uint32_t c)
 
       /* If we have large glyph, add fixup info.  */
       if (glyph.char_width > 1)
-       {
-         unsigned i;
-
-         for (i = 1; i < glyph.char_width; i++)
-           {
-             p[i].code = ' ';
-             p[i].width = glyph.char_width - 1;
-             p[i].index = i;
-           }
-       }
-         
+        {
+          unsigned i;
+
+          for (i = 1; i < glyph.char_width; i++)
+            {
+              p[i].code = ' ';
+              p[i].width = glyph.char_width - 1;
+              p[i].index = i;
+            }
+        }
+
       /* Draw glyph.  */
       write_char ();
-  
+
       /* Make sure we scroll screen when needed and wrap line correctly.  */
       virtual_screen.cursor_x += glyph.char_width;
       if (virtual_screen.cursor_x >= virtual_screen.columns)
-       {
-         virtual_screen.cursor_x = 0;
-         
-         if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
-           scroll_up ();
-         else
-           virtual_screen.cursor_y++;
-       }
+        {
+          virtual_screen.cursor_x = 0;
+
+          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+            scroll_up ();
+          else
+            virtual_screen.cursor_y++;
+        }
 
       /* Draw cursor if visible.  */
       if (virtual_screen.cursor_state)
-       write_cursor ();
+        write_cursor ();
     }
 }
 
@@ -640,7 +640,7 @@ static grub_ssize_t
 grub_gfxterm_getcharwidth (grub_uint32_t c)
 {
   struct grub_font_glyph glyph;
-  
+
   grub_font_get_glyph (c, &glyph);
 
   return glyph.char_width;
@@ -663,7 +663,7 @@ grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
 {
   if (x >= virtual_screen.columns)
     x = virtual_screen.columns - 1;
-  
+
   if (y >= virtual_screen.rows)
     y = virtual_screen.rows - 1;
 
@@ -701,13 +701,13 @@ grub_gfxterm_cls (void)
 
   /* Clear virtual screen.  */
   grub_virtual_screen_cls ();
-  
+
   /* Clear text layer.  */
   grub_video_set_active_render_target (text_layer);
   color = virtual_screen.bg_color_setting;
   grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
   grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-  
+
   /* Mark virtual screen to be redrawn.  */
   dirty_region_add_virtualscreen ();
 }
@@ -745,9 +745,9 @@ grub_gfxterm_setcursor (int on)
   if (virtual_screen.cursor_state != on)
     {
       if (virtual_screen.cursor_state)
-       write_char ();
+        write_char ();
       else
-       write_cursor ();
+        write_cursor ();
 
       virtual_screen.cursor_state = on;
     }
@@ -776,7 +776,7 @@ static struct grub_term grub_video_term =
     .setcolorstate = grub_virtual_screen_setcolorstate,
     .setcolor = grub_virtual_screen_setcolor,
     .setcursor = grub_gfxterm_setcursor,
-    .refresh = grub_gfxterm_refresh,    
+    .refresh = grub_gfxterm_refresh,
     .flags = 0,
     .next = 0
   };
diff --git a/video/bitmap.c b/video/bitmap.c
new file mode 100644 (file)
index 0000000..ec02c8a
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+/* List of bitmap readers registered to system.  */
+static grub_video_bitmap_reader_t bitmap_readers_list;
+
+/* Register bitmap reader.  */
+void
+grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader)
+{
+  reader->next = bitmap_readers_list;
+  bitmap_readers_list = reader;
+}
+
+/* Unregister bitmap reader.  */
+void
+grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader)
+{
+  grub_video_bitmap_reader_t *p, q;
+
+  for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == reader)
+      {
+        *p = q->next;
+        break;
+      }
+}
+
+/* Creates new bitmap, saves created bitmap on success to *bitmap.  */
+grub_err_t
+grub_video_bitmap_create (struct grub_video_bitmap **bitmap, 
+                          unsigned int width, unsigned int height,
+                          enum grub_video_blit_format blit_format)
+{
+  struct grub_video_mode_info *mode_info;
+  unsigned int size;
+
+  if (!bitmap)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument.");
+
+  *bitmap = 0;
+
+  if (width == 0 || height == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument.");
+
+  *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
+  if (! *bitmap)
+    return grub_errno;
+
+  mode_info = &((*bitmap)->mode_info);
+
+  /* Populate mode_info.  */
+  mode_info->width = width;
+  mode_info->height = height;
+  mode_info->blit_format = blit_format;
+
+  switch (blit_format)
+    {
+      case GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB 
+                               | GRUB_VIDEO_MODE_TYPE_ALPHA;
+        mode_info->bpp = 32;
+        mode_info->bytes_per_pixel = 4;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 8;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 8;
+        mode_info->green_field_pos = 8;
+        mode_info->blue_mask_size = 8;
+        mode_info->blue_field_pos = 16;
+        mode_info->reserved_mask_size = 8;
+        mode_info->reserved_field_pos = 24;
+        break;
+
+      case GRUB_VIDEO_BLIT_FORMAT_R8G8B8:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+        mode_info->bpp = 24;
+        mode_info->bytes_per_pixel = 3;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 8;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 8;
+        mode_info->green_field_pos = 8;
+        mode_info->blue_mask_size = 8;
+        mode_info->blue_field_pos = 16;
+        mode_info->reserved_mask_size = 0;
+        mode_info->reserved_field_pos = 0;
+        break;
+
+      case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+        mode_info->bpp = 8;
+        mode_info->bytes_per_pixel = 1;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 0;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 0;
+        mode_info->green_field_pos = 0;
+        mode_info->blue_mask_size = 0;
+        mode_info->blue_field_pos = 0;
+        mode_info->reserved_mask_size = 0;
+        mode_info->reserved_field_pos = 0;
+        break;
+
+      default:
+        grub_free (*bitmap);
+        *bitmap = 0;
+
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           "Unsupported bitmap format");
+    }
+
+  mode_info->pitch = width * mode_info->bytes_per_pixel;
+
+  /* Calculate size needed for the data.  */
+  size = (width * mode_info->bytes_per_pixel) * height;
+
+  (*bitmap)->data = grub_malloc (size);  
+  if (! (*bitmap)->data)
+    {
+      grub_free (*bitmap);
+      *bitmap = 0;
+
+      return grub_errno;
+    }
+
+  /* Clear bitmap.  */
+  grub_memset ((*bitmap)->data, 0, size);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Frees all resources allocated by bitmap.  */
+grub_err_t
+grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap)
+{
+  if (! bitmap)
+    return GRUB_ERR_NONE;
+
+  grub_free (bitmap->data);
+  grub_free (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Match extension to filename.  */
+static int
+match_extension (const char *filename, const char *ext)
+{
+  int pos;
+  int ext_len;
+
+  pos = grub_strlen (filename);
+  ext_len = grub_strlen (ext);
+
+  if (! pos || ! ext_len || ext_len > pos)
+    return 0;
+
+  pos -= ext_len;
+
+  return grub_strcmp (filename + pos, ext) == 0;
+}
+
+/* Loads bitmap using registered bitmap readers.  */
+grub_err_t
+grub_video_bitmap_load (struct grub_video_bitmap **bitmap, 
+                        const char *filename)
+{
+  grub_video_bitmap_reader_t reader = bitmap_readers_list;
+
+  if (!bitmap)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument.");
+
+  *bitmap = 0;
+
+  while (reader)
+    {
+      if (match_extension (filename, reader->extension))
+        return reader->reader (bitmap, filename);
+
+      reader = reader->next;
+    }
+
+  return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format");
+}
+
+/* Return bitmap width.  */
+unsigned int
+grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->mode_info.width;
+}
+
+/* Return bitmap height.  */
+unsigned int
+grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->mode_info.height;
+}
+
+/* Return mode info for bitmap.  */
+void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
+                                      struct grub_video_mode_info *mode_info)
+{
+  if (!bitmap)
+    return;
+
+  *mode_info = bitmap->mode_info;
+}
+
+/* Return pointer to bitmap's raw data.  */
+void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->data;
+}
+
+/* Initialize bitmap module.  */
+GRUB_MOD_INIT(video_bitmap)
+{
+}
+
+/* Finalize bitmap module.  */
+GRUB_MOD_FINI(video_bitmap)
+{
+}
index 846f12437ff6938971371b03b36912eeb19bd324..094dc676ddeb138baa59697bb28664f3c8aa9640 100644 (file)
 #include <grub/machine/vbe.h>
 #include <grub/machine/vbeblit.h>
 #include <grub/machine/vbefill.h>
+#include <grub/machine/vbeutil.h>
 #include <grub/types.h>
 #include <grub/dl.h>
 #include <grub/misc.h>
 #include <grub/font.h>
 #include <grub/mm.h>
 #include <grub/video.h>
+#include <grub/bitmap.h>
 
 /* Specify "standard" VGA palette, some video cards may
    need this and this will also be used when using RGB modes.  */
@@ -75,10 +77,6 @@ static grub_uint32_t initial_mode;
 static grub_uint32_t mode_in_use = 0x55aa;
 static grub_uint16_t *mode_list;
 
-static grub_video_color_t
-grub_video_vbe_map_rgba (grub_uint8_t red, grub_uint8_t green,
-                         grub_uint8_t blue, grub_uint8_t alpha);
-
 static void *
 real2pm (grub_vbe_farptr_t ptr)
 {
@@ -176,7 +174,7 @@ grub_vbe_set_video_mode (grub_uint32_t mode,
         default:
           return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
                              "unsupported pixel format 0x%x",
-                            active_mode_info.memory_model);
+                             active_mode_info.memory_model);
         }
     }
 
@@ -220,7 +218,7 @@ grub_vbe_set_video_mode (grub_uint32_t mode,
     default:
       grub_vbe_bios_set_mode (old_mode, 0);
       return grub_error (GRUB_ERR_BAD_DEVICE, 
-                         "cannot set VBE mode %x", 
+                         "cannot set VBE mode %x",
                          mode);
       break;
     }
@@ -238,7 +236,7 @@ grub_vbe_set_video_mode (grub_uint32_t mode,
                                                0, 
                                                palette);
 
-      /* Just ignore the status. */
+      /* Just ignore the status.  */
     }
 
   /* Copy mode info for caller.  */
@@ -299,35 +297,35 @@ grub_vbe_get_video_mode_info (grub_uint32_t mode,
 }
 
 grub_uint8_t *
-grub_video_vbe_get_video_ptr (struct grub_video_render_target *source,
+grub_video_vbe_get_video_ptr (struct grub_video_i386_vbeblit_info *source,
                               grub_uint32_t x, grub_uint32_t y)
 {
   grub_uint8_t *ptr = 0;
 
-  switch (source->mode_info.bpp)
+  switch (source->mode_info->bpp)
     {
     case 32:
       ptr = (grub_uint8_t *)source->data
-            + y * source->mode_info.pitch
+            + y * source->mode_info->pitch
             + x * 4;
       break;
 
     case 24:
       ptr = (grub_uint8_t *)source->data
-            + y * source->mode_info.pitch
+            + y * source->mode_info->pitch
             + x * 3;
       break;
 
     case 16:
     case 15:
       ptr = (grub_uint8_t *)source->data
-            + y * source->mode_info.pitch
+            + y * source->mode_info->pitch
             + x * 2;
       break;
 
     case 8:
       ptr = (grub_uint8_t *)source->data
-            + y * source->mode_info.pitch
+            + y * source->mode_info->pitch
             + x;
       break;
     }
@@ -335,112 +333,6 @@ grub_video_vbe_get_video_ptr (struct grub_video_render_target *source,
   return ptr;
 }
 
-static void
-grub_video_vbe_draw_pixel (grub_uint32_t x, grub_uint32_t y,
-                           grub_video_color_t color)
-{
-  if (x >= render_target->mode_info.width)
-    return;
-
-  if (y >= render_target->mode_info.height)
-    return;
-
-  switch (render_target->mode_info.bpp)
-    {
-    case 32:
-      {
-        grub_uint32_t *ptr;
-
-        ptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (render_target,
-                                                             x, y);
-
-        *ptr = color;
-      }
-      break;
-
-    case 24:
-      {
-        grub_uint8_t *ptr;
-        grub_uint8_t *ptr2 = (grub_uint8_t *) &color;
-
-        ptr = grub_video_vbe_get_video_ptr (render_target, x, y);
-
-        ptr[0] = ptr2[0];
-        ptr[1] = ptr2[1];
-        ptr[2] = ptr2[2];
-      }
-      break;
-
-    case 16:
-    case 15:
-      {
-        grub_uint16_t *ptr;
-
-        ptr = (grub_uint16_t *)grub_video_vbe_get_video_ptr (render_target,
-                                                             x, y);
-
-        *ptr = (grub_uint16_t) (color & 0xFFFF);
-      }
-      break;
-
-    case 8:
-      {
-        grub_uint8_t *ptr;
-
-        ptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (render_target,
-                                                            x, y);
-
-        *ptr = (grub_uint8_t) (color & 0xFF);
-      }
-      break;
-
-    default:
-      break;
-    }
-}
-
-static grub_video_color_t
-grub_video_vbe_get_pixel (struct grub_video_render_target *source,
-                          grub_uint32_t x, grub_uint32_t y)
-{
-  grub_video_color_t color = 0;
-
-  if (x >= source->mode_info.width)
-    return 0;
-
-  if (y >= source->mode_info.height)
-    return 0;
-
-  switch (source->mode_info.bpp)
-    {
-    case 32:
-      color = *(grub_uint32_t *)grub_video_vbe_get_video_ptr (source, x, y);
-      break;
-
-    case 24:
-      {
-        grub_uint8_t *ptr;
-        ptr = grub_video_vbe_get_video_ptr (source, x, y);
-        color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
-      }
-      break;
-
-    case 16:
-    case 15:
-      color = *(grub_uint16_t *)grub_video_vbe_get_video_ptr (source, x, y);
-      break;
-
-    case 8:
-      color = *(grub_uint8_t *)grub_video_vbe_get_video_ptr (source, x, y);
-      break;
-
-    default:
-      break;
-    }
-
-  return color;
-}
-
 static grub_err_t
 grub_video_vbe_init (void)
 {
@@ -482,7 +374,7 @@ grub_video_vbe_init (void)
     }
 
   /* Reset frame buffer and render target variables.  */
-  grub_memset (&framebuffer, 0, sizeof(framebuffer));  
+  grub_memset (&framebuffer, 0, sizeof(framebuffer));
   render_target = &framebuffer.render_target;
 
   return GRUB_ERR_NONE;
@@ -738,7 +630,7 @@ grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
   render_target->viewport.y = y;
   render_target->viewport.width = width;
   render_target->viewport.height = height;
-  
+
   return GRUB_ERR_NONE;
 }
 
@@ -836,7 +728,7 @@ grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green,
 
 }
 
-static grub_video_color_t
+grub_video_color_t
 grub_video_vbe_map_rgba (grub_uint8_t red, grub_uint8_t green,
                          grub_uint8_t blue, grub_uint8_t alpha)
 {
@@ -864,12 +756,15 @@ grub_video_vbe_map_rgba (grub_uint8_t red, grub_uint8_t green,
 }
 
 void
-grub_video_vbe_unmap_color (struct grub_video_render_target * source,
+grub_video_vbe_unmap_color (struct grub_video_i386_vbeblit_info * source,
                             grub_video_color_t color,
                             grub_uint8_t *red, grub_uint8_t *green,
                             grub_uint8_t *blue, grub_uint8_t *alpha)
 {
-  if ((source->mode_info.mode_type 
+  struct grub_video_mode_info *mode_info;
+  mode_info = source->mode_info;
+
+  if ((mode_info->mode_type 
        & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
     {
       /* If we have out of bounds color, return trasnparent black.  */
@@ -893,33 +788,33 @@ grub_video_vbe_unmap_color (struct grub_video_render_target * source,
       grub_uint32_t tmp;
 
       /* Get red component.  */
-      tmp = color >> source->mode_info.red_field_pos;
-      tmp &= (1 << source->mode_info.red_mask_size) - 1;
-      tmp <<= 8 - source->mode_info.red_mask_size;
-      tmp |= (1 << (8 - source->mode_info.red_mask_size)) - 1;
+      tmp = color >> mode_info->red_field_pos;
+      tmp &= (1 << mode_info->red_mask_size) - 1;
+      tmp <<= 8 - mode_info->red_mask_size;
+      tmp |= (1 << (8 - mode_info->red_mask_size)) - 1;
       *red = tmp & 0xFF;
 
       /* Get green component.  */
-      tmp = color >> source->mode_info.green_field_pos;
-      tmp &= (1 << source->mode_info.green_mask_size) - 1;
-      tmp <<= 8 - source->mode_info.green_mask_size;
-      tmp |= (1 << (8 - source->mode_info.green_mask_size)) - 1;
+      tmp = color >> mode_info->green_field_pos;
+      tmp &= (1 << mode_info->green_mask_size) - 1;
+      tmp <<= 8 - mode_info->green_mask_size;
+      tmp |= (1 << (8 - mode_info->green_mask_size)) - 1;
       *green = tmp & 0xFF;
 
       /* Get blue component.  */
-      tmp = color >> source->mode_info.blue_field_pos;
-      tmp &= (1 << source->mode_info.blue_mask_size) - 1;
-      tmp <<= 8 - source->mode_info.blue_mask_size;
-      tmp |= (1 << (8 - source->mode_info.blue_mask_size)) - 1;
+      tmp = color >> mode_info->blue_field_pos;
+      tmp &= (1 << mode_info->blue_mask_size) - 1;
+      tmp <<= 8 - mode_info->blue_mask_size;
+      tmp |= (1 << (8 - mode_info->blue_mask_size)) - 1;
       *blue = tmp & 0xFF;
 
       /* Get alpha component.  */
-      if (source->mode_info.reserved_mask_size > 0)
+      if (source->mode_info->reserved_mask_size > 0)
         {
-          tmp = color >> source->mode_info.reserved_field_pos;
-          tmp &= (1 << source->mode_info.reserved_mask_size) - 1;
-          tmp <<= 8 - source->mode_info.reserved_mask_size;
-          tmp |= (1 << (8 - source->mode_info.reserved_mask_size)) - 1;
+          tmp = color >> mode_info->reserved_field_pos;
+          tmp &= (1 << mode_info->reserved_mask_size) - 1;
+          tmp <<= 8 - mode_info->reserved_mask_size;
+          tmp |= (1 << (8 - mode_info->reserved_mask_size)) - 1;
         }
       else
         /* If there is no alpha component, assume it opaque.  */
@@ -933,7 +828,7 @@ static grub_err_t
 grub_video_vbe_fill_rect (grub_video_color_t color, int x, int y,
                           unsigned int width, unsigned int height)
 {
-  unsigned int i, j;
+  struct grub_video_i386_vbeblit_info target;
 
   /* Make sure there is something to do.  */
   if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
@@ -962,40 +857,44 @@ grub_video_vbe_fill_rect (grub_video_color_t color, int x, int y,
   x += render_target->viewport.x;
   y += render_target->viewport.y;
 
+  /* Use vbeblit_info to encapsulate rendering.  */
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
   /* Try to figure out more optimized version.  */
-  if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
     {
-      grub_video_i386_vbefill_R8G8B8A8 (render_target, color, x, y, 
+      grub_video_i386_vbefill_R8G8B8A8 (&target, color, x, y, 
                                         width, height);
       return GRUB_ERR_NONE;
     }
 
-  if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
     {
-      grub_video_i386_vbefill_R8G8B8 (render_target, color, x, y,
+      grub_video_i386_vbefill_R8G8B8 (&target, color, x, y,
                                       width, height);
       return GRUB_ERR_NONE;
     }
 
-  if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
     {
-      grub_video_i386_vbefill_index (render_target, color, x, y,
+      grub_video_i386_vbefill_index (&target, color, x, y,
                                      width, height);
       return GRUB_ERR_NONE;
     }
 
-  /* Use backup method to fill area.  */
-  for (j = 0; j < height; j++)
-    for (i = 0; i < width; i++)
-      grub_video_vbe_draw_pixel (x+i, y+j, color);
+  /* No optimized version found, use default (slow) filler.  */
+  grub_video_i386_vbefill (&target, color, x, y, width, height);
 
   return GRUB_ERR_NONE;
 }
 
+// TODO: Remove this method and replace with bitmap based glyphs
 static grub_err_t
 grub_video_vbe_blit_glyph (struct grub_font_glyph * glyph,
                            grub_video_color_t color, int x, int y)
 {
+  struct grub_video_i386_vbeblit_info target;
   unsigned int width;
   unsigned int charwidth;
   unsigned int height;
@@ -1045,29 +944,204 @@ grub_video_vbe_blit_glyph (struct grub_font_glyph * glyph,
   x += render_target->viewport.x;
   y += render_target->viewport.y;
 
+  /* Use vbeblit_info to encapsulate rendering.  */
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
   /* Draw glyph.  */
   for (j = 0; j < height; j++)
     for (i = 0; i < width; i++)
       if ((glyph->bitmap[((i + x_offset) / 8) 
                          + (j + y_offset) * (charwidth / 8)] 
            & (1 << ((charwidth - (i + x_offset) - 1) % 8))))
-        grub_video_vbe_draw_pixel (x+i, y+j, color);
+        set_pixel (&target, x+i, y+j, color);
 
   return GRUB_ERR_NONE;
 }
 
+/* NOTE: This function assumes that given coordiantes are within bounds of 
+   handled data.  */
+static void
+common_blitter (struct grub_video_i386_vbeblit_info *target,
+                struct grub_video_i386_vbeblit_info *source,
+                enum grub_video_blit_operators oper, int x, int y,
+                unsigned int width, unsigned int height,
+                int offset_x, int offset_y)
+{
+  if (oper == GRUB_VIDEO_BLIT_REPLACE)
+    {
+      /* Try to figure out more optimized version for replace operator.  */
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+        {
+          if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+            {
+              grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8 (target, source,
+                                                         x, y, width, height,
+                                                         offset_x, offset_y);
+              return;
+            }
+
+          if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+            {
+              grub_video_i386_vbeblit_R8G8B8_R8G8B8X8 (target, source,
+                                                       x, y, width, height,
+                                                       offset_x, offset_y);
+              return;
+            }
+
+          if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+            {
+              grub_video_i386_vbeblit_index_R8G8B8X8 (target, source,
+                                                      x, y, width, height,
+                                                      offset_x, offset_y);
+              return;
+            }
+        }
+
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+        {
+          if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+            {
+              grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (target, source,
+                                                       x, y, width, height,
+                                                       offset_x, offset_y);
+              return;
+            }
+
+          if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+            {
+              grub_video_i386_vbeblit_R8G8B8_R8G8B8 (target, source,
+                                                     x, y, width, height,
+                                                     offset_x, offset_y);
+              return;
+            }
+
+          if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+            {
+              grub_video_i386_vbeblit_index_R8G8B8 (target, source,
+                                                    x, y, width, height,
+                                                    offset_x, offset_y);
+              return;
+            }
+        }
+
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+        {
+          if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+            {
+              grub_video_i386_vbeblit_index_index (target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+              return;
+            }
+        }
+
+      /* No optimized replace operator found, use default (slow) blitter.  */
+      grub_video_i386_vbeblit_replace (target, source, x, y, width, height,
+                                       offset_x, offset_y);
+    }
+  else
+    {
+      /* Try to figure out more optimized blend operator.  */
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+      {
+        if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+        {
+          grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (target, source,
+              x, y, width, height,
+              offset_x, offset_y);
+          return;
+        }
+
+        if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+        {
+          grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (target, source,
+              x, y, width, height,
+              offset_x, offset_y);
+          return;
+        }
+
+        if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+        {
+          grub_video_i386_vbeblit_index_R8G8B8A8 (target, source,
+              x, y, width, height,
+              offset_x, offset_y);
+          return;
+        }
+      }
+
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+      {
+        if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+        {
+          grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (target, source,
+              x, y, width, height,
+              offset_x, offset_y);
+          return;
+        }
+
+        if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+        {
+          grub_video_i386_vbeblit_R8G8B8_R8G8B8 (target, source,
+              x, y, width, height,
+              offset_x, offset_y);
+          return;
+        }
+
+        if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+        {
+          grub_video_i386_vbeblit_index_R8G8B8 (target, source,
+              x, y, width, height,
+              offset_x, offset_y);
+          return;
+        }
+      }
+
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+      {
+        if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+        {
+          grub_video_i386_vbeblit_index_index (target, source,
+                                               x, y, width, height,
+                                               offset_x, offset_y);
+          return;
+        }
+      }
+
+      /* No optimized blend operation found, use default (slow) blitter.  */
+      grub_video_i386_vbeblit_blend (target, source, x, y, width, height,
+                                     offset_x, offset_y);
+    }
+}
+
 static grub_err_t
-grub_video_vbe_blit_bitmap (struct grub_video_bitmap * bitmap,
-                            int x, int y, int offset_x, int offset_y,
+grub_video_vbe_blit_bitmap (struct grub_video_bitmap *bitmap,
+                            enum grub_video_blit_operators oper, int x, int y,
+                            int offset_x, int offset_y,
                             unsigned int width, unsigned int height)
 {
+  struct grub_video_i386_vbeblit_info source;
+  struct grub_video_i386_vbeblit_info target;
+
   /* Make sure there is something to do.  */
+  if ((width == 0) || (height == 0))
+    return GRUB_ERR_NONE;
   if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
     return GRUB_ERR_NONE;
   if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
     return GRUB_ERR_NONE;
+  if ((x + (int)bitmap->mode_info.width) < 0)
+    return GRUB_ERR_NONE;
+  if ((y + (int)bitmap->mode_info.height) < 0)
+    return GRUB_ERR_NONE;
+  if ((offset_x >= (int)bitmap->mode_info.width) 
+      || (offset_x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((offset_y >= (int)bitmap->mode_info.height) 
+      || (offset_y + (int)height < 0))
+    return GRUB_ERR_NONE;
 
-  /* Do not allow drawing out of viewport.  */
+  /* If we have negative coordinates, optimize drawing to minimum.  */
   if (offset_x < 0)
     {
       width += offset_x;
@@ -1085,39 +1159,60 @@ grub_video_vbe_blit_bitmap (struct grub_video_bitmap * bitmap,
   if (x < 0)
     {
       width += x;
-      offset_x += (unsigned int)-x;
+      offset_x -= x;
       x = 0;
     }
+
   if (y < 0)
     {
       height += y;
-      offset_y += (unsigned int)-y;
+      offset_y -= y;
       y = 0;
     }
 
+  /* Do not allow drawing out of viewport.  */
   if ((x + width) > render_target->viewport.width)
     width = render_target->viewport.width - x;
   if ((y + height) > render_target->viewport.height)
     height = render_target->viewport.height - y;
 
-  /* TODO: Limit drawing to bitmap dimensions.  */
+  if ((offset_x + width) > bitmap->mode_info.width)
+    width = bitmap->mode_info.width - offset_x;
+  if ((offset_y + height) > bitmap->mode_info.height)
+    height = bitmap->mode_info.height - offset_y;
+
+  /* Limit drawing to source render target dimensions.  */
+  if (width > bitmap->mode_info.width)
+    width = bitmap->mode_info.width;
+
+  if (height > bitmap->mode_info.height)
+    height = bitmap->mode_info.height;
 
   /* Add viewport offset.  */
   x += render_target->viewport.x;
   y += render_target->viewport.y;
 
-  /* TODO: Render bitmap.  */
+  /* Use vbeblit_info to encapsulate rendering.  */
+  source.mode_info = &bitmap->mode_info;
+  source.data = bitmap->data;
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
+  /* Do actual blitting.  */
+  common_blitter (&target, &source, oper, x, y, width, height,
+                  offset_x, offset_y);
 
   return GRUB_ERR_NONE;
 }
 
 static grub_err_t
 grub_video_vbe_blit_render_target (struct grub_video_render_target *source,
+                                   enum grub_video_blit_operators oper,
                                    int x, int y, int offset_x, int offset_y,
                                    unsigned int width, unsigned int height)
 {
-  unsigned int i;
-  unsigned int j;
+  struct grub_video_i386_vbeblit_info source_info;
+  struct grub_video_i386_vbeblit_info target_info;
 
   /* Make sure there is something to do.  */
   if ((width == 0) || (height == 0))
@@ -1125,17 +1220,17 @@ grub_video_vbe_blit_render_target (struct grub_video_render_target *source,
   if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
     return GRUB_ERR_NONE;
   if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
-    return GRUB_ERR_NONE;    
+    return GRUB_ERR_NONE;
   if ((x + (int)source->mode_info.width) < 0)
     return GRUB_ERR_NONE;
   if ((y + (int)source->mode_info.height) < 0)
-    return GRUB_ERR_NONE;    
+    return GRUB_ERR_NONE;
   if ((offset_x >= (int)source->mode_info.width) 
       || (offset_x + (int)width < 0))
     return GRUB_ERR_NONE;
   if ((offset_y >= (int)source->mode_info.height) 
       || (offset_y + (int)height < 0))
-    return GRUB_ERR_NONE;    
+    return GRUB_ERR_NONE;
 
   /* If we have negative coordinates, optimize drawing to minimum.  */
   if (offset_x < 0)
@@ -1155,14 +1250,14 @@ grub_video_vbe_blit_render_target (struct grub_video_render_target *source,
   if (x < 0)
     {
       width += x;
-      offset_x += (unsigned int)-x;
+      offset_x -= x;
       x = 0;
     }
 
   if (y < 0)
     {
       height += y;
-      offset_y += (unsigned int)-y;
+      offset_y -= y;
       y = 0;
     }
 
@@ -1188,122 +1283,15 @@ grub_video_vbe_blit_render_target (struct grub_video_render_target *source,
   x += render_target->viewport.x;
   y += render_target->viewport.y;
 
-  /* Try to figure out more optimized version.  */
-  if (source->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
-    {
-      if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
-        {
-          grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (render_target, source,
-                                                     x, y, width, height,
-                                                     offset_x, offset_y);
-          return GRUB_ERR_NONE;
-        }
-
-      if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
-        {
-          grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (render_target, source,
-                                                   x, y, width, height,
-                                                   offset_x, offset_y);
-          return GRUB_ERR_NONE;
-        }
-
-      if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-        {
-          grub_video_i386_vbeblit_index_R8G8B8A8 (render_target, source,
-                                                  x, y, width, height,
-                                                  offset_x, offset_y);
-          return GRUB_ERR_NONE;
-        }
-    }
-
-  if (source->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
-    {
-      if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
-        {
-          grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (render_target, source,
-                                                   x, y, width, height,
-                                                   offset_x, offset_y);
-          return GRUB_ERR_NONE;
-        }
-
-      if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
-        {
-          grub_video_i386_vbeblit_R8G8B8_R8G8B8 (render_target, source,
-                                                 x, y, width, height,
-                                                 offset_x, offset_y);
-          return GRUB_ERR_NONE;
-        }
-
-      if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-        {
-          grub_video_i386_vbeblit_index_R8G8B8 (render_target, source,
-                                                x, y, width, height,
-                                                offset_x, offset_y);
-          return GRUB_ERR_NONE;
-        }
-    }
-
-  if (source->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-    {
-      if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-        {
-          grub_video_i386_vbeblit_index_index (render_target, source,
-                                               x, y, width, height,
-                                               offset_x, offset_y);
-          return GRUB_ERR_NONE;
-        }
-    }
-
-  /* Use backup method to render.  */
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t src_red;
-          grub_uint8_t src_green;
-          grub_uint8_t src_blue;
-          grub_uint8_t src_alpha;
-          grub_uint8_t dst_red;
-          grub_uint8_t dst_green;
-          grub_uint8_t dst_blue;
-          grub_uint8_t dst_alpha;
-          grub_video_color_t src_color;
-          grub_video_color_t dst_color;
-
-          src_color = grub_video_vbe_get_pixel (source, i + offset_x, j + offset_y);
-          grub_video_vbe_unmap_color (source, src_color, &src_red, &src_green, 
-                                      &src_blue, &src_alpha);
-
-          if (src_alpha == 0)
-            continue;
-
-          if (src_alpha == 255)
-            {
-              dst_color = grub_video_vbe_map_rgba (src_red, src_green,
-                                                   src_blue, src_alpha);
-               grub_video_vbe_draw_pixel (x + i, y + j, dst_color);
-               continue;
-            }
+  /* Use vbeblit_info to encapsulate rendering.  */
+  source_info.mode_info = &source->mode_info;
+  source_info.data = source->data;
+  target_info.mode_info = &render_target->mode_info;
+  target_info.data = render_target->data;
 
-          dst_color = grub_video_vbe_get_pixel (render_target, x + i, y + j);
-
-          grub_video_vbe_unmap_color (render_target,  dst_color, &dst_red, 
-                                      &dst_green, &dst_blue, &dst_alpha);
-
-          dst_red = (((src_red * src_alpha)
-                      + (dst_red * (255 - src_alpha))) / 255);
-          dst_green = (((src_green * src_alpha)
-                        + (dst_green * (255 - src_alpha))) / 255);
-          dst_blue = (((src_blue * src_alpha)
-                       + (dst_blue * (255 - src_alpha))) / 255);
-
-          dst_alpha = src_alpha;
-          dst_color = grub_video_vbe_map_rgba (dst_red, dst_green, dst_blue,
-                                               dst_alpha);
-
-          grub_video_vbe_draw_pixel (x + i, y + j, dst_color);
-        }
-    }
+  /* Do actual blitting.  */
+  common_blitter (&target_info, &source_info, oper, x, y, width, height, 
+                  offset_x, offset_y);
 
   return GRUB_ERR_NONE;
 }
@@ -1352,16 +1340,20 @@ grub_video_vbe_scroll (grub_video_color_t color, int dx, int dy)
        && (grub_abs (dy) < render_target->viewport.height))
     {
       /* 3. Move data in render target.  */
+      struct grub_video_i386_vbeblit_info target;
       grub_uint8_t *src;
       grub_uint8_t *dst;
       int j;
 
+      target.mode_info = &render_target->mode_info;
+      target.data = render_target->data;
+
       for (j = 0; j < height; j++)
         {
-          dst = grub_video_vbe_get_video_ptr (render_target, dst_x, dst_y + j);
-          src = grub_video_vbe_get_video_ptr (render_target, src_x, src_y + j);
+          dst = grub_video_vbe_get_video_ptr (&target, dst_x, dst_y + j);
+          src = grub_video_vbe_get_video_ptr (&target, src_x, src_y + j);
           grub_memmove (dst, src,
-                        width * render_target->mode_info.bytes_per_pixel);
+                        width * target.mode_info->bytes_per_pixel);
         }
     }
 
@@ -1544,7 +1536,7 @@ static struct grub_video_adapter grub_video_vbe_adapter =
     .delete_render_target = grub_video_vbe_delete_render_target,
     .set_active_render_target = grub_video_vbe_set_active_render_target,
 
-    .next = 0  
+    .next = 0
   };
 
 GRUB_MOD_INIT(video_i386_pc_vbe)
index 9cce2541c3dfffcdb6529a4d93b92851be6205c7..c462237b4f9e5e5efc02f426b8239fc388f4c9e5 100644 (file)
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <grub/err.h>
-#include <grub/machine/memory.h>
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+   bus.  If there are different address spaces do not use this code as a base
+   code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+   previous phase and they are opted out in here.  */
+
 #include <grub/machine/vbe.h>
 #include <grub/machine/vbeblit.h>
-#include <grub/types.h>
-#include <grub/dl.h>
+#include <grub/machine/vbeutil.h>
 #include <grub/misc.h>
-#include <grub/font.h>
-#include <grub/mm.h>
+#include <grub/types.h>
 #include <grub/video.h>
 
 void
-grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_render_target *dst,
-                                           struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
+                                           struct grub_video_i386_vbeblit_info *src,
                                            int x, int y, int width, int height,
                                            int offset_x, int offset_y)
 {
@@ -52,10 +59,8 @@ grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_render_target *dst,
 
   for (j = 0; j < height; j++)
     {
-      srcptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (src, offset_x,
-                                                              j + offset_y);
-
-      dstptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+      srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j);
 
       for (i = 0; i < width; i++)
         {
@@ -97,8 +102,33 @@ grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_render_target *dst,
 }
 
 void
-grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_render_target *dst,
-                                         struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8 (struct grub_video_i386_vbeblit_info *dst,
+                                           struct grub_video_i386_vbeblit_info *src,
+                                           int x, int y, int width, int height,
+                                           int offset_x, int offset_y)
+{
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  int pitch;
+
+  pitch = src->mode_info->bytes_per_pixel;
+
+  /* We do not need to worry about data being out of bounds
+     as we assume that everything has been checked before.  */
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j);
+
+      grub_memmove (dstptr, srcptr, width * pitch);
+    }
+}
+
+void
+grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
+                                         struct grub_video_i386_vbeblit_info *src,
                                          int x, int y, int width, int height,
                                          int offset_x, int offset_y)
 {
@@ -120,10 +150,8 @@ grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_render_target *dst,
 
   for (j = 0; j < height; j++)
     {
-      srcptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (src, offset_x,
-                                                              j + offset_y);
-
-      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+      srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
 
       for (i = 0; i < width; i++)
         {
@@ -166,8 +194,46 @@ grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_render_target *dst,
 }
 
 void
-grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_render_target *dst,
-                                        struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8_R8G8B8X8 (struct grub_video_i386_vbeblit_info *dst,
+                                         struct grub_video_i386_vbeblit_info *src,
+                                         int x, int y, int width, int height,
+                                         int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  /* We do not need to worry about data being out of bounds
+     as we assume that everything has been checked before.  */
+
+  for (j = 0; j < height; j++)
+  {
+    srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+    dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
+
+    for (i = 0; i < width; i++)
+    {
+      color = *srcptr++;
+
+      sr = (color >> 0) & 0xFF;
+      sg = (color >> 8) & 0xFF;
+      sb = (color >> 16) & 0xFF;
+
+      *dstptr++ = sr;
+      *dstptr++ = sg;
+      *dstptr++ = sb;
+    }
+  }
+}
+
+void
+grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
+                                        struct grub_video_i386_vbeblit_info *src,
                                         int x, int y, int width, int height,
                                         int offset_x, int offset_y)
 {
@@ -190,10 +256,8 @@ grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_render_target *dst,
 
   for (j = 0; j < height; j++)
     {
-      srcptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (src, offset_x,
-                                                              j + offset_y);
-
-      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+      srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
 
       for (i = 0; i < width; i++)
         {
@@ -232,8 +296,45 @@ grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_render_target *dst,
 }
 
 void
-grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_render_target *dst,
-                                         struct grub_video_render_target *src,
+grub_video_i386_vbeblit_index_R8G8B8X8 (struct grub_video_i386_vbeblit_info *dst,
+                                        struct grub_video_i386_vbeblit_info *src,
+                                        int x, int y, int width, int height,
+                                        int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  /* We do not need to worry about data being out of bounds
+  as we assume that everything has been checked before.  */
+
+  for (j = 0; j < height; j++)
+  {
+    srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+    dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
+
+    for (i = 0; i < width; i++)
+    {
+      color = *srcptr++;
+
+      sr = (color >> 0) & 0xFF;
+      sg = (color >> 8) & 0xFF;
+      sb = (color >> 16) & 0xFF;
+
+      color = grub_video_vbe_map_rgb(sr, sg, sb);
+      *dstptr++ = color & 0xFF;
+    }
+  }
+}
+
+void
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
+                                         struct grub_video_i386_vbeblit_info *src,
                                          int x, int y, int width, int height,
                                          int offset_x, int offset_y)
 {
@@ -251,10 +352,8 @@ grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_render_target *dst,
 
   for (j = 0; j < height; j++)
     {
-      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, offset_x,
-                                                             j + offset_y);
-
-      dstptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+      srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j);
 
       for (i = 0; i < width; i++)
         {
@@ -270,41 +369,33 @@ grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_render_target *dst,
 }
 
 void
-grub_video_i386_vbeblit_R8G8B8_R8G8B8 (struct grub_video_render_target *dst,
-                                       struct grub_video_render_target *src,
+grub_video_i386_vbeblit_R8G8B8_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
+                                       struct grub_video_i386_vbeblit_info *src,
                                        int x, int y, int width, int height,
                                        int offset_x, int offset_y)
 {
-  int i;
   int j;
   grub_uint8_t *srcptr;
   grub_uint8_t *dstptr;
+  int pitch;
+
+  pitch = src->mode_info->bytes_per_pixel;
 
   /* We do not need to worry about data being out of bounds
      as we assume that everything has been checked before.  */
 
   for (j = 0; j < height; j++)
     {
-      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, 
-                                                             offset_x,
-                                                             j + offset_y);
+      srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
 
-      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst,
-                                                             x, 
-                                                             y + j);
-
-      for (i = 0; i < width; i++)
-        {
-          *dstptr ++ = *srcptr++;
-          *dstptr ++ = *srcptr++;
-          *dstptr ++ = *srcptr++;
-        }
+      grub_memmove (dstptr, srcptr, width * pitch);
     }
 }
 
 void
-grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_render_target *dst,
-                                      struct grub_video_render_target *src,
+grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
+                                      struct grub_video_i386_vbeblit_info *src,
                                       int x, int y, int width, int height,
                                       int offset_x, int offset_y)
 {
@@ -322,10 +413,8 @@ grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_render_target *dst,
 
   for (j = 0; j < height; j++)
     {
-      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, offset_x,
-                                                             j + offset_y);
-
-      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+      srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
 
       for (i = 0; i < width; i++)
         {
@@ -341,27 +430,122 @@ grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_render_target *dst,
 }
 
 void
-grub_video_i386_vbeblit_index_index (struct grub_video_render_target *dst,
-                                     struct grub_video_render_target *src,
+grub_video_i386_vbeblit_index_index (struct grub_video_i386_vbeblit_info *dst,
+                                     struct grub_video_i386_vbeblit_info *src,
                                      int x, int y, int width, int height,
                                      int offset_x, int offset_y)
 {
-  int i;
   int j;
   grub_uint8_t *srcptr;
   grub_uint8_t *dstptr;
+  int pitch;
+
+  pitch = src->mode_info->bytes_per_pixel;
 
   /* We do not need to worry about data being out of bounds
      as we assume that everything has been checked before.  */
 
   for (j = 0; j < height; j++)
     {
-      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, offset_x,
-                                                             j + offset_y);
+      srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
+
+      grub_memmove (dstptr, srcptr, width * pitch);
+    }
+}
+
+void
+grub_video_i386_vbeblit_blend (struct grub_video_i386_vbeblit_info *dst,
+                               struct grub_video_i386_vbeblit_info *src,
+                               int x, int y, int width, int height,
+                               int offset_x, int offset_y)
+{
+  int i;
+  int j;
 
-      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+  /* We do not need to worry about data being out of bounds
+     as we assume that everything has been checked before.  */
 
+  for (j = 0; j < height; j++)
+    {
       for (i = 0; i < width; i++)
-          *dstptr++ = *srcptr++;
+        {
+          grub_uint8_t src_red;
+          grub_uint8_t src_green;
+          grub_uint8_t src_blue;
+          grub_uint8_t src_alpha;
+          grub_uint8_t dst_red;
+          grub_uint8_t dst_green;
+          grub_uint8_t dst_blue;
+          grub_uint8_t dst_alpha;
+          grub_video_color_t src_color;
+          grub_video_color_t dst_color;
+
+          src_color = get_pixel (src, i + offset_x, j + offset_y);
+          grub_video_vbe_unmap_color (src, src_color, &src_red, &src_green,
+                                      &src_blue, &src_alpha);
+
+          if (src_alpha == 0)
+            continue;
+
+          if (src_alpha == 255)
+            {
+              dst_color = grub_video_vbe_map_rgba (src_red, src_green,
+                                                   src_blue, src_alpha);
+              set_pixel (dst, x + i, y + j, dst_color);
+              continue;
+            }
+
+          dst_color = get_pixel (dst, x + i, y + j);
+
+          grub_video_vbe_unmap_color (dst, dst_color, &dst_red,
+                                      &dst_green, &dst_blue, &dst_alpha);
+
+          dst_red = (((src_red * src_alpha)
+                      + (dst_red * (255 - src_alpha))) / 255);
+          dst_green = (((src_green * src_alpha)
+                        + (dst_green * (255 - src_alpha))) / 255);
+          dst_blue = (((src_blue * src_alpha)
+                       + (dst_blue * (255 - src_alpha))) / 255);
+
+          dst_alpha = src_alpha;
+          dst_color = grub_video_vbe_map_rgba (dst_red, dst_green, dst_blue,
+                                               dst_alpha);
+
+          set_pixel (dst, x + i, y + j, dst_color);
+        }
+    }
+}
+
+void
+grub_video_i386_vbeblit_replace (struct grub_video_i386_vbeblit_info *dst,
+                                 struct grub_video_i386_vbeblit_info *src,
+                                 int x, int y, int width, int height,
+                                 int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t src_red;
+  grub_uint8_t src_green;
+  grub_uint8_t src_blue;
+  grub_uint8_t src_alpha;
+  grub_video_color_t src_color;
+  grub_video_color_t dst_color;
+
+  /* We do not need to worry about data being out of bounds
+     as we assume that everything has been checked before.  */
+
+  for (j = 0; j < height; j++)
+  {
+    for (i = 0; i < width; i++)
+    {
+      src_color = get_pixel (src, i + offset_x, j + offset_y);
+      grub_video_vbe_unmap_color (src, src_color, &src_red, &src_green,
+                                  &src_blue, &src_alpha);
+
+      dst_color = grub_video_vbe_map_rgba (src_red, src_green,
+                                           src_blue, src_alpha);
+      set_pixel (dst, x + i, y + j, dst_color);
     }
+  }
 }
index d31e21af458facd31ab8356a0d4102e76bbb0e86..3c6dbfbb2d0f9fe5259a5536b6017ab403b18486 100644 (file)
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <grub/err.h>
-#include <grub/machine/memory.h>
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+     bus.  If there are different address spaces do not use this code as a base
+     code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+     previous phase and they are opted out in here.  */
+
 #include <grub/machine/vbe.h>
 #include <grub/machine/vbefill.h>
+#include <grub/machine/vbeutil.h>
 #include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/font.h>
-#include <grub/mm.h>
 #include <grub/video.h>
 
 void
-grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
                                   grub_video_color_t color, int x, int y,
                                   int width, int height)
 {
@@ -50,7 +56,7 @@ grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_render_target *dst,
 }
 
 void
-grub_video_i386_vbefill_R8G8B8 (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
                                 grub_video_color_t color, int x, int y,
                                 int width, int height)
 {
@@ -78,7 +84,7 @@ grub_video_i386_vbefill_R8G8B8 (struct grub_video_render_target *dst,
 }
 
 void
-grub_video_i386_vbefill_index (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_index (struct grub_video_i386_vbeblit_info *dst,
                                grub_video_color_t color, int x, int y,
                                int width, int height)
 {
@@ -98,3 +104,19 @@ grub_video_i386_vbefill_index (struct grub_video_render_target *dst,
         *dstptr++ = fill;
     }
 }
+
+void
+grub_video_i386_vbefill (struct grub_video_i386_vbeblit_info *dst,
+                         grub_video_color_t color, int x, int y,
+                         int width, int height)
+{
+  int i;
+  int j;
+
+  /* We do not need to worry about data being out of bounds
+     as we assume that everything has been checked before.  */
+
+  for (j = 0; j < height; j++)
+    for (i = 0; i < width; i++)
+      set_pixel (dst, x+i, y+j, color);
+}
diff --git a/video/i386/pc/vbeutil.c b/video/i386/pc/vbeutil.c
new file mode 100644 (file)
index 0000000..116ee78
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/machine/vbeutil.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+grub_uint8_t *
+get_data_ptr (struct grub_video_i386_vbeblit_info *source,
+              unsigned int x, unsigned int y)
+{
+  grub_uint8_t *ptr = 0;
+
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      ptr = (grub_uint8_t *)source->data
+            + y * source->mode_info->pitch
+            + x * 4;
+      break;
+
+    case 24:
+      ptr = (grub_uint8_t *)source->data
+            + y * source->mode_info->pitch
+            + x * 3;
+      break;
+
+    case 16:
+    case 15:
+      ptr = (grub_uint8_t *)source->data
+            + y * source->mode_info->pitch
+            + x * 2;
+      break;
+
+    case 8:
+      ptr = (grub_uint8_t *)source->data
+            + y * source->mode_info->pitch
+            + x;
+      break;
+    }
+
+  return ptr;
+}
+
+grub_video_color_t
+get_pixel (struct grub_video_i386_vbeblit_info *source,
+           unsigned int x, unsigned int y)
+{
+  grub_video_color_t color = 0;
+
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      color = *(grub_uint32_t *)get_data_ptr (source, x, y);
+      break;
+
+    case 24:
+      {
+        grub_uint8_t *ptr;
+        ptr = get_data_ptr (source, x, y);
+        color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
+      }
+      break;
+
+    case 16:
+    case 15:
+      color = *(grub_uint16_t *)get_data_ptr (source, x, y);
+      break;
+
+    case 8:
+      color = *(grub_uint8_t *)get_data_ptr (source, x, y);
+      break;
+
+    default:
+      break;
+    }
+
+  return color;
+}
+
+void
+set_pixel (struct grub_video_i386_vbeblit_info *source,
+           unsigned int x, unsigned int y, grub_video_color_t color)
+{
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      {
+        grub_uint32_t *ptr;
+
+        ptr = (grub_uint32_t *)get_data_ptr (source, x, y);
+
+        *ptr = color;
+      }
+      break;
+
+    case 24:
+      {
+        grub_uint8_t *ptr;
+        grub_uint8_t *colorptr = (grub_uint8_t *)&color;
+
+        ptr = get_data_ptr (source, x, y);
+
+        ptr[0] = colorptr[0];
+        ptr[1] = colorptr[1];
+        ptr[2] = colorptr[2];
+      }
+      break;
+
+    case 16:
+    case 15:
+      {
+        grub_uint16_t *ptr;
+
+        ptr = (grub_uint16_t *)get_data_ptr (source, x, y);
+
+        *ptr = (grub_uint16_t) (color & 0xFFFF);
+      }
+      break;
+
+    case 8:
+      {
+        grub_uint8_t *ptr;
+
+        ptr = (grub_uint8_t *)get_data_ptr (source, x, y);
+
+        *ptr = (grub_uint8_t) (color & 0xFF);
+      }
+      break;
+
+    default:
+      break;
+    }
+}
diff --git a/video/readers/tga.c b/video/readers/tga.c
new file mode 100644 (file)
index 0000000..bdc44fa
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/arg.h>
+#include <grub/file.h>
+
+/* Uncomment following define to enable TGA debug.  */
+//#define TGA_DEBUG
+
+#if defined(TGA_DEBUG)
+#define dump_int_field(x) grub_printf( #x " = %d (0x%04x)\n", x, x);
+#endif
+
+enum
+{
+  GRUB_TGA_IMAGE_TYPE_NONE = 0,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR = 1,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR = 2,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE = 3,
+  GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR = 9,
+  GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR = 10,
+  GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE = 11,
+};
+
+enum
+{
+  GRUB_TGA_COLOR_MAP_TYPE_NONE = 0,
+  GRUB_TGA_COLOR_MAP_TYPE_INCLUDED = 1
+};
+
+enum
+{
+  GRUB_TGA_IMAGE_ORIGIN_RIGHT = 0x10,
+  GRUB_TGA_IMAGE_ORIGIN_TOP   = 0x20
+};
+
+struct grub_tga_header
+{
+  grub_uint8_t id_length;
+  grub_uint8_t color_map_type;
+  grub_uint8_t image_type;
+
+  /* Color Map Specification.  */
+  grub_uint16_t color_map_first_index;
+  grub_uint16_t color_map_length;
+  grub_uint8_t color_map_bpp;
+
+  /* Image Specification.  */
+  grub_uint16_t image_x_origin;
+  grub_uint16_t image_y_origin;
+  grub_uint16_t image_width;
+  grub_uint16_t image_height;
+  grub_uint8_t image_bpp;
+  grub_uint8_t image_descriptor;
+} __attribute__ ((packed));
+
+static grub_err_t
+tga_load_truecolor_rle_R8G8B8 (struct grub_video_bitmap *bitmap,
+                               struct grub_tga_header *header,
+                               grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t type;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width;)
+        {
+          if (grub_file_read (file, (char *)&type, sizeof (type)) != sizeof(type))
+            return grub_errno;
+
+          if (type & 0x80)
+            {
+              /* RLE-encoded packet.  */
+              type &= 0x7f;
+              type++;
+
+              if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel)
+                  != bytes_per_pixel)
+                return grub_errno;
+
+              while (type)
+                {
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr += 3;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+          else
+            {
+              /* RAW-encoded packet.  */
+              type++;
+
+              while (type)
+                {
+                  if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel)
+                      != bytes_per_pixel)
+                    return grub_errno;
+
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr += 3;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_rle_R8G8B8A8 (struct grub_video_bitmap *bitmap,
+                                 struct grub_tga_header *header,
+                                 grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t type;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width;)
+        {
+          if (grub_file_read (file, (char *)&type, sizeof (type)) != sizeof(type))
+            return grub_errno;
+
+          if (type & 0x80)
+            {
+              /* RLE-encoded packet.  */
+              type &= 0x7f;
+              type++;
+
+              if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel)
+                  != bytes_per_pixel)
+                return grub_errno;
+
+              while (type)
+                {
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr[3] = tmp[3];
+                      ptr += 4;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+          else
+            {
+              /* RAW-encoded packet.  */
+              type++;
+
+              while (type)
+                {
+                  if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel)
+                      != bytes_per_pixel)
+                    return grub_errno;
+
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr[3] = tmp[3];
+                      ptr += 4;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_R8G8B8 (struct grub_video_bitmap *bitmap,
+                           struct grub_tga_header *header,
+                           grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width; x++)
+        {
+          if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel)
+              != bytes_per_pixel)
+            return grub_errno;
+
+          ptr[0] = tmp[2];
+          ptr[1] = tmp[1];
+          ptr[2] = tmp[0];
+
+          ptr += 3;
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_R8G8B8A8 (struct grub_video_bitmap *bitmap,
+                             struct grub_tga_header *header,
+                             grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width; x++)
+        {
+          if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel)
+              != bytes_per_pixel)
+            return grub_errno;
+
+          ptr[0] = tmp[2];
+          ptr[1] = tmp[1];
+          ptr[2] = tmp[0];
+          ptr[3] = tmp[3];
+
+          ptr += 4;
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_reader_tga (struct grub_video_bitmap **bitmap,
+                       const char *filename)
+{
+  grub_file_t file;
+  grub_ssize_t pos;
+  struct grub_tga_header header;
+  int has_alpha;
+
+  file = grub_file_open (filename);
+  if (! file)
+    return grub_errno;
+
+  /* TGA Specification states that we SHOULD start by reading
+     ID from end of file, but we really don't care about that as we are
+     not going to support developer area & extensions at this point.  */
+
+  /* Read TGA header from begining of file.  */
+  if (grub_file_read (file, (char*)&header, sizeof (header)) 
+      != sizeof (header))
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  /* Skip ID field.  */
+  pos = grub_file_tell (file);
+  pos += header.id_length;
+  grub_file_seek (file, pos);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+#if defined(TGA_DEBUG)
+  grub_printf("tga: header\n");
+  dump_int_field(header.id_length);
+  dump_int_field(header.color_map_type);
+  dump_int_field(header.image_type);
+  dump_int_field(header.color_map_first_index);
+  dump_int_field(header.color_map_length);
+  dump_int_field(header.color_map_bpp);
+  dump_int_field(header.image_x_origin);
+  dump_int_field(header.image_y_origin);
+  dump_int_field(header.image_width);
+  dump_int_field(header.image_height);
+  dump_int_field(header.image_bpp);
+  dump_int_field(header.image_descriptor);
+#endif
+
+  /* Check that bitmap encoding is supported.  */
+  switch (header.image_type)
+    {
+      case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+      case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+        break;
+
+      default:
+        grub_file_close (file);
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "Unsupported bitmap format (unknown encoding).");
+    }
+
+  /* Check that bitmap depth is supported.  */
+  switch (header.image_bpp)
+    {
+      case 24:
+        has_alpha = 0;
+        break;
+
+      case 32:
+        has_alpha = 1;
+        break;
+
+      default:
+        grub_file_close (file);
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "Unsupported bitmap format (bpp=%d).",
+                           header.image_bpp);
+    }
+
+  /* Allocate bitmap.  If there is alpha information store it too.  */
+  if (has_alpha)
+    {
+      grub_video_bitmap_create (bitmap, header.image_width,
+                                header.image_height,
+                                GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          grub_file_close (file);
+          return grub_errno;
+        }
+
+      /* Load bitmap data.  */
+      switch (header.image_type)
+        {
+          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+            tga_load_truecolor_R8G8B8A8 (*bitmap, &header, file);
+            break;
+
+          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+            tga_load_truecolor_rle_R8G8B8A8 (*bitmap, &header, file);
+            break;
+        }
+    }
+  else
+    {
+      grub_video_bitmap_create (bitmap, header.image_width,
+                                header.image_height,
+                                GRUB_VIDEO_BLIT_FORMAT_R8G8B8);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          grub_file_close (file);
+          return grub_errno;
+        }
+
+      /* Load bitmap data.  */
+      switch (header.image_type)
+        {
+          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+            tga_load_truecolor_R8G8B8 (*bitmap, &header, file);
+            break;
+
+          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+            tga_load_truecolor_rle_R8G8B8 (*bitmap, &header, file);
+            break;
+        }
+    }
+
+  /* If there were loading proble, destroy bitmap.  */
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_destroy (*bitmap);
+      *bitmap = 0;
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+#if defined(TGA_DEBUG)
+static grub_err_t
+grub_cmd_tgatest (struct grub_arg_list *state __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  struct grub_video_bitmap *bitmap = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_video_reader_tga (&bitmap, args[0]);  
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_bitmap_destroy (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
+static struct grub_video_bitmap_reader tga_reader = {
+  .extension = ".tga",
+  .reader = grub_video_reader_tga,
+  .next = 0
+};
+
+GRUB_MOD_INIT(video_reader_tga)
+{
+  grub_video_bitmap_reader_register (&tga_reader);
+#if defined(TGA_DEBUG)
+  grub_register_command ("tgatest", grub_cmd_tgatest, GRUB_COMMAND_FLAG_BOTH,
+                         "tgatest FILE", "Tests loading of TGA bitmap.", 0);
+#endif
+}
+
+GRUB_MOD_FINI(video_reader_tga)
+{
+#if defined(TGA_DEBUG)
+  grub_unregister_command ("tgatest");
+#endif
+  grub_video_bitmap_reader_unregister (&tga_reader);
+}
index ac0714fd28294c502fff123e93f594066dfd1af5..61bac1c69afd02ac4f8aadb5549975c0eda6dd96 100644 (file)
@@ -82,7 +82,7 @@ grub_video_setup (unsigned int width, unsigned int height,
   /* Loop thru all possible video adapter trying to find requested mode.  */
   for (p = grub_video_adapter_list; p; p = p->next)
     {
-      /* Try to initialize adapter, if can't skip to next.  */
+      /* Try to initialize adapter, if it fails, skip to next adapter.  */
       p->init ();
       if (grub_errno != GRUB_ERR_NONE)
         {
@@ -142,7 +142,7 @@ grub_video_get_info (struct grub_video_mode_info *mode_info)
 enum grub_video_blit_format
 grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
 {
-  /* Check if we have any knwon 32 bit modes.  */
+  /* Check if we have any known 32 bit modes.  */
   if (mode_info->bpp == 32)
     {
       if ((mode_info->red_mask_size == 8)
@@ -286,13 +286,14 @@ grub_video_blit_glyph (struct grub_font_glyph *glyph,
 /* Blit bitmap to screen.  */
 grub_err_t
 grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
+                        enum grub_video_blit_operators oper,
                         int x, int y, int offset_x, int offset_y,
                         unsigned int width, unsigned int height)
 {
   if (! grub_video_adapter_active)
     return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
 
-  return grub_video_adapter_active->blit_bitmap (bitmap, x, y,
+  return grub_video_adapter_active->blit_bitmap (bitmap, oper, x, y,
                                                  offset_x, offset_y,
                                                  width, height);
 }
@@ -300,14 +301,15 @@ grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
 /* Blit render target to active render target.  */
 grub_err_t
 grub_video_blit_render_target (struct grub_video_render_target *target,
+                               enum grub_video_blit_operators oper,
                                int x, int y, int offset_x, int offset_y,
                                unsigned int width, unsigned int height)
 {
   if (! grub_video_adapter_active)
     return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
 
-  return grub_video_adapter_active->blit_render_target (target, x, y,
-                                                        offset_x, offset_y, 
+  return grub_video_adapter_active->blit_render_target (target, oper, x, y,
+                                                        offset_x, offset_y,
                                                         width, height);
 }