Integrated Thomas Kurschel's RadeonScreen preferences app.
Major cleanup. All display_mode related stuff is now handled by the new ScreenMode class, the screen preferences now only care about what they control directly. Fixed a lot of bugs. Some changes in behaviour: - the alert window that pops up after a screen change can now be confirmed with the enter key ("Keep" is now the default button), and be denied with the escape key. - when you switch workspaces, the options will only be reverted to the current workspace's options, if you haven't changed them yet - removed control flickering on mode changes (ie. when pressing "Revert" or "Defaults"). - the color pop-up now also shows the number of colors in that mode Next on the list is: make it work under Haiku, improve visual appearance, make it font sensitive, play with min/max refresh rates. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13223 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5b6aece60e
commit
223706b2c3
@ -32,23 +32,28 @@ AlertView::AlertView(BRect frame, char *name)
|
||||
fBitmap = InitIcon();
|
||||
|
||||
BStringView *stringView = new BStringView(BRect(60, 20, 400, 36), NULL,
|
||||
"Do you wish to keep these settings?");
|
||||
"Do you wish to keep these settings?");
|
||||
stringView->SetFont(be_bold_font);
|
||||
stringView->ResizeToPreferred();
|
||||
AddChild(stringView);
|
||||
|
||||
fCountdownView = new BStringView(BRect(60, 37, 400, 50), "countdown", B_EMPTY_STRING);
|
||||
fCountdownView = new BStringView(BRect(60, 37, 400, 50), "countdown",
|
||||
B_EMPTY_STRING);
|
||||
UpdateCountdownView();
|
||||
fCountdownView->ResizeToPreferred();
|
||||
AddChild(fCountdownView);
|
||||
|
||||
BButton *button = new BButton(BRect(215, 59, 400, 190), "KeepButton", "Keep", new BMessage(BUTTON_KEEP_MSG));
|
||||
BButton *button = new BButton(BRect(215, 59, 400, 190), "keep", "Keep",
|
||||
new BMessage(BUTTON_KEEP_MSG));
|
||||
button->ResizeToPreferred();
|
||||
AddChild(button);
|
||||
|
||||
button = new BButton(BRect(130, 59, 400, 199), "RevertButton", "Revert", new BMessage(BUTTON_REVERT_MSG));
|
||||
button = new BButton(BRect(130, 59, 400, 199), "revert", "Revert",
|
||||
new BMessage(BUTTON_REVERT_MSG));
|
||||
button->ResizeToPreferred();
|
||||
AddChild(button);
|
||||
|
||||
SetEventMask(B_KEYBOARD_EVENTS);
|
||||
}
|
||||
|
||||
|
||||
@ -56,6 +61,9 @@ void
|
||||
AlertView::AttachedToWindow()
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
if (BButton* button = dynamic_cast<BButton *>(FindView("keep")))
|
||||
Window()->SetDefaultButton(button);
|
||||
}
|
||||
|
||||
|
||||
@ -84,6 +92,14 @@ AlertView::Pulse()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlertView::KeyDown(const char* bytes, int32 numBytes)
|
||||
{
|
||||
if (numBytes == 1 && bytes[0] == B_ESCAPE)
|
||||
Window()->PostMessage(BUTTON_REVERT_MSG);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlertView::UpdateCountdownView()
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ class AlertView : public BView {
|
||||
virtual void AttachedToWindow();
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void Pulse();
|
||||
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||
|
||||
private:
|
||||
void UpdateCountdownView();
|
||||
|
@ -13,10 +13,12 @@
|
||||
#include "Constants.h"
|
||||
|
||||
#include <Window.h>
|
||||
#include <Screen.h>
|
||||
|
||||
|
||||
AlertWindow::AlertWindow(BRect frame, BMessenger target)
|
||||
: BWindow(frame, "Revert", B_MODAL_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
||||
AlertWindow::AlertWindow(BMessenger target)
|
||||
: BWindow(BRect(100.0, 100.0, 400.0, 193.0), "Revert",
|
||||
B_MODAL_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
||||
B_NOT_RESIZABLE | B_NOT_ZOOMABLE, B_ALL_WORKSPACES),
|
||||
fTarget(target)
|
||||
{
|
||||
@ -25,6 +27,11 @@ AlertWindow::AlertWindow(BRect frame, BMessenger target)
|
||||
|
||||
// the view displays a decrementing counter (until the user must take action)
|
||||
SetPulseRate(1000000); // every second
|
||||
|
||||
// center window on screen
|
||||
BScreen screen(this);
|
||||
MoveTo((screen.Frame().Width() - Frame().Width()) / 2,
|
||||
(screen.Frame().Height() - Frame().Height()) / 2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ class AlertView;
|
||||
|
||||
class AlertWindow : public BWindow {
|
||||
public:
|
||||
AlertWindow(BRect frame, BMessenger target);
|
||||
AlertWindow(BMessenger target);
|
||||
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
|
||||
|
@ -22,6 +22,10 @@ static const uint32 POP_RESOLUTION_MSG = 'pres';
|
||||
static const uint32 POP_COLORS_MSG = 'pclr';
|
||||
static const uint32 POP_REFRESH_MSG = 'prfr';
|
||||
static const uint32 POP_OTHER_REFRESH_MSG = 'porf';
|
||||
static const uint32 POP_COMBINE_DISPLAYS_MSG = 'pcdi';
|
||||
static const uint32 POP_SWAP_DISPLAYS_MSG = 'psdi';
|
||||
static const uint32 POP_USE_LAPTOP_PANEL_MSG = 'pulp';
|
||||
static const uint32 POP_TV_STANDARD_MSG = 'ptvs';
|
||||
static const uint32 UPDATE_DESKTOP_COLOR_MSG = 'udsc';
|
||||
static const uint32 UPDATE_DESKTOP_MSG = 'udsk';
|
||||
static const uint32 SLIDER_MODIFICATION_MSG = 'sldm';
|
||||
|
@ -1,13 +1,17 @@
|
||||
SubDir OBOS_TOP src prefs screen ;
|
||||
|
||||
UsePrivateHeaders [ FDirName graphics radeon ] ;
|
||||
|
||||
Preference Screen :
|
||||
AlertView.cpp
|
||||
AlertWindow.cpp
|
||||
MonitorView.cpp
|
||||
multimon.cpp
|
||||
RefreshSlider.cpp
|
||||
RefreshView.cpp
|
||||
RefreshWindow.cpp
|
||||
ScreenApplication.cpp
|
||||
ScreenMode.cpp
|
||||
ScreenSettings.cpp
|
||||
ScreenWindow.cpp
|
||||
Utility.cpp
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include <Window.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "RefreshSlider.h"
|
||||
#include "Constants.h"
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
RefreshSlider::RefreshSlider(BRect frame)
|
||||
:BSlider(frame, "Screen", "Refresh Rate:",
|
||||
new BMessage(SLIDER_INVOKE_MSG), gMinRefresh * 10, gMaxRefresh * 10),
|
||||
@ -41,26 +42,21 @@ RefreshSlider::DrawFocusMark()
|
||||
void
|
||||
RefreshSlider::KeyDown(const char *bytes, int32 numBytes)
|
||||
{
|
||||
switch (*bytes)
|
||||
{
|
||||
switch (*bytes) {
|
||||
case B_LEFT_ARROW:
|
||||
{
|
||||
SetValue(Value() - 1);
|
||||
|
||||
Invoke();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case B_RIGHT_ARROW:
|
||||
{
|
||||
SetValue(Value() + 1);
|
||||
|
||||
Invoke();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -73,8 +69,7 @@ RefreshSlider::UpdateText() const
|
||||
if (fStatus) {
|
||||
sprintf(fStatus, "%.1f Hz", (float)Value() / 10);
|
||||
return fStatus;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
337
src/prefs/screen/ScreenMode.cpp
Normal file
337
src/prefs/screen/ScreenMode.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
|
||||
|
||||
#include "ScreenMode.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Note, this headers defines a *private* interface to the Radeon accelerant.
|
||||
* It's a solution that works with the current BeOS interface that Haiku
|
||||
* adopted.
|
||||
* However, it's not a nice and clean solution. Don't use this header in any
|
||||
* application if you can avoid it. No other driver is using this, or should
|
||||
* be using this.
|
||||
* It will be replaced as soon as we introduce an updated accelerant interface
|
||||
* which may even happen before R1 hits the streets.
|
||||
*/
|
||||
|
||||
#include "multimon.h" // the usual: DANGER WILL, ROBINSON!
|
||||
|
||||
|
||||
static combine_mode
|
||||
get_combine_mode(display_mode& mode)
|
||||
{
|
||||
if (mode.flags & B_SCROLL == 0)
|
||||
return kCombineDisable;
|
||||
|
||||
if (mode.virtual_width == mode.timing.h_display * 2)
|
||||
return kCombineHorizontally;
|
||||
|
||||
if (mode.virtual_height == mode.timing.v_display * 2)
|
||||
return kCombineVertically;
|
||||
|
||||
return kCombineDisable;
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
get_refresh_rate(display_mode& mode)
|
||||
{
|
||||
// we have to be catious as refresh rate cannot be controlled directly,
|
||||
// so it suffers under rounding errors and hardware restrictions
|
||||
return rint(10 * float(mode.timing.pixel_clock * 1000) /
|
||||
float(mode.timing.h_total * mode.timing.v_total)) / 10.0;
|
||||
}
|
||||
|
||||
|
||||
/** helper to sort modes by resolution */
|
||||
|
||||
static int
|
||||
compare_mode(const void* _mode1, const void* _mode2)
|
||||
{
|
||||
display_mode *mode1 = (display_mode *)_mode1;
|
||||
display_mode *mode2 = (display_mode *)_mode2;
|
||||
combine_mode combine1, combine2;
|
||||
uint16 width1, width2, height1, height2;
|
||||
|
||||
combine1 = get_combine_mode(*mode1);
|
||||
combine2 = get_combine_mode(*mode2);
|
||||
|
||||
width1 = mode1->virtual_width;
|
||||
height1 = mode1->virtual_height;
|
||||
width2 = mode2->virtual_width;
|
||||
height2 = mode2->virtual_height;
|
||||
|
||||
if (combine1 == kCombineHorizontally)
|
||||
width1 /= 2;
|
||||
if (combine1 == kCombineVertically)
|
||||
height1 /= 2;
|
||||
if (combine2 == kCombineHorizontally)
|
||||
width2 /= 2;
|
||||
if (combine2 == kCombineVertically)
|
||||
height2 /= 2;
|
||||
|
||||
if (width1 != width2)
|
||||
return width1 - width2;
|
||||
|
||||
if (height1 != height2)
|
||||
return height1 - height2;
|
||||
|
||||
return (int)(10 * get_refresh_rate(*mode1)
|
||||
- 10 * get_refresh_rate(*mode2));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int32
|
||||
screen_mode::BitsPerPixel() const
|
||||
{
|
||||
switch (space) {
|
||||
case B_RGB32: return 32;
|
||||
case B_RGB24: return 24;
|
||||
case B_RGB16: return 16;
|
||||
case B_RGB15: return 15;
|
||||
case B_CMAP8: return 8;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
screen_mode::operator==(const screen_mode &other) const
|
||||
{
|
||||
return !(*this != other);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
screen_mode::operator!=(const screen_mode &other) const
|
||||
{
|
||||
return width != other.width || height != other.height
|
||||
|| space != other.space || refresh != other.refresh
|
||||
|| combine != other.combine
|
||||
|| swap_displays != other.swap_displays
|
||||
|| use_laptop_panel != other.use_laptop_panel
|
||||
|| tv_standard != other.tv_standard;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
screen_mode::SetTo(display_mode& mode)
|
||||
{
|
||||
width = mode.virtual_width;
|
||||
height = mode.virtual_height;
|
||||
space = (color_space)mode.space;
|
||||
combine = get_combine_mode(mode);
|
||||
refresh = get_refresh_rate(mode);
|
||||
|
||||
if (combine == kCombineHorizontally)
|
||||
width /= 2;
|
||||
else if (combine == kCombineVertically)
|
||||
height /= 2;
|
||||
|
||||
swap_displays = false;
|
||||
use_laptop_panel = false;
|
||||
tv_standard = 0;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ScreenMode::ScreenMode(BWindow* window)
|
||||
:
|
||||
fWindow(window),
|
||||
fUpdatedMode(false)
|
||||
{
|
||||
BScreen screen(window);
|
||||
if (screen.GetModeList(&fModeList, &fModeCount) == B_OK) {
|
||||
// sort modes by resolution and refresh to make
|
||||
// the resolution and refresh menu look nicer
|
||||
qsort(fModeList, fModeCount, sizeof(display_mode), compare_mode);
|
||||
} else {
|
||||
fModeList = NULL;
|
||||
fModeCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ScreenMode::~ScreenMode()
|
||||
{
|
||||
free(fModeList);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ScreenMode::Set(screen_mode& mode)
|
||||
{
|
||||
if (!fUpdatedMode)
|
||||
UpdateOriginalMode();
|
||||
|
||||
BScreen screen(fWindow);
|
||||
SetSwapDisplays(&screen, mode.swap_displays);
|
||||
SetUseLaptopPanel(&screen, mode.use_laptop_panel);
|
||||
SetTVStandard(&screen, mode.tv_standard);
|
||||
|
||||
display_mode displayMode;
|
||||
if (!GetDisplayMode(mode, displayMode))
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
return screen.SetMode(&displayMode, true);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ScreenMode::Get(screen_mode& mode)
|
||||
{
|
||||
display_mode displayMode;
|
||||
BScreen screen(fWindow);
|
||||
if (screen.GetMode(&displayMode) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
mode.SetTo(displayMode);
|
||||
|
||||
if (GetSwapDisplays(&screen, &mode.swap_displays) != B_OK)
|
||||
mode.swap_displays = false;
|
||||
if (GetUseLaptopPanel(&screen, &mode.use_laptop_panel) != B_OK)
|
||||
mode.use_laptop_panel = false;
|
||||
if (GetTVStandard(&screen, &mode.tv_standard) != B_OK)
|
||||
mode.tv_standard = 0;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ScreenMode::Revert()
|
||||
{
|
||||
if (!fUpdatedMode)
|
||||
return B_OK;
|
||||
|
||||
screen_mode current;
|
||||
if (Get(current) && fOriginal == current)
|
||||
return B_OK;
|
||||
|
||||
BScreen screen(fWindow);
|
||||
SetSwapDisplays(&screen, fOriginal.swap_displays);
|
||||
SetUseLaptopPanel(&screen, fOriginal.use_laptop_panel);
|
||||
SetTVStandard(&screen, fOriginal.tv_standard);
|
||||
|
||||
return screen.SetMode(&fOriginalDisplayMode, true);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScreenMode::UpdateOriginalMode()
|
||||
{
|
||||
BScreen screen(fWindow);
|
||||
if (screen.GetMode(&fOriginalDisplayMode) == B_OK) {
|
||||
fUpdatedMode = true;
|
||||
Get(fOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ScreenMode::SupportsColorSpace(screen_mode& mode, color_space space)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ScreenMode::GetRefreshLimits(screen_mode& mode, float& min, float& max)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
screen_mode
|
||||
ScreenMode::ModeAt(int32 index)
|
||||
{
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
else if (index >= (int32)fModeCount)
|
||||
index = fModeCount - 1;
|
||||
|
||||
screen_mode mode;
|
||||
mode.SetTo(fModeList[index]);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ScreenMode::CountModes()
|
||||
{
|
||||
return fModeCount;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ScreenMode::GetDisplayMode(screen_mode& mode, display_mode& displayMode)
|
||||
{
|
||||
uint16 virtualWidth, virtualHeight;
|
||||
int32 bestIndex = -1;
|
||||
float bestDiff = 999;
|
||||
|
||||
virtualWidth = mode.combine == kCombineHorizontally ?
|
||||
mode.width * 2 : mode.width;
|
||||
virtualHeight = mode.combine == kCombineVertically ?
|
||||
mode.height * 2 : mode.height;
|
||||
|
||||
// try to find mode in list provided by driver
|
||||
for (uint32 i = 0; i < fModeCount; i++) {
|
||||
if (fModeList[i].virtual_width != virtualWidth
|
||||
|| fModeList[i].virtual_height != virtualHeight
|
||||
|| (color_space)fModeList[i].space != mode.space)
|
||||
continue;
|
||||
|
||||
float refresh = get_refresh_rate(fModeList[i]);
|
||||
if (refresh == mode.refresh) {
|
||||
// we have luck - we can use this mode directly
|
||||
displayMode = fModeList[i];
|
||||
displayMode.h_display_start = 0;
|
||||
displayMode.v_display_start = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
float diff = fabs(refresh - mode.refresh);
|
||||
if (diff < bestDiff) {
|
||||
bestDiff = diff;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// we didn't find the exact mode, but something very similar?
|
||||
if (bestIndex == -1)
|
||||
return false;
|
||||
|
||||
// now, we are better of using GMT formula, but
|
||||
// as we don't have it, we just tune the pixel
|
||||
// clock of the best mode.
|
||||
|
||||
displayMode = fModeList[bestIndex];
|
||||
displayMode.h_display_start = 0;
|
||||
displayMode.v_display_start = 0;
|
||||
|
||||
// after some fiddling, it looks like this is the formula
|
||||
// used by the original panel (notice that / 10 happens before
|
||||
// multiplying with refresh rate - this leads to different
|
||||
// rounding)
|
||||
displayMode.timing.pixel_clock = ((uint32)displayMode.timing.h_total
|
||||
* displayMode.timing.v_total / 10 * int32(mode.refresh * 10)) / 1000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
68
src/prefs/screen/ScreenMode.h
Normal file
68
src/prefs/screen/ScreenMode.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef SCREEN_MODE_H
|
||||
#define SCREEN_MODE_H
|
||||
|
||||
|
||||
#include <Screen.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
kCombineDisable,
|
||||
kCombineHorizontally,
|
||||
kCombineVertically
|
||||
} combine_mode;
|
||||
|
||||
struct screen_mode {
|
||||
int32 width; // these reflect the corrected width/height,
|
||||
int32 height; // taking the combine mode into account
|
||||
color_space space;
|
||||
float refresh;
|
||||
combine_mode combine;
|
||||
bool swap_displays;
|
||||
bool use_laptop_panel;
|
||||
uint32 tv_standard;
|
||||
|
||||
void SetTo(display_mode& mode);
|
||||
int32 BitsPerPixel() const;
|
||||
|
||||
bool operator==(const screen_mode &otherMode) const;
|
||||
bool operator!=(const screen_mode &otherMode) const;
|
||||
};
|
||||
|
||||
|
||||
class ScreenMode {
|
||||
public:
|
||||
ScreenMode(BWindow* window);
|
||||
~ScreenMode();
|
||||
|
||||
status_t Set(screen_mode& mode);
|
||||
status_t Get(screen_mode& mode);
|
||||
status_t Revert();
|
||||
|
||||
void UpdateOriginalMode();
|
||||
|
||||
bool SupportsColorSpace(screen_mode& mode, color_space space);
|
||||
status_t GetRefreshLimits(screen_mode& mode, float& min, float& max);
|
||||
|
||||
screen_mode ModeAt(int32 index);
|
||||
int32 CountModes();
|
||||
|
||||
private:
|
||||
bool GetDisplayMode(screen_mode& mode, display_mode& displayMode);
|
||||
|
||||
BWindow* fWindow;
|
||||
display_mode* fModeList;
|
||||
uint32 fModeCount;
|
||||
|
||||
bool fUpdatedMode;
|
||||
display_mode fOriginalDisplayMode;
|
||||
screen_mode fOriginal;
|
||||
};
|
||||
|
||||
#endif /* SCREEN_MODE_H */
|
File diff suppressed because it is too large
Load Diff
@ -5,18 +5,22 @@
|
||||
* Authors:
|
||||
* Rafael Romo
|
||||
* Stefano Ceccherini (burton666@libero.it)
|
||||
* Thomas Kurschel
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef SCREEN_WINDOW_H
|
||||
#define SCREEN_WINDOW_H
|
||||
|
||||
|
||||
#include <Screen.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "ScreenMode.h"
|
||||
|
||||
class BBox;
|
||||
class BPopUpMenu;
|
||||
class BMenuField;
|
||||
|
||||
|
||||
class RefreshWindow;
|
||||
class MonitorView;
|
||||
class ScreenSettings;
|
||||
@ -30,48 +34,49 @@ class ScreenWindow : public BWindow {
|
||||
virtual bool QuitRequested();
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
virtual void WorkspaceActivated(int32 ws, bool state);
|
||||
virtual void FrameMoved(BPoint position);
|
||||
virtual void ScreenChanged(BRect frame, color_space mode);
|
||||
|
||||
private:
|
||||
void SetStateByMode();
|
||||
void CheckApplyEnabled();
|
||||
void CheckUpdateDisplayModes();
|
||||
void CheckModesByResolution(const char*);
|
||||
void ApplyMode();
|
||||
|
||||
ScreenSettings *fSettings;
|
||||
void CheckResolutionMenu();
|
||||
void CheckColorMenu();
|
||||
void CheckRefreshMenu();
|
||||
|
||||
MonitorView *fMonitorView;
|
||||
BPopUpMenu *fWorkspaceMenu;
|
||||
BMenuField *fWorkspaceField;
|
||||
BPopUpMenu *fWorkspaceCountMenu;
|
||||
BMenuField *fWorkspaceCountField;
|
||||
BPopUpMenu *fResolutionMenu;
|
||||
BMenuField *fResolutionField;
|
||||
BPopUpMenu *fColorsMenu;
|
||||
BMenuField *fColorsField;
|
||||
BPopUpMenu *fRefreshMenu;
|
||||
BMenuField *fRefreshField;
|
||||
BMenuItem *fCurrentWorkspaceItem;
|
||||
BMenuItem *fAllWorkspacesItem;
|
||||
BButton *fDefaultsButton;
|
||||
BButton *fApplyButton;
|
||||
BButton *fRevertButton;
|
||||
void UpdateActiveMode();
|
||||
void UpdateRefreshControl();
|
||||
void UpdateMonitorView();
|
||||
void UpdateControls();
|
||||
|
||||
BMenuItem *fInitialResolution;
|
||||
BMenuItem *fInitialColors;
|
||||
BMenuItem *fInitialRefresh;
|
||||
BMenuItem *fOtherRefresh;
|
||||
void Apply();
|
||||
|
||||
display_mode fInitialMode;
|
||||
display_mode *fSupportedModes;
|
||||
uint32 fTotalModes;
|
||||
bool CanApply() const;
|
||||
bool CanRevert() const;
|
||||
|
||||
float fMinRefresh;
|
||||
float fMaxRefresh;
|
||||
float fCustomRefresh;
|
||||
float fInitialRefreshN;
|
||||
ScreenSettings* fSettings;
|
||||
|
||||
MonitorView* fMonitorView;
|
||||
BMenuItem* fAllWorkspacesItem;
|
||||
|
||||
BPopUpMenu* fResolutionMenu;
|
||||
BMenuField* fResolutionField;
|
||||
BPopUpMenu* fColorsMenu;
|
||||
BMenuField* fColorsField;
|
||||
BPopUpMenu* fRefreshMenu;
|
||||
BMenuField* fRefreshField;
|
||||
BMenuItem* fOtherRefresh;
|
||||
|
||||
BPopUpMenu* fCombineMenu;
|
||||
BPopUpMenu* fSwapDisplaysMenu;
|
||||
BPopUpMenu* fUseLaptopPanelMenu;
|
||||
BPopUpMenu* fTVStandardMenu;
|
||||
|
||||
BButton* fDefaultsButton;
|
||||
BButton* fApplyButton;
|
||||
BButton* fRevertButton;
|
||||
|
||||
ScreenMode fScreenMode;
|
||||
bool fChangingAllWorkspaces;
|
||||
screen_mode fActive, fSelected, fOriginal;
|
||||
};
|
||||
|
||||
#endif /* SCREEN_WINDOW_H */
|
||||
|
218
src/prefs/screen/multimon.cpp
Normal file
218
src/prefs/screen/multimon.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
Copyright (c) 2002, Thomas Kurschel
|
||||
|
||||
|
||||
Part of Radeon driver
|
||||
|
||||
Multi-Monitor Settings interface
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include "multimon.h"
|
||||
#include "accelerant_ext.h"
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <Screen.h>
|
||||
|
||||
|
||||
// prepare parameters so they recognized as tunneled settings
|
||||
static void PrepareTunnel(
|
||||
display_mode *mode, display_mode *low, display_mode *high )
|
||||
{
|
||||
memset( mode, 0, sizeof( *mode ));
|
||||
|
||||
// mark modes as settings tunnel
|
||||
mode->space = low->space = high->space = 0;
|
||||
low->virtual_width = 0xffff;
|
||||
low->virtual_height = 0xffff;
|
||||
high->virtual_width = 0;
|
||||
high->virtual_height = 0;
|
||||
mode->timing.pixel_clock = 0;
|
||||
low->timing.pixel_clock = 'TKTK';
|
||||
high->timing.pixel_clock = 'KTKT';
|
||||
}
|
||||
|
||||
|
||||
// retrieve value of setting "code"
|
||||
static status_t GetSetting(
|
||||
BScreen *screen, uint16 code, uint32 *setting )
|
||||
{
|
||||
display_mode mode, low, high;
|
||||
status_t result;
|
||||
|
||||
result = TestMultiMonSupport( screen );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
PrepareTunnel( &mode, &low, &high );
|
||||
|
||||
mode.h_display_start = code;
|
||||
mode.v_display_start = 0;
|
||||
|
||||
result = screen->ProposeMode( &mode, &low, &high );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
*setting = mode.timing.flags;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// set setting "code" to "value"
|
||||
static status_t SetSetting(
|
||||
BScreen *screen, uint16 code, uint32 value )
|
||||
{
|
||||
display_mode mode, low, high;
|
||||
status_t result;
|
||||
|
||||
result = TestMultiMonSupport( screen );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
PrepareTunnel( &mode, &low, &high );
|
||||
|
||||
mode.h_display_start = code;
|
||||
mode.v_display_start = 1;
|
||||
mode.timing.flags = value;
|
||||
|
||||
return screen->ProposeMode( &mode, &low, &high );
|
||||
}
|
||||
|
||||
|
||||
// retrieve n-th supported value of setting "code"
|
||||
static status_t GetNthSupportedSetting(
|
||||
BScreen *screen, uint16 code, int32 idx, uint32 *setting )
|
||||
{
|
||||
display_mode mode, low, high;
|
||||
status_t result;
|
||||
|
||||
result = TestMultiMonSupport( screen );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
PrepareTunnel( &mode, &low, &high );
|
||||
|
||||
mode.h_display_start = code;
|
||||
mode.v_display_start = 2;
|
||||
mode.timing.flags = idx;
|
||||
|
||||
result = screen->ProposeMode( &mode, &low, &high );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
*setting = mode.timing.flags;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// get current Swap Displays settings
|
||||
status_t GetSwapDisplays(
|
||||
BScreen *screen, bool *swap )
|
||||
{
|
||||
status_t result;
|
||||
uint32 tmp;
|
||||
|
||||
result = GetSetting( screen, ms_swap, &tmp );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
*swap = tmp != 0;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// set "Swap Displays"
|
||||
status_t SetSwapDisplays(
|
||||
BScreen *screen, bool swap )
|
||||
{
|
||||
return SetSetting( screen, ms_swap, swap );
|
||||
}
|
||||
|
||||
|
||||
// get current "Use Laptop Panel" settings
|
||||
status_t GetUseLaptopPanel(
|
||||
BScreen *screen, bool *use )
|
||||
{
|
||||
status_t result;
|
||||
uint32 tmp;
|
||||
|
||||
result = GetSetting( screen, ms_use_laptop_panel, &tmp );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
*use = tmp != 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// set "Use Laptop Panel"
|
||||
status_t SetUseLaptopPanel(
|
||||
BScreen *screen, bool use )
|
||||
{
|
||||
return SetSetting( screen, ms_use_laptop_panel, use );
|
||||
}
|
||||
|
||||
|
||||
// get n-th supported TV standard
|
||||
status_t GetNthSupportedTVStandard( BScreen *screen, int idx, uint32 *standard )
|
||||
{
|
||||
return GetNthSupportedSetting(
|
||||
screen, ms_tv_standard, (int32)idx, standard );
|
||||
}
|
||||
|
||||
|
||||
// get current TV Standard settings
|
||||
status_t GetTVStandard( BScreen *screen, uint32 *standard )
|
||||
{
|
||||
return GetSetting( screen, ms_tv_standard, standard );
|
||||
}
|
||||
|
||||
|
||||
// set TV Standard
|
||||
status_t SetTVStandard( BScreen *screen, uint32 standard )
|
||||
{
|
||||
return SetSetting( screen, ms_tv_standard, standard );
|
||||
}
|
||||
|
||||
|
||||
// Verify existence of Multi-Monitor Settings Tunnel
|
||||
status_t TestMultiMonSupport( BScreen *screen )
|
||||
{
|
||||
display_mode *mode_list;
|
||||
display_mode low, high;
|
||||
uint32 count;
|
||||
status_t result;
|
||||
|
||||
// take any valid mode
|
||||
result = screen->GetModeList( &mode_list, &count );
|
||||
if( result != B_OK )
|
||||
return result;
|
||||
|
||||
if( count < 1 )
|
||||
return B_ERROR;
|
||||
|
||||
// set request bits
|
||||
mode_list[0].timing.flags |= RADEON_MODE_MULTIMON_REQUEST;
|
||||
mode_list[0].timing.flags &= ~RADEON_MODE_MULTIMON_REPLY;
|
||||
low = high = mode_list[0];
|
||||
|
||||
result = screen->ProposeMode( &mode_list[0], &low, &high );
|
||||
if( result != B_OK )
|
||||
goto err;
|
||||
|
||||
// check reply bits
|
||||
if( (mode_list[0].timing.flags & RADEON_MODE_MULTIMON_REQUEST) == 0 &&
|
||||
(mode_list[0].timing.flags & RADEON_MODE_MULTIMON_REPLY) != 0 )
|
||||
result = B_OK;
|
||||
else
|
||||
result = B_ERROR;
|
||||
|
||||
err:
|
||||
delete mode_list;
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue
Block a user