All of lore.kernel.org
 help / color / mirror / Atom feed
* [WIP PATCH 1/2] Split framebuffer from vbe
@ 2009-06-15 15:15 Vladimir 'phcoder' Serbinenko
  2009-06-15 15:16 ` Vladimir 'phcoder' Serbinenko
  0 siblings, 1 reply; 2+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-06-15 15:15 UTC (permalink / raw)
  To: The development of GRUB 2

Hello. Here is my first attempt on splitting video_fb.mod from
vbe.mod. The idea was to make framebuffer code work with render_target
without knowing what the real video mode is and let video-card
specific code bother with things like double buffering and
modesetting. Two loader: linux and xnu have to pass framebuffer
address to their payload this is however problematic because in case
of double buffering framebuffer address may change. The only idea of
clean interface I see would be a function like
grub_video_get_framebuffer_info_and_fini
which will terminate the video driver thus ensuring that video mode
(including framebuffer address) won't change. Does anyone has a better
idea?

-- 
Regards
Vladimir 'phcoder' Serbinenko



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [WIP PATCH 1/2] Split framebuffer from vbe
  2009-06-15 15:15 [WIP PATCH 1/2] Split framebuffer from vbe Vladimir 'phcoder' Serbinenko
@ 2009-06-15 15:16 ` Vladimir 'phcoder' Serbinenko
  0 siblings, 0 replies; 2+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-06-15 15:16 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 900 bytes --]

On Mon, Jun 15, 2009 at 5:15 PM, Vladimir 'phcoder'
Serbinenko<phcoder@gmail.com> wrote:
> Hello. Here is my first attempt on splitting video_fb.mod from
> vbe.mod. The idea was to make framebuffer code work with render_target
> without knowing what the real video mode is and let video-card
> specific code bother with things like double buffering and
> modesetting. Two loader: linux and xnu have to pass framebuffer
> address to their payload this is however problematic because in case
> of double buffering framebuffer address may change. The only idea of
> clean interface I see would be a function like
> grub_video_get_framebuffer_info_and_fini
> which will terminate the video driver thus ensuring that video mode
> (including framebuffer address) won't change. Does anyone has a better
> idea?
>
> --
> Regards
> Vladimir 'phcoder' Serbinenko
>



-- 
Regards
Vladimir 'phcoder' Serbinenko

[-- Attachment #2: framebuf.diff --]
[-- Type: text/x-diff, Size: 174137 bytes --]

diff --git a/conf/common.rmk b/conf/common.rmk
index 3d74f90..41bfd30 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -521,13 +521,18 @@ lua_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # Common Video Subsystem specific modules.
 pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod	\
-	png.mod	font.mod gfxterm.mod
+	png.mod	font.mod gfxterm.mod video_fb.mod
 
 # For video.mod.
 video_mod_SOURCES = video/video.c
 video_mod_CFLAGS = $(COMMON_CFLAGS)
 video_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+video_fb_mod_SOURCES = video/fb/video_fb.c video/fb/fbblit.c \
+		  video/fb/fbfill.c video/fb/fbutil.c
+video_fb_mod_CFLAGS = $(COMMON_CFLAGS)
+video_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For videotest.mod.
 videotest_mod_SOURCES = commands/videotest.c
 videotest_mod_CFLAGS = $(COMMON_CFLAGS)
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index abb6fd5..66fdbd4 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -277,8 +277,7 @@ multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
 
 # For vbe.mod.
-vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
-		  video/i386/pc/vbefill.c video/i386/pc/vbeutil.c
+vbe_mod_SOURCES = video/i386/pc/vbe.c
 vbe_mod_CFLAGS = $(COMMON_CFLAGS)
 vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
diff --git a/include/grub/fbblit.h b/include/grub/fbblit.h
new file mode 100644
index 0000000..664f508
--- /dev/null
+++ b/include/grub/fbblit.h
@@ -0,0 +1,134 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FBBLIT_HEADER
+#define GRUB_FBBLIT_HEADER	1
+
+/* NOTE: This header is private header for fb driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_fbblit_info;
+
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+			   struct grub_video_fbblit_info *src,
+			   int x, int y, int width, int height,
+			   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+				   struct grub_video_fbblit_info *src,
+				   int x, int y, int width, int height,
+				   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					     struct grub_video_fbblit_info *src,
+					     int x, int y, int width, int height,
+					     int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+					  struct grub_video_fbblit_info *src,
+					  int x, int y,
+					  int width, int height,
+					  int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_info *src,
+					int x, int y, int width, int height,
+					int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+			 struct grub_video_fbblit_info *src,
+			 int x, int y, int width, int height,
+			 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_info *src,
+					int x, int y,
+					int width, int height,
+					int offset_x, int offset_y);
+
+#endif /* ! GRUB_FBBLIT_HEADER */
diff --git a/include/grub/fbfill.h b/include/grub/fbfill.h
new file mode 100644
index 0000000..11e22c6
--- /dev/null
+++ b/include/grub/fbfill.h
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FBFILL_HEADER
+#define GRUB_FBFILL_HEADER	1
+
+/* NOTE: This header is private header for fb driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_fbblit_info;
+
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+		   grub_video_color_t color, int x, int y,
+		   int width, int height);
+
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color,  int x, int y,
+			    int width, int height);
+
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height);
+
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height);
+
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+			   grub_video_color_t color, int x, int y,
+			   int width, int height);
+
+#endif /* ! GRUB_FBFILL_HEADER */
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
new file mode 100644
index 0000000..76e1e57
--- /dev/null
+++ b/include/grub/fbutil.h
@@ -0,0 +1,43 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* 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_fbblit_info
+{
+  struct grub_video_mode_info *mode_info;
+  void *data;
+};
+
+grub_uint8_t *get_data_ptr (struct grub_video_fbblit_info *source,
+                            unsigned int x, unsigned int y);
+
+grub_video_color_t get_pixel (struct grub_video_fbblit_info *source,
+                              unsigned int x, unsigned int y);
+
+void set_pixel (struct grub_video_fbblit_info *source,
+                unsigned int x, unsigned int y, grub_video_color_t color);
+
+#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h
index bd6ecd7..fb11678 100644
--- a/include/grub/i386/pc/vbe.h
+++ b/include/grub/i386/pc/vbe.h
@@ -19,10 +19,7 @@
 #ifndef GRUB_VBE_MACHINE_HEADER
 #define GRUB_VBE_MACHINE_HEADER	1
 
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/video.h>
+#include <grub/video_fb.h>
 
 /* Default video mode to be used.  */
 #define GRUB_VBE_DEFAULT_VIDEO_MODE     0x101
@@ -224,54 +221,5 @@ grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode);
 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).  */
-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 whether 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);
-
-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);
-
-grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color,
-                                       grub_uint8_t *red,
-                                       grub_uint8_t *green,
-                                       grub_uint8_t *blue,
-                                       grub_uint8_t *alpha);
-
-void grub_video_vbe_unmap_color_int (struct grub_video_i386_vbeblit_info *source,
-                                     grub_video_color_t color,
-                                     grub_uint8_t *red,
-                                     grub_uint8_t *green,
-                                     grub_uint8_t *blue,
-                                     grub_uint8_t *alpha);
 
 #endif /* ! GRUB_VBE_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/vbeblit.h b/include/grub/i386/pc/vbeblit.h
deleted file mode 100644
index 5a2aa7a..0000000
--- a/include/grub/i386/pc/vbeblit.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#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_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);
-
-void
-grub_video_i386_vbeblit_replace_directN (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_BGRX8888_RGBX8888 (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_BGRX8888_RGB888 (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_BGR888_RGBX8888 (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_BGR888_RGB888 (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_RGBX8888_RGB888 (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_RGB888_RGBX8888 (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_index_RGBX8888 (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_index_RGB888 (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_blend_BGRA8888_RGBA8888 (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_BGR888_RGBA8888 (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_RGBA8888_RGBA8888 (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_RGB888_RGBA8888 (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_index_RGBA8888 (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 */
diff --git a/include/grub/i386/pc/vbefill.h b/include/grub/i386/pc/vbefill.h
deleted file mode 100644
index efc6378..0000000
--- a/include/grub/i386/pc/vbefill.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_VBEFILL_MACHINE_HEADER
-#define GRUB_VBEFILL_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_vbefill (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_direct32 (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_direct24 (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_direct16 (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_direct8 (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
deleted file mode 100644
index 9b5be21..0000000
--- a/include/grub/i386/pc/vbeutil.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* 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 */
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
new file mode 100644
index 0000000..8c6987e
--- /dev/null
+++ b/include/grub/video_fb.h
@@ -0,0 +1,136 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VIDEO_FB_HEADER
+#define GRUB_VIDEO_FB_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/video.h>
+
+/* FB module internal prototype (should not be used from elsewhere).  */
+
+struct grub_video_fbblit_info;
+
+struct grub_video_fbrender_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 whether 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_video_fbstd_colors[16];
+
+grub_uint8_t * grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+                                             grub_uint32_t x, grub_uint32_t y);
+
+grub_err_t
+grub_video_fb_init (void);
+
+grub_err_t
+grub_video_fb_fini (void);
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info);
+
+grub_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+			    unsigned int width, unsigned int height);
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+			    unsigned int *width, unsigned int *height);
+
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name);
+
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+		       grub_uint8_t blue);
+
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+			grub_uint8_t blue, grub_uint8_t alpha);
+
+grub_err_t 
+grub_video_fb_unmap_color (grub_video_color_t color,
+			   grub_uint8_t *red, grub_uint8_t *green,
+			   grub_uint8_t *blue, grub_uint8_t *alpha);
+
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+			       grub_video_color_t color,
+			       grub_uint8_t *red, grub_uint8_t *green,
+			       grub_uint8_t *blue, grub_uint8_t *alpha);
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+			 unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_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_fb_blit_render_target (struct grub_video_fbrender_target *source,
+                                   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_fb_scroll (grub_video_color_t color, int dx, int dy);
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+				    unsigned int width, unsigned int height,
+				    unsigned int mode_type __attribute__ ((unused)));
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target);
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target);
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target);
+
+#endif /* ! GRUB_VIDEO_FB_HEADER */
diff --git a/loader/i386/linux.c b/loader/i386/linux.c
index 6510db6..1748836 100644
--- a/loader/i386/linux.c
+++ b/loader/i386/linux.c
@@ -31,9 +31,7 @@
 #include <grub/term.h>
 #include <grub/cpu/linux.h>
 #include <grub/video.h>
-/* FIXME: the definition of `struct grub_video_render_target' is
-   VBE-specific.  */
-#include <grub/i386/pc/vbe.h>
+#include <grub/video_fb.h>
 #include <grub/command.h>
 
 #define GRUB_LINUX_CL_OFFSET		0x1000
@@ -403,14 +401,15 @@ static int
 grub_linux_setup_video (struct linux_kernel_params *params)
 {
   struct grub_video_mode_info mode_info;
-  struct grub_video_render_target *render_target;
+  struct grub_video_fbrender_target *render_target;
   int ret;
 
   ret = grub_video_get_info (&mode_info);
   if (ret)
     return 1;
 
-  ret = grub_video_get_active_render_target (&render_target);
+  ret = grub_video_get_active_render_target 
+    ((struct grub_video_render_target **) &render_target);
   if (ret)
     return 1;
 
diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c
index 037a713..2712a8a 100644
--- a/loader/i386/pc/xnu.c
+++ b/loader/i386/pc/xnu.c
@@ -21,8 +21,7 @@
 #include <grub/xnu.h>
 #include <grub/mm.h>
 #include <grub/cpu/xnu.h>
-#include <grub/machine/vbe.h>
-#include <grub/machine/vga.h>
+#include <grub/video_fb.h>
 
 #define min(a,b) (((a) < (b)) ? (a) : (b))
 #define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -43,7 +42,7 @@ grub_err_t
 grub_xnu_set_video (struct grub_xnu_boot_params *params)
 {
   struct grub_video_mode_info mode_info;
-  struct grub_video_render_target *render_target;
+  struct grub_video_fbrender_target *render_target;
   int ret;
   int x,y;
   char *tmp, *modevar;
@@ -71,7 +70,8 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
   if (ret)
     return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
 
-  ret = grub_video_get_active_render_target (&render_target);
+  ret = grub_video_get_active_render_target 
+    ((struct grub_video_render_target **) &render_target);
   if (ret)
     return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
 
diff --git a/video/fb/fbblit.c b/video/fb/fbblit.c
new file mode 100644
index 0000000..138eba8
--- /dev/null
+++ b/video/fb/fbblit.c
@@ -0,0 +1,828 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* 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/video_fb.h>
+#include <grub/fbblit.h>
+#include <grub/fbutil.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+/* Generic replacing blitter (slow).  Works for every supported format.  */
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+			   struct grub_video_fbblit_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;
+
+  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_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+					 &src_blue, &src_alpha);
+
+	  dst_color = grub_video_fb_map_rgba (src_red, src_green,
+					      src_blue, src_alpha);
+
+	  set_pixel (dst, x + i, y + j, dst_color);
+	}
+    }
+}
+
+/* Block copy replacing blitter.  Works with modes multiple of 8 bits.  */
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+				   struct grub_video_fbblit_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 bpp;
+
+  bpp = src->mode_info->bytes_per_pixel;
+
+  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 * bpp);
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGRX8888.  */
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					     struct grub_video_fbblit_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;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+          grub_uint8_t a = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+          *dstptr++ = a;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to BGRX8888.  */
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_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;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+
+          /* Set alpha component as opaque.  */
+          *dstptr++ = 255;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGR888.  */
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          grub_uint8_t sr;
+          grub_uint8_t sg;
+          grub_uint8_t sb;
+
+          color = *srcptr++;
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          *dstptr++ = sb;
+          *dstptr++ = sg;
+          *dstptr++ = sr;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to BGR888.  */
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_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;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to RGBX8888.  */
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_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_uint8_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; 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++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+
+          /* Set alpha as opaque.  */
+          color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
+
+          *dstptr++ = color;
+        }
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to RGB888.  */
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_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;
+
+  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;
+	}
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to indexed color.  */
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+					  struct grub_video_fbblit_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;
+
+  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_fb_map_rgb(sr, sg, sb);
+	  *dstptr++ = color & 0xFF;
+	}
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to indexed color.  */
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_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_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; 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++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+
+          color = grub_video_fb_map_rgb(sr, sg, sb);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
+
+/* Generic blending blitter.  Works for every supported format.  */
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+			 struct grub_video_fbblit_info *src,
+			 int x, int y, int width, int height,
+			 int offset_x, int offset_y)
+{
+  int i;
+  int j;
+
+  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 = get_pixel (src, i + offset_x, j + offset_y);
+          grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+					 &src_blue, &src_alpha);
+
+          if (src_alpha == 0)
+            continue;
+
+          if (src_alpha == 255)
+            {
+              dst_color = grub_video_fb_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_fb_unmap_color_int (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_fb_map_rgba (dst_red, dst_green, dst_blue,
+					      dst_alpha);
+
+          set_pixel (dst, x + i, y + j, dst_color);
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGRA8888.  */
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint32_t *) get_data_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          unsigned int sr;
+          unsigned int sg;
+          unsigned int sb;
+          unsigned int a;
+          unsigned int dr;
+          unsigned int dg;
+          unsigned int db;
+
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              /* Skip transparent source pixels.  */
+              dstptr++;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              /* Opaque pixel shortcut.  */
+              dr = sr;
+              dg = sg;
+              db = sb;
+            }
+          else
+            {
+              /* General pixel color blending.  */
+              color = *dstptr;
+
+              dr = (color >> 16) & 0xFF;
+              dr = (dr * (255 - a) + sr * a) / 255;
+              dg = (color >> 8) & 0xFF;
+              dg = (dg * (255 - a) + sg * a) / 255;
+              db = (color >> 0) & 0xFF;
+              db = (db * (255 - a) + sb * a) / 255;
+            }
+
+          color = (a << 24) | (dr << 16) | (dg << 8) | db;
+
+          *dstptr++ = color;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGR888.  */
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          unsigned int sr;
+          unsigned int sg;
+          unsigned int sb;
+          unsigned int a;
+          unsigned int dr;
+          unsigned int dg;
+          unsigned int db;
+
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              /* Skip transparent source pixels.  */
+              dstptr += 3;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              /* Opaque pixel shortcut.  */
+              dr = sr;
+              dg = sg;
+              db = sb;
+            }
+          else
+            {
+              /* General pixel color blending.  */
+              color = *dstptr;
+
+              db = dstptr[0];
+              db = (db * (255 - a) + sb * a) / 255;
+              dg = dstptr[1];
+              dg = (dg * (255 - a) + sg * a) / 255;
+              dr = dstptr[2];
+              dr = (dr * (255 - a) + sr * a) / 255;
+            }
+
+          *dstptr++ = db;
+          *dstptr++ = dg;
+          *dstptr++ = dr;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for RGBA888 to RGBA8888.  */
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_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_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+
+  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);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          if (a == 255)
+            {
+              *dstptr++ = color;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          color = *dstptr;
+
+          dr = (color >> 0) & 0xFF;
+          dg = (color >> 8) & 0xFF;
+          db = (color >> 16) & 0xFF;
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          color = (a << 24) | (db << 16) | (dg << 8) | dr;
+
+          *dstptr++ = color;
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to RGB888.  */
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_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;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+
+  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++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr += 3;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              *dstptr++ = sr;
+              *dstptr++ = sg;
+              *dstptr++ = sb;
+
+              continue;
+            }
+
+          dr = dstptr[0];
+          dg = dstptr[1];
+          db = dstptr[2];
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          *dstptr++ = dr;
+          *dstptr++ = dg;
+          *dstptr++ = db;
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to indexed color.  */
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_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;
+  unsigned int a;
+  unsigned char dr;
+  unsigned char dg;
+  unsigned char db;
+  unsigned char da;
+
+  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++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              color = grub_video_fb_map_rgb(sr, sg, sb);
+              *dstptr++ = color & 0xFF;
+              continue;
+            }
+
+          grub_video_fb_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          color = grub_video_fb_map_rgb(dr, dg, db);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
diff --git a/video/fb/fbfill.c b/video/fb/fbfill.c
new file mode 100644
index 0000000..a4ca7c2
--- /dev/null
+++ b/video/fb/fbfill.c
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* 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/video_fb.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+/* Generic filler that works for every supported mode.  */
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+		   grub_video_color_t color, int x, int y,
+		   int width, int height)
+{
+  int i;
+  int j;
+
+  for (j = 0; j < height; j++)
+    for (i = 0; i < width; i++)
+      set_pixel (dst, x + i, y + j, color);
+}
+
+/* Optimized filler for direct color 32 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height)
+{
+  int i;
+  int j;
+  grub_uint32_t *dstptr;
+  grub_size_t rowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        *dstptr++ = color;
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip);
+    }
+}
+
+/* Optimized filler for direct color 24 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+  grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          *dstptr++ = fill0;
+          *dstptr++ = fill1;
+          *dstptr++ = fill2;
+        }
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
+
+/* Optimized filler for direct color 16 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          *dstptr++ = fill0;
+          *dstptr++ = fill1;
+        }
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
+
+/* Optimized filler for index color.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+			   grub_video_color_t color, int x, int y,
+			   int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        *dstptr++ = fill;
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
diff --git a/video/fb/fbutil.c b/video/fb/fbutil.c
new file mode 100644
index 0000000..09cbb12
--- /dev/null
+++ b/video/fb/fbutil.c
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/fbutil.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+grub_uint8_t *
+get_data_ptr (struct grub_video_fbblit_info *source,
+              unsigned int x, unsigned int y)
+{
+  grub_uint8_t *ptr = 0;
+
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      ptr = (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;
+
+    case 1:
+      /* For 1-bit bitmaps, addressing needs to be done at the bit level
+         and it doesn't make sense, in general, to ask for a pointer
+         to a particular pixel's data.  */
+      break;
+    }
+
+  return ptr;
+}
+
+grub_video_color_t
+get_pixel (struct grub_video_fbblit_info *source,
+           unsigned int x, unsigned int y)
+{
+  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;
+
+    case 1:
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+        {
+          int bit_index = y * source->mode_info->width + x;
+          grub_uint8_t *ptr = (grub_uint8_t *)source->data
+                              + bit_index / 8;
+          int bit_pos = 7 - bit_index % 8;
+          color = (*ptr >> bit_pos) & 0x01;
+        }
+      break;
+
+    default:
+      break;
+    }
+
+  return color;
+}
+
+void
+set_pixel (struct grub_video_fbblit_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;
+
+    case 1:
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+        {
+          int bit_index = y * source->mode_info->width + x;
+          grub_uint8_t *ptr = (grub_uint8_t *)source->data
+                              + bit_index / 8;
+          int bit_pos = 7 - bit_index % 8;
+          *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
+        }
+      break;
+
+    default:
+      break;
+    }
+}
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
new file mode 100644
index 0000000..98f80c3
--- /dev/null
+++ b/video/fb/video_fb.c
@@ -0,0 +1,1100 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/fbblit.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/bitmap.h>
+
+static struct grub_video_fbrender_target *render_target;
+struct grub_video_palette_data *palette;
+static unsigned int palette_size;
+
+/* Specify "standard" VGA palette, some video cards may
+   need this and this will also be used when using RGB modes.  */
+struct grub_video_palette_data grub_video_fbstd_colors[16] =
+  {
+    // {R, G, B, A}
+    {0x00, 0x00, 0x00, 0xFF}, // 0 = black
+    {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue
+    {0x00, 0xA8, 0x00, 0xFF}, // 2 = green
+    {0x00, 0xA8, 0xA8, 0xFF}, // 3 = cyan
+    {0xA8, 0x00, 0x00, 0xFF}, // 4 = red
+    {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
+    {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown
+    {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray
+
+    {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray
+    {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue
+    {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green
+    {0x54, 0xFE, 0xFE, 0xFF}, // 11 = bright cyan
+    {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red
+    {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta
+    {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow
+    {0xFE, 0xFE, 0xFE, 0xFF}  // 15 = white
+  };
+
+grub_err_t
+grub_video_fb_init (void)
+{
+  grub_free (palette);
+  render_target = 0;
+  palette = 0;
+  palette_size = 0;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_fini (void)
+{
+  grub_free (palette);
+  render_target = 0;
+  palette = 0;
+  palette_size = 0;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info)
+{
+  /* Copy mode info from active render target.  */
+  grub_memcpy (mode_info, &render_target->mode_info,
+               sizeof (struct grub_video_mode_info));
+
+  return GRUB_ERR_NONE;
+}
+
+
+grub_uint8_t *
+grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+			     grub_uint32_t x, grub_uint32_t 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_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data)
+{
+  unsigned int i;
+
+  /* Assume that we know everything from index color palette.  */
+  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+    palette_data[i] = palette[start + i];
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data)
+{
+  unsigned i;
+  if (start + count > palette_size)
+    {
+      palette_size = start + count;
+      palette = grub_realloc (palette, sizeof (palette[0]) * palette_size);
+      if (!palette)
+	{
+	  grub_video_fb_fini ();
+	  return grub_errno;
+	}
+    }
+  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+    palette[start + i] = palette_data[i];
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+			    unsigned int width, unsigned int height)
+{
+  render_target->viewport.x = x;
+  render_target->viewport.y = y;
+  render_target->viewport.width = width;
+  render_target->viewport.height = height;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+			    unsigned int *width, unsigned int *height)
+{
+  if (x) *x = render_target->viewport.x;
+  if (y) *y = render_target->viewport.y;
+  if (width) *width = render_target->viewport.width;
+  if (height) *height = render_target->viewport.height;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Maps color name to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name)
+{
+  /* TODO: implement color theme mapping code.  */
+
+  if (color_name < palette_size)
+    {
+      if ((render_target->mode_info.mode_type
+           & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+        return color_name;
+      else
+        {
+          grub_video_color_t color;
+
+          color = grub_video_fb_map_rgb (palette[color_name].r,
+					 palette[color_name].g,
+					 palette[color_name].b);
+
+          return color;
+        }
+    }
+
+  return 0;
+}
+
+/* Maps RGB to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+		       grub_uint8_t blue)
+{
+  if ((render_target->mode_info.mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    {
+      int minindex = 0;
+      int delta = 0;
+      int tmp;
+      int val;
+      unsigned i;
+
+      /* Find best matching color.  */
+      for (i = 0; i < palette_size; i++)
+        {
+          val = palette[i].r - red;
+          tmp = val * val;
+          val = palette[i].g - green;
+          tmp += val * val;
+          val = palette[i].b - blue;
+          tmp += val * val;
+
+          if (i == 0)
+            delta = tmp;
+
+          if (tmp < delta)
+            {
+              delta = tmp;
+              minindex = i;
+              if (tmp == 0)
+                break;
+            }
+        }
+
+      return minindex;
+    }
+  else if ((render_target->mode_info.mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+       if (red == render_target->mode_info.fg_red
+           && green == render_target->mode_info.fg_green
+           && blue == render_target->mode_info.fg_blue)
+         return 1;
+       else
+         return 0;
+    }
+  else
+    {
+      grub_uint32_t value;
+      grub_uint8_t alpha = 255; /* Opaque color.  */
+
+      red >>= 8 - render_target->mode_info.red_mask_size;
+      green >>= 8 - render_target->mode_info.green_mask_size;
+      blue >>= 8 - render_target->mode_info.blue_mask_size;
+      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+      value = red << render_target->mode_info.red_field_pos;
+      value |= green << render_target->mode_info.green_field_pos;
+      value |= blue << render_target->mode_info.blue_field_pos;
+      value |= alpha << render_target->mode_info.reserved_field_pos;
+
+      return value;
+    }
+
+}
+
+/* Maps RGBA to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+			grub_uint8_t blue, grub_uint8_t alpha)
+{
+  if ((render_target->mode_info.mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    /* No alpha available in index color modes, just use
+       same value as in only RGB modes.  */
+    return grub_video_fb_map_rgb (red, green, blue);
+  else if ((render_target->mode_info.mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+      if (red == render_target->mode_info.fg_red
+          && green == render_target->mode_info.fg_green
+          && blue == render_target->mode_info.fg_blue
+          && alpha == render_target->mode_info.fg_alpha)
+        return 1;
+      else
+        return 0;
+    }
+  else
+    {
+      grub_uint32_t value;
+
+      red >>= 8 - render_target->mode_info.red_mask_size;
+      green >>= 8 - render_target->mode_info.green_mask_size;
+      blue >>= 8 - render_target->mode_info.blue_mask_size;
+      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+      value = red << render_target->mode_info.red_field_pos;
+      value |= green << render_target->mode_info.green_field_pos;
+      value |= blue << render_target->mode_info.blue_field_pos;
+      value |= alpha << render_target->mode_info.reserved_field_pos;
+
+      return value;
+    }
+}
+
+/* Splits target optimized format to components.  */
+grub_err_t 
+grub_video_fb_unmap_color (grub_video_color_t color,
+			   grub_uint8_t *red, grub_uint8_t *green,
+			   grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+  struct grub_video_fbblit_info target_info;
+
+  target_info.mode_info = &render_target->mode_info;
+  target_info.data = render_target->data;
+
+  grub_video_fb_unmap_color_int (&target_info, color, red, green, blue, alpha);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Splits color in source format to components.  */
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+			       grub_video_color_t color,
+			       grub_uint8_t *red, grub_uint8_t *green,
+			       grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+  struct grub_video_mode_info *mode_info;
+  mode_info = source->mode_info;
+
+  if ((mode_info->mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    {
+      /* If we have an out-of-bounds color, return transparent black.  */
+      if (color > 255)
+        {
+          *red = 0;
+          *green = 0;
+          *blue = 0;
+          *alpha = 0;
+          return;
+        }
+
+      *red = palette[color].r;
+      *green = palette[color].g;
+      *blue = palette[color].b;
+      *alpha = palette[color].a;
+      return;
+    }
+  else if ((mode_info->mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+      if (color & 1)
+        {
+          *red = mode_info->fg_red;
+          *green = mode_info->fg_green;
+          *blue = mode_info->fg_blue;
+          *alpha = mode_info->fg_alpha;
+        }
+      else
+        {
+          *red = mode_info->bg_red;
+          *green = mode_info->bg_green;
+          *blue = mode_info->bg_blue;
+          *alpha = mode_info->bg_alpha;
+        }
+    }
+  else
+    {
+      grub_uint32_t tmp;
+
+      /* Get red component.  */
+      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 >> 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 >> 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)
+        {
+          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.  */
+        tmp = 255;
+
+      *alpha = tmp & 0xFF;
+    }
+}
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+			 unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info target;
+
+  /* Make sure there is something to do.  */
+  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;
+
+  /* Do not allow drawing out of viewport.  */
+  if (x < 0)
+    {
+      width += x;
+      x = 0;
+    }
+  if (y < 0)
+    {
+      height += y;
+      y = 0;
+    }
+
+  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;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_info to encapsulate rendering.  */
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
+  /* Try to figure out more optimized version.  Note that color is already
+     mapped to target format so we can make assumptions based on that.  */
+  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+    {
+      grub_video_fbfill_direct32 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+    {
+      grub_video_fbfill_direct32 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+    {
+      grub_video_fbfill_direct24 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
+    {
+      grub_video_fbfill_direct16 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
+    {
+      grub_video_fbfill_direct16 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+    {
+      grub_video_fbfill_direct8 (&target, color, x, y,
+				       width, height);
+      return GRUB_ERR_NONE;
+    }
+
+  /* No optimized version found, use default (slow) filler.  */
+  grub_video_fbfill (&target, color, x, y, width, height);
+
+  return GRUB_ERR_NONE;
+}
+
+/* NOTE: This function assumes that given coordinates are within bounds of
+   handled data.  */
+static void
+common_blitter (struct grub_video_fbblit_info *target,
+                struct grub_video_fbblit_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_RGBA_8888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source,
+								 x, y, width, height,
+								 offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_replace_BGR888_RGBX8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_replace_RGB888_RGBX8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_index_RGBX8888 (target, source,
+							      x, y, width, height,
+							      offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_index_RGB888 (target, source,
+							    x, y, width, height,
+							    offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	}
+
+      /* No optimized replace operator found, use default (slow) blitter.  */
+      grub_video_fbblit_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_RGBA_8888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_blend_BGRA8888_RGBA8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_blend_BGR888_RGBA8888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_blend_RGB888_RGBA8888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_blend_index_RGBA8888 (target, source,
+							    x, y, width, height,
+							    offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	{
+	  /* Note: There is really no alpha information here, so blend is
+	     changed to replace.  */
+
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_index_RGB888 (target, source,
+							    x, y, width, height,
+							    offset_x, offset_y);
+	      return;
+	    }
+	}
+
+      /* No optimized blend operation found, use default (slow) blitter.  */
+      grub_video_fbblit_blend (target, source, x, y, width, height,
+				     offset_x, offset_y);
+    }
+}
+
+grub_err_t
+grub_video_fb_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_fbblit_info source;
+  struct grub_video_fbblit_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;
+
+  /* If we have negative coordinates, optimize drawing to minimum.  */
+  if (offset_x < 0)
+    {
+      width += offset_x;
+      x -= offset_x;
+      offset_x = 0;
+    }
+
+  if (offset_y < 0)
+    {
+      height += offset_y;
+      y -= offset_y;
+      offset_y = 0;
+    }
+
+  if (x < 0)
+    {
+      width += x;
+      offset_x -= x;
+      x = 0;
+    }
+
+  if (y < 0)
+    {
+      height += 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;
+
+  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;
+
+  /* Use fbblit_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;
+}
+
+grub_err_t
+grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
+                                   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_fbblit_info source_info;
+  struct grub_video_fbblit_info target_info;
+
+  /* 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)source->mode_info.width) < 0)
+    return GRUB_ERR_NONE;
+  if ((y + (int)source->mode_info.height) < 0)
+    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;
+
+  /* If we have negative coordinates, optimize drawing to minimum.  */
+  if (offset_x < 0)
+    {
+      width += offset_x;
+      x -= offset_x;
+      offset_x = 0;
+    }
+
+  if (offset_y < 0)
+    {
+      height += offset_y;
+      y -= offset_y;
+      offset_y = 0;
+    }
+
+  if (x < 0)
+    {
+      width += x;
+      offset_x -= x;
+      x = 0;
+    }
+
+  if (y < 0)
+    {
+      height += 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;
+
+  if ((offset_x + width) > source->mode_info.width)
+    width = source->mode_info.width - offset_x;
+  if ((offset_y + height) > source->mode_info.height)
+    height = source->mode_info.height - offset_y;
+
+  /* Limit drawing to source render target dimensions.  */
+  if (width > source->mode_info.width)
+    width = source->mode_info.width;
+
+  if (height > source->mode_info.height)
+    height = source->mode_info.height;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_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;
+
+  /* Do actual blitting.  */
+  common_blitter (&target_info, &source_info, oper, x, y, width, height,
+                  offset_x, offset_y);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
+{
+  int width;
+  int height;
+  int src_x;
+  int src_y;
+  int dst_x;
+  int dst_y;
+
+  /* 1. Check if we have something to do.  */
+  if ((dx == 0) && (dy == 0))
+    return GRUB_ERR_NONE;
+
+  width = render_target->viewport.width - grub_abs (dx);
+  height = render_target->viewport.height - grub_abs (dy);
+
+  if (dx < 0)
+    {
+      src_x = render_target->viewport.x - dx;
+      dst_x = render_target->viewport.x;
+    }
+  else
+    {
+      src_x = render_target->viewport.x;
+      dst_x = render_target->viewport.x + dx;
+    }
+
+  if (dy < 0)
+    {
+      src_y = render_target->viewport.y - dy;
+      dst_y = render_target->viewport.y;
+    }
+  else
+    {
+      src_y = render_target->viewport.y;
+      dst_y = render_target->viewport.y + dy;
+    }
+
+  /* 2. Check if there is need to copy data.  */
+  if ((grub_abs (dx) < render_target->viewport.width)
+       && (grub_abs (dy) < render_target->viewport.height))
+    {
+      /* 3. Move data in render target.  */
+      struct grub_video_fbblit_info target;
+      grub_uint8_t *src;
+      grub_uint8_t *dst;
+      int j;
+
+      target.mode_info = &render_target->mode_info;
+      target.data = render_target->data;
+
+      /* Check vertical direction of the move.  */
+      if (dy <= 0)
+	/* 3a. Move data upwards.  */
+	for (j = 0; j < height; j++)
+	  {
+	    dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
+	    src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
+	    grub_memmove (dst, src,
+			  width * target.mode_info->bytes_per_pixel);
+	  }
+      else
+	/* 3b. Move data downwards.  */
+	for (j = (height - 1); j >= 0; j--)
+	  {
+	    dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
+	    src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
+	    grub_memmove (dst, src,
+			  width * target.mode_info->bytes_per_pixel);
+	  }
+    }
+
+  /* 4. Fill empty space with specified color.  In this implementation
+     there might be colliding areas but at the moment there is no need
+     to optimize this.  */
+
+  /* 4a. Fill top & bottom parts.  */
+  if (dy > 0)
+    grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy);
+  else if (dy < 0)
+    {
+      if (render_target->viewport.height < grub_abs (dy))
+        dy = -render_target->viewport.height;
+
+      grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy,
+                                render_target->viewport.width, -dy);
+    }
+
+  /* 4b. Fill left & right parts.  */
+  if (dx > 0)
+    grub_video_fb_fill_rect (color, 0, 0,
+                              dx, render_target->viewport.height);
+  else if (dx < 0)
+    {
+      if (render_target->viewport.width < grub_abs (dx))
+        dx = -render_target->viewport.width;
+
+      grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0,
+                                -dx, render_target->viewport.height);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+				    unsigned int width, unsigned int height,
+				    unsigned int mode_type __attribute__ ((unused)))
+{
+  struct grub_video_fbrender_target *target;
+  unsigned int size;
+
+  /* Validate arguments.  */
+  if ((! result)
+      || (width == 0)
+      || (height == 0))
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "invalid argument given.");
+
+  /* Allocate memory for render target.  */
+  target = grub_malloc (sizeof (struct grub_video_fbrender_target));
+  if (! target)
+    return grub_errno;
+
+  /* TODO: Implement other types too.
+     Currently only 32bit render targets are supported.  */
+
+  /* Mark render target as allocated.  */
+  target->is_allocated = 1;
+
+  /* Maximize viewport.  */
+  target->viewport.x = 0;
+  target->viewport.y = 0;
+  target->viewport.width = width;
+  target->viewport.height = height;
+
+  /* Setup render target format.  */
+  target->mode_info.width = width;
+  target->mode_info.height = height;
+  target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+                                | GRUB_VIDEO_MODE_TYPE_ALPHA;
+  target->mode_info.bpp = 32;
+  target->mode_info.bytes_per_pixel = 4;
+  target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
+  target->mode_info.number_of_colors = palette_size; /* Emulated palette.  */
+  target->mode_info.red_mask_size = 8;
+  target->mode_info.red_field_pos = 0;
+  target->mode_info.green_mask_size = 8;
+  target->mode_info.green_field_pos = 8;
+  target->mode_info.blue_mask_size = 8;
+  target->mode_info.blue_field_pos = 16;
+  target->mode_info.reserved_mask_size = 8;
+  target->mode_info.reserved_field_pos = 24;
+
+  target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
+
+  /* Calculate size needed for the data.  */
+  size = (width * target->mode_info.bytes_per_pixel) * height;
+
+  target->data = grub_malloc (size);
+  if (! target->data)
+    {
+      grub_free (target);
+      return grub_errno;
+    }
+
+  /* Clear render target with black and maximum transparency.  */
+  grub_memset (target->data, 0, size);
+
+  /* TODO: Add render target to render target list.  */
+
+  /* Save result to caller.  */
+  *result = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target)
+{
+  /* If there is no target, then just return without error.  */
+  if (! target)
+    return GRUB_ERR_NONE;
+
+  /* TODO: Delist render target from render target list.  */
+
+  /* If this is software render target, free it's memory.  */
+  if (target->is_allocated)
+    grub_free (target->data);
+
+  /* Free render target.  */
+  grub_free (target);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target)
+{
+  if (! target->data)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "invalid render target given.");
+
+  render_target = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target)
+{
+  *target = render_target;
+
+  return GRUB_ERR_NONE;
+}
diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c
index ae08402..19cfaf5 100644
--- a/video/i386/pc/vbe.c
+++ b/video/i386/pc/vbe.c
@@ -16,43 +16,17 @@
  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define grub_video_render_target grub_video_fbrender_target
+
 #include <grub/err.h>
 #include <grub/machine/memory.h>
 #include <grub/machine/vga.h>
 #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/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.  */
-static struct grub_vbe_palette_data vga_colors[16] =
-  {
-    // {B, G, R, A}
-    {0x00, 0x00, 0x00, 0x00}, // 0 = black
-    {0xA8, 0x00, 0x00, 0x00}, // 1 = blue
-    {0x00, 0xA8, 0x00, 0x00}, // 2 = green
-    {0xA8, 0xA8, 0x00, 0x00}, // 3 = cyan
-    {0x00, 0x00, 0xA8, 0x00}, // 4 = red
-    {0xA8, 0x00, 0xA8, 0x00}, // 5 = magenta
-    {0x00, 0x54, 0xA8, 0x00}, // 6 = brown
-    {0xA8, 0xA8, 0xA8, 0x00}, // 7 = light gray
-
-    {0x54, 0x54, 0x54, 0x00}, // 8 = dark gray
-    {0xFE, 0x54, 0x54, 0x00}, // 9 = bright blue
-    {0x54, 0xFE, 0x54, 0x00}, // 10 = bright green
-    {0xFE, 0xFE, 0x54, 0x00}, // 11 = bright cyan
-    {0x54, 0x54, 0xFE, 0x00}, // 12 = bright red
-    {0xFE, 0x54, 0xFE, 0x00}, // 13 = bright magenta
-    {0x54, 0xFE, 0xFE, 0x00}, // 14 = yellow
-    {0xFE, 0xFE, 0xFE, 0x00}  // 15 = white
-  };
 
 static int vbe_detected = -1;
 
@@ -68,10 +42,8 @@ static struct
   grub_uint32_t active_mode;
   grub_uint8_t *ptr;
   int index_color_mode;
-  struct grub_video_palette_data palette[256];
 } framebuffer;
 
-static struct grub_video_render_target *render_target;
 static grub_uint32_t initial_mode;
 static grub_uint32_t mode_in_use = 0x55aa;
 static grub_uint16_t *mode_list;
@@ -239,11 +211,20 @@ grub_vbe_set_video_mode (grub_uint32_t mode,
 	{
 	  struct grub_vbe_palette_data *palette
 	    = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+	  unsigned i;
 
-	  /* Make sure that the BIOS can reach the palette.  */
-	  grub_memcpy (palette, vga_colors, sizeof (vga_colors));
-	  status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)
-						   / sizeof (struct grub_vbe_palette_data),
+	  /* Make sure that the BIOS can reach the palette.  */	  
+	  for (i = 0; i < sizeof (grub_video_fbstd_colors)
+		 / sizeof (grub_video_fbstd_colors[0]); i++)
+	    {
+	      palette[i].red = grub_video_fbstd_colors[i].r;
+	      palette[i].green = grub_video_fbstd_colors[i].g;
+	      palette[i].blue = grub_video_fbstd_colors[i].b;
+	      palette[i].alignment = 0;
+	    }
+
+	  status = grub_vbe_bios_set_palette_data (sizeof (grub_video_fbstd_colors)
+						   / sizeof (grub_video_fbstd_colors[0]),
 						   0,
 						   palette);
 
@@ -308,43 +289,6 @@ grub_vbe_get_video_mode_info (grub_uint32_t mode,
   return GRUB_ERR_NONE;
 }
 
-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_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;
-}
-
 static grub_err_t
 grub_video_vbe_init (void)
 {
@@ -387,9 +331,7 @@ grub_video_vbe_init (void)
 
   /* Reset frame buffer and render target variables.  */
   grub_memset (&framebuffer, 0, sizeof(framebuffer));
-  render_target = &framebuffer.render_target;
-
-  return GRUB_ERR_NONE;
+  return grub_video_fb_init ();
 }
 
 static grub_err_t
@@ -409,8 +351,7 @@ grub_video_vbe_fini (void)
 
   /* TODO: destroy render targets.  */
 
-  /* Return success to caller.  */
-  return GRUB_ERR_NONE;
+  return grub_video_fb_fini ();
 }
 
 static grub_err_t
@@ -422,7 +363,6 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
   struct grub_vbe_mode_info_block best_mode_info;
   grub_uint32_t best_mode = 0;
   int depth;
-  unsigned int i;
 
   /* Decode depth from mode_type.  If it is zero, then autodetect.  */
   depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
@@ -512,54 +452,63 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
          in order to fasten later operations.  */
       mode_in_use = best_mode;
 
-      /* Reset render target to framebuffer one.  */
-      render_target = &framebuffer.render_target;
-
       /* Fill mode info details in framebuffer's render target.  */
-      render_target->mode_info.width = active_mode_info.x_resolution;
-      render_target->mode_info.height = active_mode_info.y_resolution;
+      framebuffer.render_target.mode_info.width 
+	= active_mode_info.x_resolution;
+      framebuffer.render_target.mode_info.height 
+	= active_mode_info.y_resolution;
 
       if (framebuffer.index_color_mode)
-        render_target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+        framebuffer.render_target.mode_info.mode_type 
+	  = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
       else
-        render_target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
-
-      render_target->mode_info.bpp = active_mode_info.bits_per_pixel;
-      render_target->mode_info.bytes_per_pixel = framebuffer.bytes_per_pixel;
-      render_target->mode_info.pitch = framebuffer.bytes_per_scan_line;
-      render_target->mode_info.number_of_colors = 256; /* TODO: fix me.  */
-      render_target->mode_info.red_mask_size = active_mode_info.red_mask_size;
-      render_target->mode_info.red_field_pos = active_mode_info.red_field_position;
-      render_target->mode_info.green_mask_size = active_mode_info.green_mask_size;
-      render_target->mode_info.green_field_pos = active_mode_info.green_field_position;
-      render_target->mode_info.blue_mask_size = active_mode_info.blue_mask_size;
-      render_target->mode_info.blue_field_pos = active_mode_info.blue_field_position;
-      render_target->mode_info.reserved_mask_size = active_mode_info.rsvd_mask_size;
-      render_target->mode_info.reserved_field_pos = active_mode_info.rsvd_field_position;
-
-      render_target->mode_info.blit_format = grub_video_get_blit_format (&render_target->mode_info);
+        framebuffer.render_target.mode_info.mode_type 
+	  = GRUB_VIDEO_MODE_TYPE_RGB;
+
+      framebuffer.render_target.mode_info.bpp = active_mode_info.bits_per_pixel;
+      framebuffer.render_target.mode_info.bytes_per_pixel 
+	= framebuffer.bytes_per_pixel;
+      framebuffer.render_target.mode_info.pitch 
+	= framebuffer.bytes_per_scan_line;
+      framebuffer.render_target.mode_info.number_of_colors 
+	= 256; /* TODO: fix me.  */
+      framebuffer.render_target.mode_info.red_mask_size 
+	= active_mode_info.red_mask_size;
+      framebuffer.render_target.mode_info.red_field_pos 
+	= active_mode_info.red_field_position;
+      framebuffer.render_target.mode_info.green_mask_size 
+	= active_mode_info.green_mask_size;
+      framebuffer.render_target.mode_info.green_field_pos 
+	= active_mode_info.green_field_position;
+      framebuffer.render_target.mode_info.blue_mask_size 
+	= active_mode_info.blue_mask_size;
+      framebuffer.render_target.mode_info.blue_field_pos 
+	= active_mode_info.blue_field_position;
+      framebuffer.render_target.mode_info.reserved_mask_size 
+	= active_mode_info.rsvd_mask_size;
+      framebuffer.render_target.mode_info.reserved_field_pos 
+	= active_mode_info.rsvd_field_position;
+
+      framebuffer.render_target.mode_info.blit_format 
+	= grub_video_get_blit_format (&framebuffer.render_target.mode_info);
 
       /* Reset viewport to match new mode.  */
-      render_target->viewport.x = 0;
-      render_target->viewport.y = 0;
-      render_target->viewport.width = active_mode_info.x_resolution;
-      render_target->viewport.height = active_mode_info.y_resolution;
+      framebuffer.render_target.viewport.x = 0;
+      framebuffer.render_target.viewport.y = 0;
+      framebuffer.render_target.viewport.width = active_mode_info.x_resolution;
+      framebuffer.render_target.viewport.height = active_mode_info.y_resolution;
 
       /* Set framebuffer pointer and mark it as non allocated.  */
-      render_target->is_allocated = 0;
-      render_target->data = framebuffer.ptr;
+      framebuffer.render_target.is_allocated = 0;
+      framebuffer.render_target.data = framebuffer.ptr;
 
       /* Copy default palette to initialize emulated palette.  */
-      for (i = 0;
-           i < (sizeof (vga_colors)
-                / sizeof (struct grub_vbe_palette_data));
-           i++)
-        {
-          framebuffer.palette[i].r = vga_colors[i].red;
-          framebuffer.palette[i].g = vga_colors[i].green;
-          framebuffer.palette[i].b = vga_colors[i].blue;
-          framebuffer.palette[i].a = 0xFF;
-        }
+      grub_video_fb_set_palette (0, (sizeof (grub_video_fbstd_colors)
+				     / sizeof (grub_video_fbstd_colors[0])),
+				 grub_video_fbstd_colors);
+
+      /* Reset render target to framebuffer one.  */
+      grub_video_fb_set_active_render_target (&framebuffer.render_target);
 
       return GRUB_ERR_NONE;
     }
@@ -569,21 +518,9 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
 }
 
 static grub_err_t
-grub_video_vbe_get_info (struct grub_video_mode_info *mode_info)
-{
-  /* Copy mode info from active render target.  */
-  grub_memcpy (mode_info, &render_target->mode_info,
-               sizeof (struct grub_video_mode_info));
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
 grub_video_vbe_set_palette (unsigned int start, unsigned int count,
                             struct grub_video_palette_data *palette_data)
 {
-  unsigned int i;
-
   if (framebuffer.index_color_mode)
     {
       /* TODO: Implement setting indexed color mode palette to hardware.  */
@@ -595,28 +532,13 @@ grub_video_vbe_set_palette (unsigned int start, unsigned int count,
     }
 
   /* Then set color to emulated palette.  */
-  for (i = 0; (i < count) && ((i + start) < 256); i++)
-    framebuffer.palette[start + i] = palette_data[i];
-
-  return GRUB_ERR_NONE;
-}
 
-static grub_err_t
-grub_video_vbe_get_palette (unsigned int start, unsigned int count,
-                            struct grub_video_palette_data *palette_data)
-{
-  unsigned int i;
-
-  /* Assume that we know everything from index color palette.  */
-  for (i = 0; (i < count) && ((i + start) < 256); i++)
-    palette_data[i] = framebuffer.palette[start + i];
-
-  return GRUB_ERR_NONE;
+  return grub_video_fb_set_palette (start, count, palette_data);
 }
 
-static grub_err_t
+grub_err_t
 grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
-                             unsigned int width, unsigned int height)
+			    unsigned int width, unsigned int height)
 {
   /* Make sure viewport is withing screen dimensions.  If viewport was set
      to be out of the region, mark its size as zero.  */
@@ -637,832 +559,7 @@ grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
 
   if (y + height > active_mode_info.y_resolution)
     height = active_mode_info.y_resolution - y;
-
-  render_target->viewport.x = x;
-  render_target->viewport.y = y;
-  render_target->viewport.width = width;
-  render_target->viewport.height = height;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_get_viewport (unsigned int *x, unsigned int *y,
-                             unsigned int *width, unsigned int *height)
-{
-  if (x) *x = render_target->viewport.x;
-  if (y) *y = render_target->viewport.y;
-  if (width) *width = render_target->viewport.width;
-  if (height) *height = render_target->viewport.height;
-
-  return GRUB_ERR_NONE;
-}
-
-/* Maps color name to target optimized color format.  */
-static grub_video_color_t
-grub_video_vbe_map_color (grub_uint32_t color_name)
-{
-  /* TODO: implement color theme mapping code.  */
-
-  if (color_name < 256)
-    {
-      if ((render_target->mode_info.mode_type
-           & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
-        return color_name;
-      else
-        {
-          grub_video_color_t color;
-
-          color = grub_video_vbe_map_rgb (framebuffer.palette[color_name].r,
-                                          framebuffer.palette[color_name].g,
-                                          framebuffer.palette[color_name].b);
-
-          return color;
-        }
-    }
-
-  return 0;
-}
-
-/* Maps RGB to target optimized color format.  */
-grub_video_color_t
-grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green,
-                        grub_uint8_t blue)
-{
-  if ((render_target->mode_info.mode_type
-       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
-    {
-      int minindex = 0;
-      int delta = 0;
-      int tmp;
-      int val;
-      int i;
-
-      /* Find best matching color.  */
-      for (i = 0; i < 256; i++)
-        {
-          val = framebuffer.palette[i].r - red;
-          tmp = val * val;
-          val = framebuffer.palette[i].g - green;
-          tmp += val * val;
-          val = framebuffer.palette[i].b - blue;
-          tmp += val * val;
-
-          if (i == 0)
-            delta = tmp;
-
-          if (tmp < delta)
-            {
-              delta = tmp;
-              minindex = i;
-              if (tmp == 0)
-                break;
-            }
-        }
-
-      return minindex;
-    }
-  else if ((render_target->mode_info.mode_type
-            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
-    {
-       if (red == render_target->mode_info.fg_red
-           && green == render_target->mode_info.fg_green
-           && blue == render_target->mode_info.fg_blue)
-         return 1;
-       else
-         return 0;
-    }
-  else
-    {
-      grub_uint32_t value;
-      grub_uint8_t alpha = 255; /* Opaque color.  */
-
-      red >>= 8 - render_target->mode_info.red_mask_size;
-      green >>= 8 - render_target->mode_info.green_mask_size;
-      blue >>= 8 - render_target->mode_info.blue_mask_size;
-      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
-
-      value = red << render_target->mode_info.red_field_pos;
-      value |= green << render_target->mode_info.green_field_pos;
-      value |= blue << render_target->mode_info.blue_field_pos;
-      value |= alpha << render_target->mode_info.reserved_field_pos;
-
-      return value;
-    }
-
-}
-
-/* Maps RGBA to target optimized color format.  */
-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)
-{
-  if ((render_target->mode_info.mode_type
-       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
-    /* No alpha available in index color modes, just use
-       same value as in only RGB modes.  */
-    return grub_video_vbe_map_rgb (red, green, blue);
-  else if ((render_target->mode_info.mode_type
-            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
-    {
-      if (red == render_target->mode_info.fg_red
-          && green == render_target->mode_info.fg_green
-          && blue == render_target->mode_info.fg_blue
-          && alpha == render_target->mode_info.fg_alpha)
-        return 1;
-      else
-        return 0;
-    }
-  else
-    {
-      grub_uint32_t value;
-
-      red >>= 8 - render_target->mode_info.red_mask_size;
-      green >>= 8 - render_target->mode_info.green_mask_size;
-      blue >>= 8 - render_target->mode_info.blue_mask_size;
-      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
-
-      value = red << render_target->mode_info.red_field_pos;
-      value |= green << render_target->mode_info.green_field_pos;
-      value |= blue << render_target->mode_info.blue_field_pos;
-      value |= alpha << render_target->mode_info.reserved_field_pos;
-
-      return value;
-    }
-}
-
-/* Splits target optimized format to components.  */
-grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color,
-                                       grub_uint8_t *red, grub_uint8_t *green,
-                                       grub_uint8_t *blue, grub_uint8_t *alpha)
-{
-  struct grub_video_i386_vbeblit_info target_info;
-
-  target_info.mode_info = &render_target->mode_info;
-  target_info.data = render_target->data;
-
-  grub_video_vbe_unmap_color_int (&target_info, color, red, green, blue, alpha);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Splits color in source format to components.  */
-void
-grub_video_vbe_unmap_color_int (struct grub_video_i386_vbeblit_info * source,
-                                grub_video_color_t color,
-                                grub_uint8_t *red, grub_uint8_t *green,
-                                grub_uint8_t *blue, grub_uint8_t *alpha)
-{
-  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 an out-of-bounds color, return transparent black.  */
-      if (color > 255)
-        {
-          *red = 0;
-          *green = 0;
-          *blue = 0;
-          *alpha = 0;
-          return;
-        }
-
-      *red = framebuffer.palette[color].r;
-      *green = framebuffer.palette[color].g;
-      *blue = framebuffer.palette[color].b;
-      *alpha = framebuffer.palette[color].a;
-      return;
-    }
-  else if ((mode_info->mode_type
-            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
-    {
-      if (color & 1)
-        {
-          *red = mode_info->fg_red;
-          *green = mode_info->fg_green;
-          *blue = mode_info->fg_blue;
-          *alpha = mode_info->fg_alpha;
-        }
-      else
-        {
-          *red = mode_info->bg_red;
-          *green = mode_info->bg_green;
-          *blue = mode_info->bg_blue;
-          *alpha = mode_info->bg_alpha;
-        }
-    }
-  else
-    {
-      grub_uint32_t tmp;
-
-      /* Get red component.  */
-      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 >> 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 >> 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)
-        {
-          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.  */
-        tmp = 255;
-
-      *alpha = tmp & 0xFF;
-    }
-}
-
-static grub_err_t
-grub_video_vbe_fill_rect (grub_video_color_t color, int x, int y,
-                          unsigned int width, unsigned int height)
-{
-  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))
-    return GRUB_ERR_NONE;
-  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
-    return GRUB_ERR_NONE;
-
-  /* Do not allow drawing out of viewport.  */
-  if (x < 0)
-    {
-      width += x;
-      x = 0;
-    }
-  if (y < 0)
-    {
-      height += y;
-      y = 0;
-    }
-
-  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;
-
-  /* Add viewport offset.  */
-  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.  Note that color is already
-     mapped to target format so we can make assumptions based on that.  */
-  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-    {
-      grub_video_i386_vbefill_direct32 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-    {
-      grub_video_i386_vbefill_direct32 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-    {
-      grub_video_i386_vbefill_direct24 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
-    {
-      grub_video_i386_vbefill_direct16 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
-    {
-      grub_video_i386_vbefill_direct16 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-    {
-      grub_video_i386_vbefill_direct8 (&target, color, x, y,
-				       width, height);
-      return GRUB_ERR_NONE;
-    }
-
-  /* No optimized version found, use default (slow) filler.  */
-  grub_video_i386_vbefill (&target, color, x, y, width, height);
-
-  return GRUB_ERR_NONE;
-}
-
-/* NOTE: This function assumes that given coordinates 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_RGBA_8888)
-	{
-	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-	    {
-	      grub_video_i386_vbeblit_replace_directN (target, source,
-						       x, y, width, height,
-						       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-	    {
-	      grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (target, source,
-								 x, y, width, height,
-								 offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-	    {
-	      grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-	    {
-	      grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-	    {
-	      grub_video_i386_vbeblit_replace_index_RGBX8888 (target, source,
-							      x, y, width, height,
-							      offset_x, offset_y);
-	      return;
-	    }
-	}
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-	{
-	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-	    {
-	      grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-	    {
-	      grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-	    {
-	      grub_video_i386_vbeblit_replace_BGR888_RGB888 (target, source,
-							     x, y, width, height,
-							     offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-	    {
-	      grub_video_i386_vbeblit_replace_directN (target, source,
-						       x, y, width, height,
-						       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-	    {
-	      grub_video_i386_vbeblit_replace_index_RGB888 (target, source,
-							    x, y, width, height,
-							    offset_x, offset_y);
-	      return;
-	    }
-	}
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-	{
-	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-	    {
-	      grub_video_i386_vbeblit_replace_directN (target, source,
-						       x, y, width, height,
-						       offset_x, offset_y);
-	      return;
-	    }
-	}
-      else 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_replace_directN (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_RGBA_8888)
-	{
-	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-	    {
-	      grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-	    {
-	      grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-	    {
-	      grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (target, source,
-							     x, y, width, height,
-							     offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-	    {
-	      grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (target, source,
-							     x, y, width, height,
-							     offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-	    {
-	      grub_video_i386_vbeblit_blend_index_RGBA8888 (target, source,
-							    x, y, width, height,
-							    offset_x, offset_y);
-	      return;
-	    }
-	}
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-	{
-	  /* Note: There is really no alpha information here, so blend is
-	     changed to replace.  */
-
-	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-	    {
-	      grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-	    {
-	      grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (target, source,
-							       x, y, width, height,
-							       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-	    {
-	      grub_video_i386_vbeblit_replace_BGR888_RGB888 (target, source,
-							     x, y, width, height,
-							     offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-	    {
-	      grub_video_i386_vbeblit_replace_directN (target, source,
-						       x, y, width, height,
-						       offset_x, offset_y);
-	      return;
-	    }
-	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-	    {
-	      grub_video_i386_vbeblit_replace_index_RGB888 (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,
-                            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;
-
-  /* If we have negative coordinates, optimize drawing to minimum.  */
-  if (offset_x < 0)
-    {
-      width += offset_x;
-      x -= offset_x;
-      offset_x = 0;
-    }
-
-  if (offset_y < 0)
-    {
-      height += offset_y;
-      y -= offset_y;
-      offset_y = 0;
-    }
-
-  if (x < 0)
-    {
-      width += x;
-      offset_x -= x;
-      x = 0;
-    }
-
-  if (y < 0)
-    {
-      height += 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;
-
-  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;
-
-  /* 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)
-{
-  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))
-    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)source->mode_info.width) < 0)
-    return GRUB_ERR_NONE;
-  if ((y + (int)source->mode_info.height) < 0)
-    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;
-
-  /* If we have negative coordinates, optimize drawing to minimum.  */
-  if (offset_x < 0)
-    {
-      width += offset_x;
-      x -= offset_x;
-      offset_x = 0;
-    }
-
-  if (offset_y < 0)
-    {
-      height += offset_y;
-      y -= offset_y;
-      offset_y = 0;
-    }
-
-  if (x < 0)
-    {
-      width += x;
-      offset_x -= x;
-      x = 0;
-    }
-
-  if (y < 0)
-    {
-      height += 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;
-
-  if ((offset_x + width) > source->mode_info.width)
-    width = source->mode_info.width - offset_x;
-  if ((offset_y + height) > source->mode_info.height)
-    height = source->mode_info.height - offset_y;
-
-  /* Limit drawing to source render target dimensions.  */
-  if (width > source->mode_info.width)
-    width = source->mode_info.width;
-
-  if (height > source->mode_info.height)
-    height = source->mode_info.height;
-
-  /* Add viewport offset.  */
-  x += render_target->viewport.x;
-  y += render_target->viewport.y;
-
-  /* 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;
-
-  /* Do actual blitting.  */
-  common_blitter (&target_info, &source_info, oper, x, y, width, height,
-                  offset_x, offset_y);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_scroll (grub_video_color_t color, int dx, int dy)
-{
-  int width;
-  int height;
-  int src_x;
-  int src_y;
-  int dst_x;
-  int dst_y;
-
-  /* 1. Check if we have something to do.  */
-  if ((dx == 0) && (dy == 0))
-    return GRUB_ERR_NONE;
-
-  width = render_target->viewport.width - grub_abs (dx);
-  height = render_target->viewport.height - grub_abs (dy);
-
-  if (dx < 0)
-    {
-      src_x = render_target->viewport.x - dx;
-      dst_x = render_target->viewport.x;
-    }
-  else
-    {
-      src_x = render_target->viewport.x;
-      dst_x = render_target->viewport.x + dx;
-    }
-
-  if (dy < 0)
-    {
-      src_y = render_target->viewport.y - dy;
-      dst_y = render_target->viewport.y;
-    }
-  else
-    {
-      src_y = render_target->viewport.y;
-      dst_y = render_target->viewport.y + dy;
-    }
-
-  /* 2. Check if there is need to copy data.  */
-  if ((grub_abs (dx) < render_target->viewport.width)
-       && (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;
-
-      /* Check vertical direction of the move.  */
-      if (dy <= 0)
-	/* 3a. Move data upwards.  */
-	for (j = 0; j < height; 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 * target.mode_info->bytes_per_pixel);
-	  }
-      else
-	/* 3b. Move data downwards.  */
-	for (j = (height - 1); j >= 0; 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 * target.mode_info->bytes_per_pixel);
-	  }
-    }
-
-  /* 4. Fill empty space with specified color.  In this implementation
-     there might be colliding areas but at the moment there is no need
-     to optimize this.  */
-
-  /* 4a. Fill top & bottom parts.  */
-  if (dy > 0)
-    grub_video_vbe_fill_rect (color, 0, 0, render_target->viewport.width, dy);
-  else if (dy < 0)
-    {
-      if (render_target->viewport.height < grub_abs (dy))
-        dy = -render_target->viewport.height;
-
-      grub_video_vbe_fill_rect (color, 0, render_target->viewport.height + dy,
-                                render_target->viewport.width, -dy);
-    }
-
-  /* 4b. Fill left & right parts.  */
-  if (dx > 0)
-    grub_video_vbe_fill_rect (color, 0, 0,
-                              dx, render_target->viewport.height);
-  else if (dx < 0)
-    {
-      if (render_target->viewport.width < grub_abs (dx))
-        dx = -render_target->viewport.width;
-
-      grub_video_vbe_fill_rect (color, render_target->viewport.width + dx, 0,
-                                -dx, render_target->viewport.height);
-    }
-
-  return GRUB_ERR_NONE;
+  return grub_video_fb_set_viewport (x, y, width, height);
 }
 
 static grub_err_t
@@ -1473,126 +570,16 @@ grub_video_vbe_swap_buffers (void)
 }
 
 static grub_err_t
-grub_video_vbe_create_render_target (struct grub_video_render_target **result,
-                                     unsigned int width, unsigned int height,
-                                     unsigned int mode_type __attribute__ ((unused)))
-{
-  struct grub_video_render_target *target;
-  unsigned int size;
-
-  /* Validate arguments.  */
-  if ((! result)
-      || (width == 0)
-      || (height == 0))
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "invalid argument given.");
-
-  /* Allocate memory for render target.  */
-  target = grub_malloc (sizeof (struct grub_video_render_target));
-  if (! target)
-    return grub_errno;
-
-  /* TODO: Implement other types too.
-     Currently only 32bit render targets are supported.  */
-
-  /* Mark render target as allocated.  */
-  target->is_allocated = 1;
-
-  /* Maximize viewport.  */
-  target->viewport.x = 0;
-  target->viewport.y = 0;
-  target->viewport.width = width;
-  target->viewport.height = height;
-
-  /* Setup render target format.  */
-  target->mode_info.width = width;
-  target->mode_info.height = height;
-  target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
-                                | GRUB_VIDEO_MODE_TYPE_ALPHA;
-  target->mode_info.bpp = 32;
-  target->mode_info.bytes_per_pixel = 4;
-  target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
-  target->mode_info.number_of_colors = 256; /* Emulated palette.  */
-  target->mode_info.red_mask_size = 8;
-  target->mode_info.red_field_pos = 0;
-  target->mode_info.green_mask_size = 8;
-  target->mode_info.green_field_pos = 8;
-  target->mode_info.blue_mask_size = 8;
-  target->mode_info.blue_field_pos = 16;
-  target->mode_info.reserved_mask_size = 8;
-  target->mode_info.reserved_field_pos = 24;
-
-  target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
-
-  /* Calculate size needed for the data.  */
-  size = (width * target->mode_info.bytes_per_pixel) * height;
-
-  target->data = grub_malloc (size);
-  if (! target->data)
-    {
-      grub_free (target);
-      return grub_errno;
-    }
-
-  /* Clear render target with black and maximum transparency.  */
-  grub_memset (target->data, 0, size);
-
-  /* TODO: Add render target to render target list.  */
-
-  /* Save result to caller.  */
-  *result = target;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_delete_render_target (struct grub_video_render_target *target)
-{
-  /* If there is no target, then just return without error.  */
-  if (! target)
-    return GRUB_ERR_NONE;
-
-  /* TODO: Delist render target from render target list.  */
-
-  /* If this is software render target, free it's memory.  */
-  if (target->is_allocated)
-    grub_free (target->data);
-
-  /* Free render target.  */
-  grub_free (target);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
 grub_video_vbe_set_active_render_target (struct grub_video_render_target *target)
 {
   if (target == GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER)
-    {
-      render_target = &framebuffer.render_target;
-
-      return GRUB_ERR_NONE;
-    }
+    return grub_video_fb_set_active_render_target (&framebuffer.render_target);
 
   if (target == GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER)
     return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
                        "double buffering not implemented yet.");
 
-  if (! target->data)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "invalid render target given.");
-
-  render_target = target;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
-{
-  *target = render_target;
-
-  return GRUB_ERR_NONE;
+    return grub_video_fb_set_active_render_target (target);
 }
 
 static struct grub_video_adapter grub_video_vbe_adapter =
@@ -1602,24 +589,24 @@ static struct grub_video_adapter grub_video_vbe_adapter =
     .init = grub_video_vbe_init,
     .fini = grub_video_vbe_fini,
     .setup = grub_video_vbe_setup,
-    .get_info = grub_video_vbe_get_info,
+    .get_info = grub_video_fb_get_info,
     .set_palette = grub_video_vbe_set_palette,
-    .get_palette = grub_video_vbe_get_palette,
-    .set_viewport = grub_video_vbe_set_viewport,
-    .get_viewport = grub_video_vbe_get_viewport,
-    .map_color = grub_video_vbe_map_color,
-    .map_rgb = grub_video_vbe_map_rgb,
-    .map_rgba = grub_video_vbe_map_rgba,
-    .unmap_color = grub_video_vbe_unmap_color,
-    .fill_rect = grub_video_vbe_fill_rect,
-    .blit_bitmap = grub_video_vbe_blit_bitmap,
-    .blit_render_target = grub_video_vbe_blit_render_target,
-    .scroll = grub_video_vbe_scroll,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
     .swap_buffers = grub_video_vbe_swap_buffers,
-    .create_render_target = grub_video_vbe_create_render_target,
-    .delete_render_target = grub_video_vbe_delete_render_target,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
     .set_active_render_target = grub_video_vbe_set_active_render_target,
-    .get_active_render_target = grub_video_vbe_get_active_render_target,
+    .get_active_render_target = grub_video_fb_get_active_render_target,
 
     .next = 0
   };
diff --git a/video/i386/pc/vbeblit.c b/video/i386/pc/vbeblit.c
deleted file mode 100644
index 4121bfe..0000000
--- a/video/i386/pc/vbeblit.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* 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/machine/vbeutil.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/video.h>
-
-/* Generic replacing blitter (slow).  Works for every supported format.  */
-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;
-
-  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_int (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);
-	}
-    }
-}
-
-/* Block copy replacing blitter.  Works with modes multiple of 8 bits.  */
-void
-grub_video_i386_vbeblit_replace_directN (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 bpp;
-
-  bpp = src->mode_info->bytes_per_pixel;
-
-  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 * bpp);
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to BGRX8888.  */
-void
-grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (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;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t r = *srcptr++;
-          grub_uint8_t g = *srcptr++;
-          grub_uint8_t b = *srcptr++;
-          grub_uint8_t a = *srcptr++;
-
-          *dstptr++ = b;
-          *dstptr++ = g;
-          *dstptr++ = r;
-          *dstptr++ = a;
-        }
-
-      srcptr += srcrowskip;
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to BGRX8888.  */
-void
-grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (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;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t r = *srcptr++;
-          grub_uint8_t g = *srcptr++;
-          grub_uint8_t b = *srcptr++;
-
-          *dstptr++ = b;
-          *dstptr++ = g;
-          *dstptr++ = r;
-
-          /* Set alpha component as opaque.  */
-          *dstptr++ = 255;
-        }
-
-      srcptr += srcrowskip;
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to BGR888.  */
-void
-grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (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 *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-  int i;
-  int j;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint32_t color;
-          grub_uint8_t sr;
-          grub_uint8_t sg;
-          grub_uint8_t sb;
-
-          color = *srcptr++;
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          *dstptr++ = sb;
-          *dstptr++ = sg;
-          *dstptr++ = sr;
-        }
-
-      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to BGR888.  */
-void
-grub_video_i386_vbeblit_replace_BGR888_RGB888 (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;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t r = *srcptr++;
-          grub_uint8_t g = *srcptr++;
-          grub_uint8_t b = *srcptr++;
-
-          *dstptr++ = b;
-          *dstptr++ = g;
-          *dstptr++ = r;
-        }
-
-      srcptr += srcrowskip;
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to RGBX8888.  */
-void
-grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (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_uint8_t *srcptr;
-  grub_uint32_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-
-  for (j = 0; j < height; 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++)
-        {
-          sr = *srcptr++;
-          sg = *srcptr++;
-          sb = *srcptr++;
-
-          /* Set alpha as opaque.  */
-          color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
-
-          *dstptr++ = color;
-        }
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to RGB888.  */
-void
-grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (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;
-
-  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;
-	}
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to indexed color.  */
-void
-grub_video_i386_vbeblit_replace_index_RGBX8888 (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;
-
-  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;
-	}
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to indexed color.  */
-void
-grub_video_i386_vbeblit_replace_index_RGB888 (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_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-
-  for (j = 0; j < height; 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++)
-        {
-          sr = *srcptr++;
-          sg = *srcptr++;
-          sb = *srcptr++;
-
-          color = grub_video_vbe_map_rgb(sr, sg, sb);
-
-          *dstptr++ = color & 0xFF;
-        }
-    }
-}
-
-/* Generic blending blitter.  Works for every supported format.  */
-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;
-
-  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 = get_pixel (src, i + offset_x, j + offset_y);
-          grub_video_vbe_unmap_color_int (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_int (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);
-        }
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to BGRA8888.  */
-void
-grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (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 *srcptr;
-  grub_uint32_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-  int i;
-  int j;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint32_t *) get_data_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint32_t color;
-          unsigned int sr;
-          unsigned int sg;
-          unsigned int sb;
-          unsigned int a;
-          unsigned int dr;
-          unsigned int dg;
-          unsigned int db;
-
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              /* Skip transparent source pixels.  */
-              dstptr++;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              /* Opaque pixel shortcut.  */
-              dr = sr;
-              dg = sg;
-              db = sb;
-            }
-          else
-            {
-              /* General pixel color blending.  */
-              color = *dstptr;
-
-              dr = (color >> 16) & 0xFF;
-              dr = (dr * (255 - a) + sr * a) / 255;
-              dg = (color >> 8) & 0xFF;
-              dg = (dg * (255 - a) + sg * a) / 255;
-              db = (color >> 0) & 0xFF;
-              db = (db * (255 - a) + sb * a) / 255;
-            }
-
-          color = (a << 24) | (dr << 16) | (dg << 8) | db;
-
-          *dstptr++ = color;
-        }
-
-      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
-      dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to BGR888.  */
-void
-grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (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 *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-  int i;
-  int j;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint32_t color;
-          unsigned int sr;
-          unsigned int sg;
-          unsigned int sb;
-          unsigned int a;
-          unsigned int dr;
-          unsigned int dg;
-          unsigned int db;
-
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              /* Skip transparent source pixels.  */
-              dstptr += 3;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              /* Opaque pixel shortcut.  */
-              dr = sr;
-              dg = sg;
-              db = sb;
-            }
-          else
-            {
-              /* General pixel color blending.  */
-              color = *dstptr;
-
-              db = dstptr[0];
-              db = (db * (255 - a) + sb * a) / 255;
-              dg = dstptr[1];
-              dg = (dg * (255 - a) + sg * a) / 255;
-              dr = dstptr[2];
-              dr = (dr * (255 - a) + sr * a) / 255;
-            }
-
-          *dstptr++ = db;
-          *dstptr++ = dg;
-          *dstptr++ = dr;
-        }
-
-      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized blending blitter for RGBA888 to RGBA8888.  */
-void
-grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (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_uint32_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-  unsigned int a;
-  unsigned int dr;
-  unsigned int dg;
-  unsigned int db;
-
-  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);
-
-      for (i = 0; i < width; i++)
-        {
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              dstptr++;
-              continue;
-            }
-
-          if (a == 255)
-            {
-              *dstptr++ = color;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          color = *dstptr;
-
-          dr = (color >> 0) & 0xFF;
-          dg = (color >> 8) & 0xFF;
-          db = (color >> 16) & 0xFF;
-
-          dr = (dr * (255 - a) + sr * a) / 255;
-          dg = (dg * (255 - a) + sg * a) / 255;
-          db = (db * (255 - a) + sb * a) / 255;
-
-          color = (a << 24) | (db << 16) | (dg << 8) | dr;
-
-          *dstptr++ = color;
-        }
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to RGB888.  */
-void
-grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (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;
-  unsigned int a;
-  unsigned int dr;
-  unsigned int dg;
-  unsigned int db;
-
-  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++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              dstptr += 3;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              *dstptr++ = sr;
-              *dstptr++ = sg;
-              *dstptr++ = sb;
-
-              continue;
-            }
-
-          dr = dstptr[0];
-          dg = dstptr[1];
-          db = dstptr[2];
-
-          dr = (dr * (255 - a) + sr * a) / 255;
-          dg = (dg * (255 - a) + sg * a) / 255;
-          db = (db * (255 - a) + sb * a) / 255;
-
-          *dstptr++ = dr;
-          *dstptr++ = dg;
-          *dstptr++ = db;
-        }
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to indexed color.  */
-void
-grub_video_i386_vbeblit_blend_index_RGBA8888 (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;
-  unsigned int a;
-  unsigned char dr;
-  unsigned char dg;
-  unsigned char db;
-  unsigned char da;
-
-  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++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              dstptr++;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              color = grub_video_vbe_map_rgb(sr, sg, sb);
-              *dstptr++ = color & 0xFF;
-              continue;
-            }
-
-          grub_video_vbe_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
-
-          dr = (dr * (255 - a) + sr * a) / 255;
-          dg = (dg * (255 - a) + sg * a) / 255;
-          db = (db * (255 - a) + sb * a) / 255;
-
-          color = grub_video_vbe_map_rgb(dr, dg, db);
-
-          *dstptr++ = color & 0xFF;
-        }
-    }
-}
diff --git a/video/i386/pc/vbefill.c b/video/i386/pc/vbefill.c
deleted file mode 100644
index 3a98a71..0000000
--- a/video/i386/pc/vbefill.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* 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/video.h>
-
-/* Generic filler that works for every supported mode.  */
-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;
-
-  for (j = 0; j < height; j++)
-    for (i = 0; i < width; i++)
-      set_pixel (dst, x+i, y+j, color);
-}
-
-/* Optimized filler for direct color 32 bit modes.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_i386_vbefill_direct32 (struct grub_video_i386_vbeblit_info *dst,
-                                  grub_video_color_t color, int x, int y,
-                                  int width, int height)
-{
-  int i;
-  int j;
-  grub_uint32_t *dstptr;
-  grub_size_t rowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint32_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        *dstptr++ = color;
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip);
-    }
-}
-
-/* Optimized filler for direct color 24 bit modes.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_i386_vbefill_direct24 (struct grub_video_i386_vbeblit_info *dst,
-                                  grub_video_color_t color, int x, int y,
-                                  int width, int height)
-{
-  int i;
-  int j;
-  grub_size_t rowskip;
-  grub_uint8_t *dstptr;
-  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
-  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
-  grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          *dstptr++ = fill0;
-          *dstptr++ = fill1;
-          *dstptr++ = fill2;
-        }
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr += rowskip;
-    }
-}
-
-/* Optimized filler for direct color 16 bit modes.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_i386_vbefill_direct16 (struct grub_video_i386_vbeblit_info *dst,
-                                  grub_video_color_t color, int x, int y,
-                                  int width, int height)
-{
-  int i;
-  int j;
-  grub_size_t rowskip;
-  grub_uint8_t *dstptr;
-  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
-  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          *dstptr++ = fill0;
-          *dstptr++ = fill1;
-        }
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr += rowskip;
-    }
-}
-
-/* Optimized filler for index color.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_i386_vbefill_direct8 (struct grub_video_i386_vbeblit_info *dst,
-				 grub_video_color_t color, int x, int y,
-				 int width, int height)
-{
-  int i;
-  int j;
-  grub_size_t rowskip;
-  grub_uint8_t *dstptr;
-  grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        *dstptr++ = fill;
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr += rowskip;
-    }
-}
diff --git a/video/i386/pc/vbeutil.c b/video/i386/pc/vbeutil.c
deleted file mode 100644
index 1040dc9..0000000
--- a/video/i386/pc/vbeutil.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/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;
-
-    case 1:
-      /* For 1-bit bitmaps, addressing needs to be done at the bit level
-         and it doesn't make sense, in general, to ask for a pointer
-         to a particular pixel's data.  */
-      break;
-    }
-
-  return ptr;
-}
-
-grub_video_color_t
-get_pixel (struct grub_video_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;
-
-    case 1:
-      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
-        {
-          int bit_index = y * source->mode_info->width + x;
-          grub_uint8_t *ptr = (grub_uint8_t *)source->data
-                              + bit_index / 8;
-          int bit_pos = 7 - bit_index % 8;
-          color = (*ptr >> bit_pos) & 0x01;
-        }
-      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;
-
-    case 1:
-      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
-        {
-          int bit_index = y * source->mode_info->width + x;
-          grub_uint8_t *ptr = (grub_uint8_t *)source->data
-                              + bit_index / 8;
-          int bit_pos = 7 - bit_index % 8;
-          *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
-        }
-      break;
-
-    default:
-      break;
-    }
-}
diff --git a/video/video.c b/video/video.c
index c22947b..8271d79 100644
--- a/video/video.c
+++ b/video/video.c
@@ -654,6 +654,8 @@ grub_video_set_mode (char *modestring,
 	  if (err != GRUB_ERR_NONE)
 	    {
 	      p->fini ();
+	      grub_dprintf ("video", "Failed to setup mode %dx%d (%x) on %s\n", 
+			    width, height, flags, p->name);
 	      grub_errno = GRUB_ERR_NONE;
 	      continue;
 	    }
@@ -662,6 +664,8 @@ grub_video_set_mode (char *modestring,
 	  if (err != GRUB_ERR_NONE)
 	    {
 	      p->fini ();
+	      grub_dprintf ("video", "Failed to get info: %dx%d (%x) on %s\n", 
+			    width, height, flags, p->name);
 	      grub_errno = GRUB_ERR_NONE;
 	      continue;
 	    }

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-06-15 15:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-15 15:15 [WIP PATCH 1/2] Split framebuffer from vbe Vladimir 'phcoder' Serbinenko
2009-06-15 15:16 ` Vladimir 'phcoder' Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.