📄 vbe.c
字号:
status = grub_vbe_bios_set_mode (initial_mode, 0); if (status != GRUB_VBE_STATUS_OK) /* TODO: Decide, is this something we want to do. */ return grub_errno; /* TODO: Free any resources allocated by driver. */ grub_free (mode_list); mode_list = 0; /* TODO: destroy render targets. */ /* Return success to caller. */ return GRUB_ERR_NONE;}static grub_err_tgrub_video_vbe_setup (unsigned int width, unsigned int height, unsigned int mode_type){ grub_uint16_t *p; struct grub_vbe_mode_info_block mode_info; 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) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; /* Walk thru mode list and try to find matching mode. */ for (p = mode_list; *p != 0xFFFF; p++) { grub_uint32_t mode = *p; grub_vbe_get_video_mode_info (mode, &mode_info); if (grub_errno != GRUB_ERR_NONE) { /* Could not retrieve mode info, retreat. */ grub_errno = GRUB_ERR_NONE; break; } if ((mode_info.mode_attributes & 0x001) == 0) /* If not available, skip it. */ continue; if ((mode_info.mode_attributes & 0x002) == 0) /* Not enough information. */ continue; if ((mode_info.mode_attributes & 0x008) == 0) /* Monochrome is unusable. */ continue; if ((mode_info.mode_attributes & 0x080) == 0) /* We support only linear frame buffer modes. */ continue; if ((mode_info.mode_attributes & 0x010) == 0) /* We allow only graphical modes. */ continue; if ((mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL) && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)) /* Not compatible memory model. */ continue; if ((mode_info.x_resolution != width) || (mode_info.y_resolution != height)) /* Non matching resolution. */ continue; /* Check if user requested RGB or index color mode. */ if ((mode_type & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0) { if (((mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)) /* Requested only index color modes. */ continue; if (((mode_type & GRUB_VIDEO_MODE_TYPE_RGB) != 0) && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)) /* Requested only RGB modes. */ continue; } /* If there is a request for specific depth, ignore others. */ if ((depth != 0) && (mode_info.bits_per_pixel != depth)) continue; /* Select mode with most number of bits per pixel. */ if (best_mode != 0) if (mode_info.bits_per_pixel < best_mode_info.bits_per_pixel) continue; /* Save so far best mode information for later use. */ best_mode = mode; grub_memcpy (&best_mode_info, &mode_info, sizeof (mode_info)); } /* Try to initialize best mode found. */ if (best_mode != 0) { /* If this fails, then we have mode selection heuristics problem, or adapter failure. */ grub_vbe_set_video_mode (best_mode, &active_mode_info); if (grub_errno != GRUB_ERR_NONE) return grub_errno; /* Now we are happily in requested video mode. Cache some info 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; if (framebuffer.index_color_mode) 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); /* 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; /* Set framebuffer pointer and mark it as non allocated. */ render_target->is_allocated = 0; 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; } return GRUB_ERR_NONE; } /* Couldn't found matching mode. */ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found.");}static grub_err_tgrub_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_tgrub_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. */ //status = grub_vbe_bios_set_palette_data (sizeof (vga_colors) // / sizeof (struct grub_vbe_palette_data), // 0, // palette); } /* 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_tgrub_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;}static grub_err_tgrub_video_vbe_set_viewport (unsigned int x, unsigned int y, unsigned int width, unsigned int height){ /* Make sure viewport is withing screen dimensions. If viewport was set to be out of the reqion, mark its size as zero. */ if (x > active_mode_info.x_resolution) { x = 0; width = 0; } if (y > active_mode_info.y_resolution) { y = 0; height = 0; } if (x + width > active_mode_info.x_resolution) width = active_mode_info.x_resolution - x; 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_tgrub_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;}static grub_video_color_tgrub_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;}grub_video_color_tgrub_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 { 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; }}grub_video_color_tgrub_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 { 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; }}voidgrub_video_vbe_unmap_color (struct grub_video_i386_vbeblit_info * source, grub_video_color_t color, grub_uint8_t *red, grub_uint8_t *green, grub_uint8_t *blue, grub_uint8_t *alpha){ struct grub_video_mode_info *mode_info; mode_info = source->mode_info; if ((mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) { /* If we have out of bounds color, return trasnparent black. */ if (color > 255) { *red = 0; *green = 0; *blue = 0; *alpha = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -