* Started accelerant extension to be able to get the preferred mode from
the accelerant, as well as its EDID info. B_GET_PREFERRED_DISPLAY_MODE and B_GET_EDID_INFO are both optional. The preferred mode will be taken from the EDID info if only the latter hook is implemented, or the former returned an error. * Currently, the app_server should correctly set the preferred mode on start, but no accelerant supports that yet, so it's not really tested. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22520 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -41,6 +41,8 @@ enum {
|
||||
B_DPMS_CAPABILITIES, /* required if driver supports DPMS */
|
||||
B_DPMS_MODE, /* required if driver supports DPMS */
|
||||
B_SET_DPMS_MODE, /* required if driver supports DPMS */
|
||||
B_GET_PREFERRED_DISPLAY_MODE, /* optional */
|
||||
B_GET_EDID_INFO, /* optional */
|
||||
|
||||
/* cursor managment */
|
||||
B_MOVE_CURSOR = 0x200, /* optional */
|
||||
@@ -213,6 +215,8 @@ typedef void (*set_indexed_colors)(uint count, uint8 first, uint8 *color_data, u
|
||||
typedef uint32 (*dpms_capabilities)(void);
|
||||
typedef uint32 (*dpms_mode)(void);
|
||||
typedef status_t (*set_dpms_mode)(uint32 dpms_flags);
|
||||
typedef status_t (*get_preferred_display_mode)(display_mode *preferredMode);
|
||||
typedef status_t (*get_edid_info)(void *info, uint32 size, uint32 *_version);
|
||||
typedef sem_id (*accelerant_retrace_semaphore)(void);
|
||||
|
||||
typedef status_t (*set_cursor_shape)(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask);
|
||||
|
||||
@@ -86,7 +86,7 @@ Screen::Shutdown()
|
||||
|
||||
|
||||
status_t
|
||||
Screen::SetMode(display_mode mode, bool makeDefault)
|
||||
Screen::SetMode(const display_mode& mode, bool makeDefault)
|
||||
{
|
||||
gBitmapManager->SuspendOverlays();
|
||||
|
||||
@@ -140,6 +140,18 @@ Screen::SetMode(uint16 width, uint16 height, uint32 colorspace,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Screen::SetPreferredMode()
|
||||
{
|
||||
display_mode mode;
|
||||
status_t status = fHWInterface->GetPreferredMode(&mode);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return SetMode(mode, false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Screen::GetMode(display_mode* mode) const
|
||||
{
|
||||
@@ -149,7 +161,7 @@ Screen::GetMode(display_mode* mode) const
|
||||
|
||||
void
|
||||
Screen::GetMode(uint16 &width, uint16 &height, uint32 &colorspace,
|
||||
float &frequency) const
|
||||
float &frequency) const
|
||||
{
|
||||
display_mode mode;
|
||||
fHWInterface->GetMode(&mode);
|
||||
@@ -183,7 +195,7 @@ Screen::ColorSpace() const
|
||||
|
||||
status_t
|
||||
Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace,
|
||||
float frequency, display_mode* mode) const
|
||||
float frequency, display_mode* mode) const
|
||||
{
|
||||
display_mode* modes = NULL;
|
||||
uint32 count;
|
||||
|
||||
@@ -30,10 +30,11 @@ class Screen {
|
||||
|
||||
int32 ID() const { return fID; }
|
||||
|
||||
status_t SetMode(display_mode mode, bool makeDefault);
|
||||
status_t SetMode(const display_mode& mode, bool makeDefault);
|
||||
status_t SetMode(uint16 width, uint16 height,
|
||||
uint32 colorspace, float frequency,
|
||||
bool makeDefault);
|
||||
status_t SetPreferredMode();
|
||||
|
||||
void GetMode(display_mode* mode) const;
|
||||
void GetMode(uint16 &width,
|
||||
|
||||
@@ -133,7 +133,8 @@ VirtualScreen::AddScreen(Screen* screen)
|
||||
}
|
||||
if (status < B_OK) {
|
||||
// TODO: more intelligent standard mode (monitor preference, desktop default, ...)
|
||||
screen->SetMode(800, 600, B_RGB32, 60.f, false);
|
||||
if (screen->SetPreferredMode() != B_OK)
|
||||
screen->SetMode(800, 600, B_RGB32, 60.f, false);
|
||||
}
|
||||
|
||||
// TODO: this works only for single screen configurations
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ServerProtocol.h"
|
||||
#include "SystemPalette.h"
|
||||
|
||||
#include <edid.h>
|
||||
#include <safemode.h>
|
||||
|
||||
#include <Accelerant.h>
|
||||
@@ -349,6 +350,8 @@ AccelerantHWInterface::_SetupDefaultHooks()
|
||||
// optional
|
||||
fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL);
|
||||
fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL);
|
||||
fAccGetPreferredDisplayMode = (get_preferred_display_mode)fAccelerantHook(B_GET_PREFERRED_DISPLAY_MODE, NULL);
|
||||
fAccGetEDIDInfo = (get_edid_info)fAccelerantHook(B_GET_EDID_INFO, NULL);
|
||||
|
||||
// cursor
|
||||
fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL);
|
||||
@@ -716,6 +719,102 @@ AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AccelerantHWInterface::GetPreferredMode(display_mode* mode)
|
||||
{
|
||||
status_t status = B_NOT_SUPPORTED;
|
||||
|
||||
if (fAccGetPreferredDisplayMode != NULL) {
|
||||
status = fAccGetPreferredDisplayMode(mode);
|
||||
if (status == B_OK)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (fAccGetEDIDInfo != NULL) {
|
||||
edid1_info info;
|
||||
uint32 version;
|
||||
status_t status = fAccGetEDIDInfo(&info, sizeof(info), &version);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
if (version != EDID_VERSION_1)
|
||||
return B_NOT_SUPPORTED;
|
||||
|
||||
status = B_ERROR;
|
||||
|
||||
// find preferred mode from EDID info
|
||||
for (uint32 i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
|
||||
if (info.detailed_monitor[i].monitor_desc_type != EDID1_IS_DETAILED_TIMING)
|
||||
continue;
|
||||
|
||||
// TODO: we could also just look for this mode in the most list
|
||||
// TODO: handle sync and flags correctly!
|
||||
const edid1_detailed_timing& timing = info.detailed_monitor[i].data.detailed_timing;
|
||||
mode->timing.pixel_clock = timing.pixel_clock * 10;
|
||||
mode->timing.h_display = timing.h_active;
|
||||
mode->timing.h_sync_start = timing.h_blank;
|
||||
mode->timing.h_sync_end = timing.h_sync_off;
|
||||
mode->timing.h_total = timing.h_sync_width;
|
||||
mode->timing.v_display = timing.v_active;
|
||||
mode->timing.v_sync_start = timing.v_blank;
|
||||
mode->timing.v_sync_end = timing.v_sync_off;
|
||||
mode->timing.v_total = timing.v_sync_width;
|
||||
mode->timing.flags = B_POSITIVE_HSYNC | B_POSITIVE_VSYNC;
|
||||
mode->space = B_RGB32;
|
||||
mode->virtual_width = timing.h_active;
|
||||
mode->virtual_height = timing.v_active;
|
||||
mode->h_display_start = 0;
|
||||
mode->v_display_start = 0;
|
||||
if (fModeCount > 0)
|
||||
mode->flags = fModeList[0].flags;
|
||||
else
|
||||
mode->flags = B_8_BIT_DAC | B_PARALLEL_ACCESS;
|
||||
status = B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AccelerantHWInterface::GetMonitorInfo(BString& name, BString& serial)
|
||||
{
|
||||
if (fAccGetEDIDInfo == NULL)
|
||||
return B_NOT_SUPPORTED;
|
||||
|
||||
edid1_info info;
|
||||
uint32 version;
|
||||
status_t status = fAccGetEDIDInfo(&info, sizeof(info), &version);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
if (version != EDID_VERSION_1)
|
||||
return B_NOT_SUPPORTED;
|
||||
|
||||
uint32 found = 0;
|
||||
|
||||
for (uint32 i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
|
||||
edid1_detailed_monitor *monitor = &info.detailed_monitor[i];
|
||||
|
||||
switch (monitor->monitor_desc_type) {
|
||||
case EDID1_SERIAL_NUMBER:
|
||||
serial.SetTo(monitor->data.serial_number);
|
||||
found++;
|
||||
break;
|
||||
|
||||
case EDID1_MONITOR_NAME:
|
||||
name.SetTo(monitor->data.monitor_name);
|
||||
found++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found > 0 ? B_OK : B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
sem_id
|
||||
AccelerantHWInterface::RetraceSemaphore()
|
||||
{
|
||||
|
||||
@@ -41,6 +41,8 @@ public:
|
||||
virtual status_t ProposeMode(display_mode *candidate,
|
||||
const display_mode *low,
|
||||
const display_mode *high);
|
||||
virtual status_t GetPreferredMode(display_mode* mode);
|
||||
virtual status_t GetMonitorInfo(BString& name, BString& serial);
|
||||
|
||||
virtual sem_id RetraceSemaphore();
|
||||
virtual status_t WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||
@@ -128,6 +130,8 @@ private:
|
||||
// optional accelerant hooks
|
||||
get_timing_constraints fAccGetTimingConstraints;
|
||||
propose_display_mode fAccProposeDisplayMode;
|
||||
get_preferred_display_mode fAccGetPreferredDisplayMode;
|
||||
get_edid_info fAccGetEDIDInfo;
|
||||
fill_rectangle fAccFillRect;
|
||||
invert_rectangle fAccInvertRect;
|
||||
screen_to_screen_blit fAccScreenBlit;
|
||||
|
||||
@@ -89,6 +89,20 @@ HWInterface::GetDriverPath(BString &path)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
HWInterface::GetPreferredMode(display_mode* mode)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
HWInterface::GetMonitorInfo(BString& name, BString& serial)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
||||
@@ -77,6 +77,8 @@ class HWInterface : protected MultiLocker {
|
||||
virtual status_t ProposeMode(display_mode *candidate,
|
||||
const display_mode *low,
|
||||
const display_mode *high) = 0;
|
||||
virtual status_t GetPreferredMode(display_mode* mode);
|
||||
virtual status_t GetMonitorInfo(BString& name, BString& serial);
|
||||
|
||||
virtual sem_id RetraceSemaphore() = 0;
|
||||
virtual status_t WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT) = 0;
|
||||
|
||||
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src servers app drawing ;
|
||||
|
||||
UseLibraryHeaders agg ;
|
||||
UsePrivateHeaders app graphics kernel interface shared ;
|
||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
|
||||
|
||||
Reference in New Issue
Block a user