/* videoinfo.c - command to list video modes. */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2005,2007,2008,2009,2010 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 . */ #include #include #include #include #include #include #include GRUB_MOD_LICENSE ("GPLv3+"); static unsigned height, width, depth; static struct grub_video_mode_info *current_mode; static int hook (const struct grub_video_mode_info *info) { if (height && width && (info->width != width || info->height != height)) return 0; if (depth && info->bpp != depth) return 0; if (info->mode_number == GRUB_VIDEO_MODE_NUMBER_INVALID) grub_printf (" "); else { if (current_mode && info->mode_number == current_mode->mode_number) grub_printf ("*"); else grub_printf (" "); grub_printf (" 0x%03x ", info->mode_number); } grub_printf ("%4d x %4d x %2d ", info->width, info->height, info->bpp); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) grub_xputs (_("Text-only ")); /* Show mask and position details for direct color modes. */ if (info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB) grub_printf_ (N_("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d"), info->red_mask_size, info->green_mask_size, info->blue_mask_size, info->reserved_mask_size, info->red_field_pos, info->green_field_pos, info->blue_field_pos, info->reserved_field_pos); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) grub_xputs (_("Packed ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_YUV) grub_xputs (_("YUV ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PLANAR) grub_xputs (_("Planar ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_HERCULES) grub_xputs (_("Hercules ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_CGA) grub_xputs (_("CGA ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_NONCHAIN4) grub_xputs (_("Non-chain 4 ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) grub_xputs (_("Monochrome ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_UNKNOWN) grub_xputs (_("Unknown ")); grub_xputs ("\n"); return 0; } static void print_edid (struct grub_video_edid_info *edid_info) { unsigned int edid_width, edid_height; if (grub_video_edid_checksum (edid_info)) { grub_puts_ (N_(" EDID checksum invalid")); grub_errno = GRUB_ERR_NONE; return; } grub_printf_ (N_(" EDID version: %u.%u\n"), edid_info->version, edid_info->revision); if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height) == GRUB_ERR_NONE) grub_printf_ (N_(" Preferred mode: %ux%u\n"), edid_width, edid_height); else { grub_printf_ (N_(" No preferred mode available\n")); grub_errno = GRUB_ERR_NONE; } } static grub_err_t grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_video_adapter_t adapter; grub_video_driver_id_t id; height = width = depth = 0; if (argc) { char *ptr; ptr = args[0]; width = grub_strtoul (ptr, &ptr, 0); if (grub_errno) return grub_errno; if (*ptr != 'x') return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid mode specification"); ptr++; height = grub_strtoul (ptr, &ptr, 0); if (grub_errno) return grub_errno; if (*ptr == 'x') { ptr++; depth = grub_strtoul (ptr, &ptr, 0); if (grub_errno) return grub_errno; } } #ifdef GRUB_MACHINE_PCBIOS if (grub_strcmp (cmd->name, "vbeinfo") == 0) grub_dl_load ("vbe"); #endif id = grub_video_get_driver_id (); grub_puts_ (N_("List of supported video modes:")); grub_puts_ (N_("Legend: P=Packed pixel, D=Direct color, " "mask/pos=R/G/B/reserved")); FOR_VIDEO_ADAPTERS (adapter) { struct grub_video_mode_info info; struct grub_video_edid_info edid_info; grub_printf_ (N_("Adapter '%s':\n"), adapter->name); if (!adapter->iterate) { grub_puts_ (N_(" No info available")); continue; } current_mode = NULL; if (adapter->id == id) { if (grub_video_get_info (&info) == GRUB_ERR_NONE) current_mode = &info; else /* Don't worry about errors. */ grub_errno = GRUB_ERR_NONE; } else { if (adapter->init ()) { grub_puts_ (N_(" Failed")); grub_errno = GRUB_ERR_NONE; continue; } } if (adapter->print_adapter_specific_info) adapter->print_adapter_specific_info (); adapter->iterate (hook); if (adapter->get_edid && adapter->get_edid (&edid_info) == GRUB_ERR_NONE) print_edid (&edid_info); else grub_errno = GRUB_ERR_NONE; current_mode = NULL; if (adapter->id != id) { if (adapter->fini ()) { grub_errno = GRUB_ERR_NONE; continue; } } } return GRUB_ERR_NONE; } static grub_command_t cmd; #ifdef GRUB_MACHINE_PCBIOS static grub_command_t cmd_vbe; #endif GRUB_MOD_INIT(videoinfo) { cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, N_("[WxH[xD]]"), N_("List available video modes. If " "resolution is given show only modes" " matching it.")); #ifdef GRUB_MACHINE_PCBIOS cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, N_("[WxH[xD]]"), N_("List available video modes. If " "resolution is given show only modes" " matching it.")); #endif } GRUB_MOD_FINI(videoinfo) { grub_unregister_command (cmd); #ifdef GRUB_MACHINE_PCBIOS grub_unregister_command (cmd_vbe); #endif }