2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/video.h>
20 #include <grub/types.h>
23 /* The list of video adapters registered to system. */
24 static grub_video_adapter_t grub_video_adapter_list
;
26 /* Active video adapter. */
27 static grub_video_adapter_t grub_video_adapter_active
;
29 /* Register video driver. */
31 grub_video_register (grub_video_adapter_t adapter
)
33 adapter
->next
= grub_video_adapter_list
;
34 grub_video_adapter_list
= adapter
;
37 /* Unregister video driver. */
39 grub_video_unregister (grub_video_adapter_t adapter
)
41 grub_video_adapter_t
*p
, q
;
43 for (p
= &grub_video_adapter_list
, q
= *p
; q
; p
= &(q
->next
), q
= q
->next
)
51 /* Iterate thru all registered video drivers. */
53 grub_video_iterate (int (*hook
) (grub_video_adapter_t adapter
))
55 grub_video_adapter_t p
;
57 for (p
= grub_video_adapter_list
; p
; p
= p
->next
)
62 /* Setup specified video mode. */
64 grub_video_setup (unsigned int width
, unsigned int height
,
65 unsigned int mode_type
)
67 grub_video_adapter_t p
;
69 /* De-activate last set video adapter. */
70 if (grub_video_adapter_active
)
72 /* Finalize adapter. */
73 grub_video_adapter_active
->fini ();
74 if (grub_errno
!= GRUB_ERR_NONE
)
77 /* Mark active adapter as not set. */
78 grub_video_adapter_active
= 0;
81 /* Loop thru all possible video adapter trying to find requested mode. */
82 for (p
= grub_video_adapter_list
; p
; p
= p
->next
)
84 /* Try to initialize adapter, if it fails, skip to next adapter. */
86 if (grub_errno
!= GRUB_ERR_NONE
)
88 grub_errno
= GRUB_ERR_NONE
;
92 /* Try to initialize video mode. */
93 p
->setup (width
, height
, mode_type
);
94 if (grub_errno
== GRUB_ERR_NONE
)
96 /* Valid mode found from adapter, and it has been activated.
97 Specify it as active adapter. */
98 grub_video_adapter_active
= p
;
102 grub_errno
= GRUB_ERR_NONE
;
104 /* No valid mode found in this adapter, finalize adapter. */
106 if (grub_errno
!= GRUB_ERR_NONE
)
110 /* We couldn't find suitable adapter for specified mode. */
111 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
,
112 "Can't locate valid adapter for mode");
115 /* Restore back to initial mode (where applicable). */
117 grub_video_restore (void)
119 if (grub_video_adapter_active
)
121 grub_video_adapter_active
->fini ();
122 if (grub_errno
!= GRUB_ERR_NONE
)
125 grub_video_adapter_active
= 0;
127 return GRUB_ERR_NONE
;
130 /* Get information about active video mode. */
132 grub_video_get_info (struct grub_video_mode_info
*mode_info
)
134 if (! grub_video_adapter_active
)
135 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
137 /* If mode_info is NULL just report that video adapter is active. */
140 grub_errno
= GRUB_ERR_NONE
;
144 return grub_video_adapter_active
->get_info (mode_info
);
147 /* Determine optimized blitting formation for specified video mode info. */
148 enum grub_video_blit_format
149 grub_video_get_blit_format (struct grub_video_mode_info
*mode_info
)
151 /* Check if we have any known 32 bit modes. */
152 if (mode_info
->bpp
== 32)
154 if ((mode_info
->red_mask_size
== 8)
155 && (mode_info
->red_field_pos
== 16)
156 && (mode_info
->green_mask_size
== 8)
157 && (mode_info
->green_field_pos
== 8)
158 && (mode_info
->blue_mask_size
== 8)
159 && (mode_info
->blue_field_pos
== 0))
161 return GRUB_VIDEO_BLIT_FORMAT_BGRA_8888
;
163 else if ((mode_info
->red_mask_size
== 8)
164 && (mode_info
->red_field_pos
== 0)
165 && (mode_info
->green_mask_size
== 8)
166 && (mode_info
->green_field_pos
== 8)
167 && (mode_info
->blue_mask_size
== 8)
168 && (mode_info
->blue_field_pos
== 16))
170 return GRUB_VIDEO_BLIT_FORMAT_RGBA_8888
;
173 /* Check if we have any known 24 bit modes. */
174 else if (mode_info
->bpp
== 24)
176 if ((mode_info
->red_mask_size
== 8)
177 && (mode_info
->red_field_pos
== 16)
178 && (mode_info
->green_mask_size
== 8)
179 && (mode_info
->green_field_pos
== 8)
180 && (mode_info
->blue_mask_size
== 8)
181 && (mode_info
->blue_field_pos
== 0))
183 return GRUB_VIDEO_BLIT_FORMAT_BGR_888
;
185 else if ((mode_info
->red_mask_size
== 8)
186 && (mode_info
->red_field_pos
== 0)
187 && (mode_info
->green_mask_size
== 8)
188 && (mode_info
->green_field_pos
== 8)
189 && (mode_info
->blue_mask_size
== 8)
190 && (mode_info
->blue_field_pos
== 16))
192 return GRUB_VIDEO_BLIT_FORMAT_RGB_888
;
195 /* Check if we have any known 16 bit modes. */
196 else if (mode_info
->bpp
== 16)
198 if ((mode_info
->red_mask_size
== 5)
199 && (mode_info
->red_field_pos
== 11)
200 && (mode_info
->green_mask_size
== 6)
201 && (mode_info
->green_field_pos
== 5)
202 && (mode_info
->blue_mask_size
== 5)
203 && (mode_info
->blue_field_pos
== 0))
205 return GRUB_VIDEO_BLIT_FORMAT_BGR_565
;
207 else if ((mode_info
->red_mask_size
== 5)
208 && (mode_info
->red_field_pos
== 0)
209 && (mode_info
->green_mask_size
== 6)
210 && (mode_info
->green_field_pos
== 5)
211 && (mode_info
->blue_mask_size
== 5)
212 && (mode_info
->blue_field_pos
== 11))
214 return GRUB_VIDEO_BLIT_FORMAT_RGB_565
;
218 /* Backup route. Unknown format. */
220 /* If there are more than 8 bits per color, assume RGB(A) mode. */
221 if (mode_info
->bpp
> 8)
223 if (mode_info
->reserved_mask_size
> 0)
225 return GRUB_VIDEO_BLIT_FORMAT_RGBA
;
229 return GRUB_VIDEO_BLIT_FORMAT_RGB
;
233 /* Assume as indexcolor mode. */
234 return GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR
;
237 /* Set new indexed color palette entries. */
239 grub_video_set_palette (unsigned int start
, unsigned int count
,
240 struct grub_video_palette_data
*palette_data
)
242 if (! grub_video_adapter_active
)
243 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
245 return grub_video_adapter_active
->set_palette (start
, count
, palette_data
);
248 /* Get indexed color palette entries. */
250 grub_video_get_palette (unsigned int start
, unsigned int count
,
251 struct grub_video_palette_data
*palette_data
)
253 if (! grub_video_adapter_active
)
254 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
256 return grub_video_adapter_active
->get_palette (start
, count
, palette_data
);
259 /* Set viewport dimensions. */
261 grub_video_set_viewport (unsigned int x
, unsigned int y
,
262 unsigned int width
, unsigned int height
)
264 if (! grub_video_adapter_active
)
265 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
267 return grub_video_adapter_active
->set_viewport (x
, y
, width
, height
);
270 /* Get viewport dimensions. */
272 grub_video_get_viewport (unsigned int *x
, unsigned int *y
,
273 unsigned int *width
, unsigned int *height
)
275 if (! grub_video_adapter_active
)
276 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
278 return grub_video_adapter_active
->get_viewport (x
, y
, width
, height
);
281 /* Map color name to adapter specific color. */
283 grub_video_map_color (grub_uint32_t color_name
)
285 if (! grub_video_adapter_active
)
288 return grub_video_adapter_active
->map_color (color_name
);
291 /* Map RGB value to adapter specific color. */
293 grub_video_map_rgb (grub_uint8_t red
, grub_uint8_t green
, grub_uint8_t blue
)
295 if (! grub_video_adapter_active
)
298 return grub_video_adapter_active
->map_rgb (red
, green
, blue
);
301 /* Map RGBA value to adapter specific color. */
303 grub_video_map_rgba (grub_uint8_t red
, grub_uint8_t green
, grub_uint8_t blue
,
306 if (! grub_video_adapter_active
)
309 return grub_video_adapter_active
->map_rgba (red
, green
, blue
, alpha
);
312 /* Unmap video color back to RGBA components. */
314 grub_video_unmap_color (grub_video_color_t color
, grub_uint8_t
*red
,
315 grub_uint8_t
*green
, grub_uint8_t
*blue
,
318 if (! grub_video_adapter_active
)
319 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
321 return grub_video_adapter_active
->unmap_color (color
,
328 /* Fill rectangle using specified color. */
330 grub_video_fill_rect (grub_video_color_t color
, int x
, int y
,
331 unsigned int width
, unsigned int height
)
333 if (! grub_video_adapter_active
)
334 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
336 return grub_video_adapter_active
->fill_rect (color
, x
, y
, width
, height
);
339 /* Blit bitmap to screen. */
341 grub_video_blit_bitmap (struct grub_video_bitmap
*bitmap
,
342 enum grub_video_blit_operators oper
,
343 int x
, int y
, int offset_x
, int offset_y
,
344 unsigned int width
, unsigned int height
)
346 if (! grub_video_adapter_active
)
347 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
349 return grub_video_adapter_active
->blit_bitmap (bitmap
, oper
, x
, y
,
354 /* Blit render target to active render target. */
356 grub_video_blit_render_target (struct grub_video_render_target
*target
,
357 enum grub_video_blit_operators oper
,
358 int x
, int y
, int offset_x
, int offset_y
,
359 unsigned int width
, unsigned int height
)
361 if (! grub_video_adapter_active
)
362 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
364 return grub_video_adapter_active
->blit_render_target (target
, oper
, x
, y
,
369 /* Scroll viewport and fill new areas with specified color. */
371 grub_video_scroll (grub_video_color_t color
, int dx
, int dy
)
373 if (! grub_video_adapter_active
)
374 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
376 return grub_video_adapter_active
->scroll (color
, dx
, dy
);
379 /* Swap buffers (swap active render target). */
381 grub_video_swap_buffers (void)
383 if (! grub_video_adapter_active
)
384 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
386 return grub_video_adapter_active
->swap_buffers ();
389 /* Create new render target. */
391 grub_video_create_render_target (struct grub_video_render_target
**result
,
392 unsigned int width
, unsigned int height
,
393 unsigned int mode_type
)
395 if (! grub_video_adapter_active
)
396 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
398 return grub_video_adapter_active
->create_render_target (result
,
403 /* Delete render target. */
405 grub_video_delete_render_target (struct grub_video_render_target
*target
)
407 if (! grub_video_adapter_active
)
408 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
410 return grub_video_adapter_active
->delete_render_target (target
);
413 /* Set active render target. */
415 grub_video_set_active_render_target (struct grub_video_render_target
*target
)
417 if (! grub_video_adapter_active
)
418 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
420 return grub_video_adapter_active
->set_active_render_target (target
);
423 /* Get active render target. */
425 grub_video_get_active_render_target (struct grub_video_render_target
**target
)
427 if (! grub_video_adapter_active
)
428 return grub_error (GRUB_ERR_BAD_DEVICE
, "No video mode activated");
430 return grub_video_adapter_active
->get_active_render_target (target
);
433 /* Initialize Video API module. */
434 GRUB_MOD_INIT(video_video
)
436 grub_video_adapter_active
= 0;
437 grub_video_adapter_list
= 0;
440 /* Finalize Video API module. */
441 GRUB_MOD_FINI(video_video
)