X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fdisplay.cpp;h=8c3813d16cd8d19321fddcd6609a9dfc5748da3c;hb=6222d13e2790bdaa1013444f1221841397834cdd;hp=42b0e8bb773404c892b01896d8ca13a589fa6f73;hpb=1aca77b93853ee127ac3bbf6886f7f04920542ef;p=libs%2Fgui.git diff --git a/source/graphics/display.cpp b/source/graphics/display.cpp index 42b0e8b..8c3813d 100644 --- a/source/graphics/display.cpp +++ b/source/graphics/display.cpp @@ -1,5 +1,6 @@ -#include #include "display.h" +#include +#include #include "display_private.h" #include "window.h" @@ -8,26 +9,97 @@ using namespace std; namespace Msp { namespace Graphics { -unsupported_video_mode::unsupported_video_mode(const VideoMode &mode): - runtime_error(format("%dx%d", mode.width, mode.height)) -{ } - - void Display::add_window(Window &wnd) { priv->windows[wnd.get_private().window] = &wnd; + wnd.signal_got_focus.connect(sigc::bind(sigc::mem_fun(this, &Display::window_got_focus), sigc::ref(wnd))); + wnd.signal_lost_focus.connect(sigc::mem_fun(this, &Display::window_lost_focus)); } void Display::remove_window(Window &wnd) { priv->windows.erase(wnd.get_private().window); + if(&wnd==focus_window) + focus_window = nullptr; +} + +const VideoMode &Display::get_desktop_mode() const +{ + if(!primary_monitor || !primary_monitor->desktop_settings.mode) + throw logic_error("no desktop mode"); + return *primary_monitor->desktop_settings.mode; +} + +void Display::restore_mode() +{ + for(const Monitor &m: monitors) + if(m.desktop_settings.mode) + set_mode(*m.desktop_settings.mode, false); +} + +const VideoMode *Display::find_mode(const VideoMode &mode, float rate_tolerance) const +{ + const VideoMode *closest = nullptr; + float rate_diff = 0.0f; + + float target_rate = mode.rate; + if(!target_rate && mode.monitor) + if(const VideoMode *current_mode = mode.monitor->current_settings.mode) + target_rate = current_mode->rate; + + for(const VideoMode &m: modes) + { + if(mode.monitor && m.monitor!=mode.monitor) + continue; + // Only check rate tolerance against an explicitly requested rate + if(mode.rate && (m.ratemode.rate+rate_tolerance)) + continue; + if(m.width!=mode.width || m.height!=mode.height) + continue; + + float ref_rate = target_rate; + if(!ref_rate) + if(const VideoMode *current_mode = m.monitor->current_settings.mode) + ref_rate = current_mode->rate; + + float d = abs(m.rate-ref_rate); + if(!closest || d