* Copyright 2005-2015, Axel DΓΆrfler, axeld@pinc-software.de.
* Copyright 2016, Jessica Hamilton, jessica.l.hamilton@gmail.com.
* Distributed under the terms of the MIT License.
*/
#include <stdlib.h>
#include <string.h>
#include <compute_display_timing.h>
#include <create_display_modes.h>
#include "accelerant_protos.h"
#include "accelerant.h"
#include "utility.h"
#ifdef TRACE_MODE
extern "C" void _sPrintf(const char* format, ...);
# define TRACE(x) _sPrintf x
#else
# define TRACE(x) ;
#endif
bool
operator==(const display_mode &lhs, const display_mode &rhs)
{
return lhs.space == rhs.space
&& lhs.virtual_width == rhs.virtual_width
&& lhs.virtual_height == rhs.virtual_height
&& lhs.h_display_start == rhs.h_display_start
&& lhs.v_display_start == rhs.v_display_start;
}
static bool
is_mode_supported(display_mode* mode)
{
return (mode != NULL) && (*mode == gInfo->shared_info->current_mode);
}
It's called from vesa_init_accelerant().
*/
status_t
create_mode_list(void)
{
const color_space colorspace[] = {
(color_space)gInfo->shared_info->current_mode.space
};
display_mode mode = gInfo->shared_info->current_mode;
compute_display_timing(mode.virtual_width, mode.virtual_height, 60, false,
&mode.timing);
fill_display_mode(mode.virtual_width, mode.virtual_height, &mode);
gInfo->mode_list_area = create_display_modes("framebuffer modes",
NULL, &mode, 1, colorspace, 1, is_mode_supported, &gInfo->mode_list,
&gInfo->shared_info->mode_count);
if (gInfo->mode_list_area < 0)
return gInfo->mode_list_area;
gInfo->shared_info->mode_list_area = gInfo->mode_list_area;
return B_OK;
}
uint32
framebuffer_accelerant_mode_count(void)
{
TRACE(("framebuffer_accelerant_mode_count() = %d\n",
gInfo->shared_info->mode_count));
return gInfo->shared_info->mode_count;
}
status_t
framebuffer_get_mode_list(display_mode* modeList)
{
TRACE(("framebuffer_get_mode_info()\n"));
memcpy(modeList, gInfo->mode_list,
gInfo->shared_info->mode_count * sizeof(display_mode));
return B_OK;
}
status_t
framebuffer_set_display_mode(display_mode* _mode)
{
TRACE(("framebuffer_set_display_mode()\n"));
if (_mode != NULL && *_mode == gInfo->shared_info->current_mode)
return B_OK;
return B_UNSUPPORTED;
}
status_t
framebuffer_get_display_mode(display_mode* _currentMode)
{
TRACE(("framebuffer_get_display_mode()\n"));
*_currentMode = gInfo->shared_info->current_mode;
return B_OK;
}
status_t
framebuffer_get_edid_info(void* info, size_t size, uint32* _version)
{
TRACE(("framebuffer_get_edid_info()\n"));
if (!gInfo->shared_info->has_edid)
return B_ERROR;
if (size < sizeof(struct edid1_info))
return B_BUFFER_OVERFLOW;
memcpy(info, &gInfo->shared_info->edid_info, sizeof(struct edid1_info));
*_version = EDID_VERSION_1;
return B_OK;
}
status_t
framebuffer_get_frame_buffer_config(frame_buffer_config* config)
{
TRACE(("framebuffer_get_frame_buffer_config()\n"));
config->frame_buffer = gInfo->shared_info->frame_buffer;
config->frame_buffer_dma = gInfo->shared_info->physical_frame_buffer;
config->bytes_per_row = gInfo->shared_info->bytes_per_row;
return B_OK;
}
status_t
framebuffer_get_pixel_clock_limits(display_mode* mode, uint32* _low, uint32* _high)
{
TRACE(("framebuffer_get_pixel_clock_limits()\n"));
uint32 totalPixel = (uint32)mode->timing.h_total
* (uint32)mode->timing.v_total;
uint32 clockLimit = 2000000;
*_low = totalPixel * 48L / 1000L;
if (*_low > clockLimit)
return B_ERROR;
*_high = clockLimit;
return B_OK;
}