* Added a new list_insert_item_before() function that inserts a new item
before another one in the list. * The video modes in the boot loader are now sorted (by resolution, larger resolution comes first). Doubled entries are automatically removed; this fixes bug #192. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16572 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5370f52b15
commit
d5062208bb
@ -1,7 +1,7 @@
|
||||
/*
|
||||
** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef KERNEL_LIST_H
|
||||
#define KERNEL_LIST_H
|
||||
|
||||
@ -50,6 +50,7 @@ extern void *list_get_next_item(struct list *list, void *item);
|
||||
extern void *list_get_prev_item(struct list *list, void *item);
|
||||
extern void list_add_item(struct list *list, void *item);
|
||||
extern void list_remove_item(struct list *list, void *item);
|
||||
extern void list_insert_item_before(struct list *list, void *before, void *item);
|
||||
extern void *list_remove_head_item(struct list *list);
|
||||
extern void *list_remove_tail_item(struct list *list);
|
||||
extern void list_move_to_list(struct list *sourceList, struct list *targetList);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -46,6 +46,102 @@ static bool sModeChosen;
|
||||
static bool sSettingsLoaded;
|
||||
|
||||
|
||||
static int
|
||||
compare_video_modes(video_mode *a, video_mode *b)
|
||||
{
|
||||
int compare = a->width - b->width;
|
||||
if (compare != 0)
|
||||
return compare;
|
||||
|
||||
compare = a->height - b->height;
|
||||
if (compare != 0)
|
||||
return compare;
|
||||
|
||||
// TODO: compare video_mode::mode?
|
||||
return a->bits_per_pixel - b->bits_per_pixel;
|
||||
}
|
||||
|
||||
|
||||
/** Insert the video mode into the list, sorted by resolution and bit depth.
|
||||
* Higher resolutions/depths come first.
|
||||
*/
|
||||
|
||||
static void
|
||||
add_video_mode(video_mode *videoMode)
|
||||
{
|
||||
video_mode *mode = NULL;
|
||||
while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) {
|
||||
int compare = compare_video_modes(videoMode, mode);
|
||||
if (compare == 0) {
|
||||
// mode already exists
|
||||
return;
|
||||
}
|
||||
|
||||
if (compare > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
list_insert_item_before(&sModeList, mode, videoMode);
|
||||
}
|
||||
|
||||
|
||||
static video_mode *
|
||||
find_video_mode(int32 width, int32 height, int32 depth)
|
||||
{
|
||||
video_mode *mode = NULL;
|
||||
while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) {
|
||||
if (mode->width == width
|
||||
&& mode->height == height
|
||||
&& mode->bits_per_pixel == depth) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_mode_from_settings(void)
|
||||
{
|
||||
if (sSettingsLoaded)
|
||||
return;
|
||||
|
||||
void *handle = load_driver_settings("vesa");
|
||||
if (handle == NULL)
|
||||
return;
|
||||
|
||||
const driver_settings *settings = get_driver_settings(handle);
|
||||
if (settings == NULL)
|
||||
goto out;
|
||||
|
||||
sSettingsLoaded = true;
|
||||
|
||||
for (int32 i = 0; i < settings->parameter_count; i++) {
|
||||
driver_parameter ¶meter = settings->parameters[i];
|
||||
|
||||
if (!strcmp(parameter.name, "mode") && parameter.value_count > 2) {
|
||||
// parameter found, now get its values
|
||||
int32 width = strtol(parameter.values[0], NULL, 0);
|
||||
int32 height = strtol(parameter.values[1], NULL, 0);
|
||||
int32 depth = strtol(parameter.values[2], NULL, 0);
|
||||
|
||||
// search mode that fits
|
||||
|
||||
video_mode *mode = find_video_mode(width, height, depth);
|
||||
if (mode != NULL)
|
||||
sMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
unload_driver_settings(handle);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - vga
|
||||
|
||||
|
||||
static void
|
||||
vga_set_palette(const uint8 *palette, int32 firstIndex, int32 numEntries)
|
||||
{
|
||||
@ -189,7 +285,7 @@ vesa_init(vbe_info_block *info, video_mode **_standardMode)
|
||||
}
|
||||
}
|
||||
|
||||
list_add_item(&sModeList, videoMode);
|
||||
add_video_mode(videoMode);
|
||||
}
|
||||
} else
|
||||
TRACE(("(failed)\n"));
|
||||
@ -344,60 +440,6 @@ video_mode_menu()
|
||||
}
|
||||
|
||||
|
||||
static video_mode *
|
||||
find_video_mode(int32 width, int32 height, int32 depth)
|
||||
{
|
||||
video_mode *mode = NULL;
|
||||
while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) {
|
||||
if (mode->width == width
|
||||
&& mode->height == height
|
||||
&& mode->bits_per_pixel == depth) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_mode_from_settings(void)
|
||||
{
|
||||
if (sSettingsLoaded)
|
||||
return;
|
||||
|
||||
void *handle = load_driver_settings("vesa");
|
||||
if (handle == NULL)
|
||||
return;
|
||||
|
||||
const driver_settings *settings = get_driver_settings(handle);
|
||||
if (settings == NULL)
|
||||
goto out;
|
||||
|
||||
sSettingsLoaded = true;
|
||||
|
||||
for (int32 i = 0; i < settings->parameter_count; i++) {
|
||||
driver_parameter ¶meter = settings->parameters[i];
|
||||
|
||||
if (!strcmp(parameter.name, "mode") && parameter.value_count > 2) {
|
||||
// parameter found, now get its values
|
||||
int32 width = strtol(parameter.values[0], NULL, 0);
|
||||
int32 height = strtol(parameter.values[1], NULL, 0);
|
||||
int32 depth = strtol(parameter.values[2], NULL, 0);
|
||||
|
||||
// search mode that fits
|
||||
|
||||
video_mode *mode = find_video_mode(width, height, depth);
|
||||
if (mode != NULL)
|
||||
sMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
unload_driver_settings(handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_vga_mode(void)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <util/list.h>
|
||||
@ -156,6 +156,33 @@ list_remove_item(struct list *list, void *item)
|
||||
}
|
||||
|
||||
|
||||
/** Inserts an item before another item in the list.
|
||||
* If you pass NULL as \a before item, the item is added at the end of
|
||||
* the list.
|
||||
*/
|
||||
|
||||
void
|
||||
list_insert_item_before(struct list *list, void *before, void *item)
|
||||
{
|
||||
list_link *beforeLink;
|
||||
list_link *link;
|
||||
|
||||
if (before == NULL) {
|
||||
list_add_item(list, item);
|
||||
return;
|
||||
}
|
||||
|
||||
beforeLink = GET_LINK(list, before);
|
||||
link = GET_LINK(list, item);
|
||||
|
||||
link->prev = beforeLink->prev;
|
||||
link->next = beforeLink;
|
||||
|
||||
beforeLink->prev->next = link;
|
||||
beforeLink->prev = link;
|
||||
}
|
||||
|
||||
|
||||
/** Removes the first item in the list and returns it.
|
||||
* Returns NULL if the list is empty.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user