Preferred resolution detection for VBE.
+ * grub-core/video/video.c (grub_video_edid_checksum): New function.
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info):
- New function.
+ Likewise.
(grub_vbe_bios_get_ddc_capabilities): Likewise.
(grub_vbe_bios_read_edid): Likewise.
- (grub_vbe_edid_checksum): Likewise.
(grub_vbe_get_preferred_mode): Likewise. Try EDID followed by the
Flat Panel extension, in line with the X.org VESA driver.
(grub_video_vbe_setup): When the mode is "auto", try to get the
than the preferred mode (some BIOSes expose a preferred mode that is
not in their mode list!). If this fails, fall back to 640x480 as a
safe conservative choice.
+ * include/grub/video.h (struct grub_vbe_edid_info): New structure.
+ (grub_video_edid_checksum): Add prototype.
* include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New
structure.
- (struct grub_vbe_edid_info): Likewise.
(grub_vbe_bios_get_flat_panel_info): Add prototype.
(grub_vbe_bios_get_ddc_capabilities): Likewise.
(grub_vbe_bios_read_edid): Likewise.
/* Call VESA BIOS 0x4f15 to read EDID information, return status. */
grub_vbe_status_t
-grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_info)
+grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_info)
{
struct grub_bios_int_registers regs;
return GRUB_ERR_NONE;
}
-static grub_err_t
-grub_vbe_edid_checksum (struct grub_vbe_edid_info *edid_info)
-{
- const char *edid_bytes = (const char *) edid_info;
- int i;
- char checksum = 0;
-
- /* Check EDID checksum. */
- for (i = 0; i < 128; ++i)
- checksum += edid_bytes[i];
-
- if (checksum != 0)
- return grub_error (GRUB_ERR_BAD_DEVICE,
- "invalid EDID checksum %d", checksum);
-
- grub_errno = GRUB_ERR_NONE;
- return grub_errno;
-}
-
static grub_err_t
grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height)
{
grub_vbe_status_t status;
grub_uint8_t ddc_level;
- struct grub_vbe_edid_info edid_info;
+ struct grub_video_edid_info edid_info;
struct grub_vbe_flat_panel_info flat_panel_info;
if (controller_info.version >= 0x200
/* Bit 1 in the Feature Support field indicates that the first
Detailed Timing Description is the preferred timing mode. */
if (status == GRUB_VBE_STATUS_OK
- && grub_vbe_edid_checksum (&edid_info) == GRUB_ERR_NONE
+ && grub_video_edid_checksum (&edid_info) == GRUB_ERR_NONE
&& edid_info.version == 1 /* we don't understand later versions */
&& (edid_info.feature_support
- & GRUB_VBE_EDID_FEATURE_PREFERRED_TIMING_MODE)
+ & GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE)
&& edid_info.detailed_timings[0].pixel_clock)
{
*width = edid_info.detailed_timings[0].horizontal_active_lo
return grub_video_adapter_active->get_active_render_target (target);
}
+grub_err_t
+grub_video_edid_checksum (struct grub_video_edid_info *edid_info)
+{
+ const char *edid_bytes = (const char *) edid_info;
+ int i;
+ char checksum = 0;
+
+ /* Check EDID checksum. */
+ for (i = 0; i < 128; ++i)
+ checksum += edid_bytes[i];
+
+ if (checksum != 0)
+ return grub_error (GRUB_ERR_BAD_DEVICE,
+ "invalid EDID checksum %d", checksum);
+
+ grub_errno = GRUB_ERR_NONE;
+ return grub_errno;
+}
+
/* Parse <width>x<height>[x<depth>]*/
static grub_err_t
parse_modespec (const char *current_mode, int *width, int *height, int *depth)
#ifndef GRUB_VBE_MACHINE_HEADER
#define GRUB_VBE_MACHINE_HEADER 1
+#include <grub/video.h>
+
/* Default video mode to be used. */
#define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101
grub_uint8_t reserved[14];
} __attribute__ ((packed));
-struct grub_vbe_edid_info
-{
- grub_uint8_t header[8];
- grub_uint16_t manufacturer_id;
- grub_uint16_t product_id;
- grub_uint32_t serial_number;
- grub_uint8_t week_of_manufacture;
- grub_uint8_t year_of_manufacture;
- grub_uint8_t version;
- grub_uint8_t revision;
-
- grub_uint8_t video_input_definition;
- grub_uint8_t max_horizontal_image_size;
- grub_uint8_t max_vertical_image_size;
- grub_uint8_t display_gamma;
- grub_uint8_t feature_support;
-#define GRUB_VBE_EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1)
-
- grub_uint8_t red_green_lo;
- grub_uint8_t blue_white_lo;
- grub_uint8_t red_x_hi;
- grub_uint8_t red_y_hi;
- grub_uint8_t green_x_hi;
- grub_uint8_t green_y_hi;
- grub_uint8_t blue_x_hi;
- grub_uint8_t blue_y_hi;
- grub_uint8_t white_x_hi;
- grub_uint8_t white_y_hi;
-
- grub_uint8_t established_timings_1;
- grub_uint8_t established_timings_2;
- grub_uint8_t manufacturer_reserved_timings;
-
- grub_uint16_t standard_timings[8];
-
- struct {
- grub_uint16_t pixel_clock;
- /* Only valid if the pixel clock is non-null. */
- grub_uint8_t horizontal_active_lo;
- grub_uint8_t horizontal_blanking_lo;
- grub_uint8_t horizontal_hi;
- grub_uint8_t vertical_active_lo;
- grub_uint8_t vertical_blanking_lo;
- grub_uint8_t vertical_hi;
- grub_uint8_t horizontal_sync_offset_lo;
- grub_uint8_t horizontal_sync_pulse_width_lo;
- grub_uint8_t vertical_sync_lo;
- grub_uint8_t sync_hi;
- grub_uint8_t horizontal_image_size_lo;
- grub_uint8_t vertical_image_size_lo;
- grub_uint8_t image_size_hi;
- grub_uint8_t horizontal_border;
- grub_uint8_t vertical_border;
- grub_uint8_t flags;
- } detailed_timings[4];
-
- grub_uint8_t extension_flag;
- grub_uint8_t checksum;
-} __attribute__ ((packed));
-
/* Prototypes for helper functions. */
/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */
grub_vbe_status_t
grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level);
/* Call VESA BIOS 0x4f15 to read EDID information, return status. */
grub_vbe_status_t
-grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_data);
+grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_data);
grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *width);
grub_uint8_t a; /* Reserved bits value (0-255). */
};
+struct grub_video_edid_info
+{
+ grub_uint8_t header[8];
+ grub_uint16_t manufacturer_id;
+ grub_uint16_t product_id;
+ grub_uint32_t serial_number;
+ grub_uint8_t week_of_manufacture;
+ grub_uint8_t year_of_manufacture;
+ grub_uint8_t version;
+ grub_uint8_t revision;
+
+ grub_uint8_t video_input_definition;
+ grub_uint8_t max_horizontal_image_size;
+ grub_uint8_t max_vertical_image_size;
+ grub_uint8_t display_gamma;
+ grub_uint8_t feature_support;
+#define GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1)
+
+ grub_uint8_t red_green_lo;
+ grub_uint8_t blue_white_lo;
+ grub_uint8_t red_x_hi;
+ grub_uint8_t red_y_hi;
+ grub_uint8_t green_x_hi;
+ grub_uint8_t green_y_hi;
+ grub_uint8_t blue_x_hi;
+ grub_uint8_t blue_y_hi;
+ grub_uint8_t white_x_hi;
+ grub_uint8_t white_y_hi;
+
+ grub_uint8_t established_timings_1;
+ grub_uint8_t established_timings_2;
+ grub_uint8_t manufacturer_reserved_timings;
+
+ grub_uint16_t standard_timings[8];
+
+ struct {
+ grub_uint16_t pixel_clock;
+ /* Only valid if the pixel clock is non-null. */
+ grub_uint8_t horizontal_active_lo;
+ grub_uint8_t horizontal_blanking_lo;
+ grub_uint8_t horizontal_hi;
+ grub_uint8_t vertical_active_lo;
+ grub_uint8_t vertical_blanking_lo;
+ grub_uint8_t vertical_hi;
+ grub_uint8_t horizontal_sync_offset_lo;
+ grub_uint8_t horizontal_sync_pulse_width_lo;
+ grub_uint8_t vertical_sync_lo;
+ grub_uint8_t sync_hi;
+ grub_uint8_t horizontal_image_size_lo;
+ grub_uint8_t vertical_image_size_lo;
+ grub_uint8_t image_size_hi;
+ grub_uint8_t horizontal_border;
+ grub_uint8_t vertical_border;
+ grub_uint8_t flags;
+ } detailed_timings[4];
+
+ grub_uint8_t extension_flag;
+ grub_uint8_t checksum;
+} __attribute__ ((packed));
+
typedef enum grub_video_driver_id
{
GRUB_VIDEO_DRIVER_NONE,
grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
+grub_err_t grub_video_edid_checksum (struct grub_video_edid_info *edid_info);
+
grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring,
unsigned int modemask,
unsigned int modevalue);