Now maintains a list of possible video modes, and creates a real video

mode menu that even works.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8111 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-06-22 00:35:19 +00:00
parent 3be048bd11
commit f42302bcc8
+60 -24
View File
@@ -1,6 +1,6 @@
/* /*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved. ** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. ** Distributed under the terms of the Haiku License.
*/ */
@@ -15,13 +15,22 @@
#include <boot/platform.h> #include <boot/platform.h>
#include <boot/menu.h> #include <boot/menu.h>
#include <boot/kernel_args.h> #include <boot/kernel_args.h>
#include <util/list.h>
#include <stdio.h>
#include <string.h> #include <string.h>
struct video_mode {
list_link link;
uint16 mode;
int32 width, height, bits_per_pixel;
};
static vbe_info_block sInfo; static vbe_info_block sInfo;
uint16 sMode; video_mode *sMode;
bool sVesaCompatible; bool sVesaCompatible;
struct list sModeList;
static void static void
@@ -93,12 +102,15 @@ vesa_get_vbe_info_block(vbe_info_block *info)
static status_t static status_t
vesa_init(vbe_info_block *info, uint16 *_standardMode) vesa_init(vbe_info_block *info, video_mode **_standardMode)
{ {
if (vesa_get_vbe_info_block(info) != B_OK) if (vesa_get_vbe_info_block(info) != B_OK)
return B_ERROR; return B_ERROR;
dprintf("mode list:\n"); // fill mode list
video_mode *standardMode = NULL;
int32 i = 0; int32 i = 0;
while (true) { while (true) {
uint16 mode = ((uint16 *)info->mode_list)[i++]; uint16 mode = ((uint16 *)info->mode_list)[i++];
@@ -117,22 +129,45 @@ vesa_init(vbe_info_block *info, uint16 *_standardMode)
const uint32 requiredAttributes = MODE_ATTR_AVAILABLE | MODE_ATTR_GRAPHICS_MODE const uint32 requiredAttributes = MODE_ATTR_AVAILABLE | MODE_ATTR_GRAPHICS_MODE
| MODE_ATTR_COLOR_MODE | MODE_ATTR_LINEAR_BUFFER; | MODE_ATTR_COLOR_MODE | MODE_ATTR_LINEAR_BUFFER;
if (modeInfo.width >= 800 if (modeInfo.width >= 640
&& modeInfo.physical_base != 0 && modeInfo.physical_base != 0
&& modeInfo.num_planes == 1 && modeInfo.num_planes == 1
&& (modeInfo.memory_model == MODE_MEMORY_PACKED_PIXEL && (modeInfo.memory_model == MODE_MEMORY_PACKED_PIXEL
|| modeInfo.memory_model == MODE_MEMORY_DIRECT_COLOR) || modeInfo.memory_model == MODE_MEMORY_DIRECT_COLOR)
&& (modeInfo.attributes & requiredAttributes) == requiredAttributes && (modeInfo.attributes & requiredAttributes) == requiredAttributes) {
&& modeInfo.bits_per_pixel == 8) { // this mode fits our needs
*_standardMode = mode; video_mode *videoMode = (video_mode *)malloc(sizeof(struct video_mode));
return B_OK; if (videoMode == NULL)
continue;
videoMode->mode = mode;
videoMode->width = modeInfo.width;
videoMode->height = modeInfo.height;
videoMode->bits_per_pixel = modeInfo.bits_per_pixel;
// ToDo: for now, only accept 8 bit modes as standard
if (standardMode == NULL && modeInfo.bits_per_pixel == 8)
standardMode = videoMode;
else if (standardMode != NULL) {
// switch to the one with the higher resolution
// ToDo: is that always a good idea?
if (modeInfo.width > standardMode->width)
standardMode = videoMode;
}
list_add_item(&sModeList, videoMode);
} }
} else } else
dprintf("(failed)\n"); dprintf("(failed)\n");
} }
// no usable VESA mode found... if (standardMode == NULL) {
return B_ERROR; // no usable VESA mode found...
return B_ERROR;
}
*_standardMode = standardMode;
return B_OK;
} }
@@ -209,11 +244,11 @@ vesa_set_palette(const uint8 *palette, int32 firstIndex, int32 numEntries)
extern "C" void extern "C" void
platform_switch_to_logo(void) platform_switch_to_logo(void)
{ {
if (!sVesaCompatible) if (!sVesaCompatible || sMode == NULL)
// no logo for now... // no logo for now...
return; return;
if (vesa_set_mode(sMode) != B_OK) if (vesa_set_mode(sMode->mode) != B_OK)
return; return;
gKernelArgs.fb.enabled = 1; gKernelArgs.fb.enabled = 1;
@@ -221,7 +256,7 @@ platform_switch_to_logo(void)
if (!gKernelArgs.fb.already_mapped) { if (!gKernelArgs.fb.already_mapped) {
// the graphics memory has not been mapped yet! // the graphics memory has not been mapped yet!
struct vbe_mode_info modeInfo; struct vbe_mode_info modeInfo;
if (vesa_get_mode_info(sMode, &modeInfo) != B_OK) { if (vesa_get_mode_info(sMode->mode, &modeInfo) != B_OK) {
platform_switch_to_text_mode(); platform_switch_to_text_mode();
return; return;
} }
@@ -276,7 +311,7 @@ platform_switch_to_text_mode(void)
Menu * Menu *
video_mode_menu() video_mode_menu()
{ {
Menu *menu = new Menu(CHOICE_MENU); Menu *menu = new Menu(CHOICE_MENU, "Select video mode:");
MenuItem *item; MenuItem *item;
menu->AddItem(item = new MenuItem("Default")); menu->AddItem(item = new MenuItem("Default"));
@@ -285,13 +320,13 @@ video_mode_menu()
menu->AddItem(new MenuItem("Standard VGA")); menu->AddItem(new MenuItem("Standard VGA"));
if (sVesaCompatible) { video_mode *mode = NULL;
// add VESA modes while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) {
menu->AddItem(new MenuItem("1024x768 32bit")); char label[64];
menu->AddItem(new MenuItem("800x600 16bit")); sprintf(label, "%ldx%ld %ld bit", mode->width, mode->height, mode->bits_per_pixel);
menu->AddItem(new MenuItem("800x600 15bit"));
menu->AddItem(new MenuItem("800x600 8bit")); menu->AddItem(item = new MenuItem(label));
menu->AddItem(new MenuItem("640x480 8bit")); item->SetData(mode);
} }
menu->AddSeparatorItem(); menu->AddSeparatorItem();
@@ -301,10 +336,11 @@ video_mode_menu()
} }
extern "C" status_t extern "C" status_t
video_init(void) platform_init_video(void)
{ {
gKernelArgs.fb.enabled = 0; gKernelArgs.fb.enabled = 0;
list_init(&sModeList);
sVesaCompatible = vesa_init(&sInfo, &sMode) == B_OK; sVesaCompatible = vesa_init(&sInfo, &sMode) == B_OK;
if (!sVesaCompatible) { if (!sVesaCompatible) {