]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/display.cpp
Refactor storage of monitor settings
[libs/gui.git] / source / graphics / display.cpp
index de5a06952a58e8efa8f3e956ee0f949126775426..ebf14ea489c9d1befa6c8efd192a12806d5833d6 100644 (file)
@@ -1,3 +1,5 @@
+#include <cmath>
+#include <sigc++/bind.h>
 #include "display.h"
 #include "display_private.h"
 #include "window.h"
@@ -10,40 +12,58 @@ namespace Graphics {
 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 = 0;
 }
 
 const VideoMode &Display::get_desktop_mode() const
 {
-       if(!primary_monitor || !primary_monitor->desktop_mode)
+       if(!primary_monitor || !primary_monitor->desktop_settings.mode)
                throw logic_error("no desktop mode");
-       return *primary_monitor->desktop_mode;
+       return *primary_monitor->desktop_settings.mode;
 }
 
 void Display::restore_mode()
 {
        for(list<Monitor>::const_iterator i=monitors.begin(); i!=monitors.end(); ++i)
-               if(i->desktop_mode)
-                       set_mode(*i->desktop_mode, false);
+               if(i->desktop_settings.mode)
+                       set_mode(*i->desktop_settings.mode, false);
 }
 
-const VideoMode *Display::find_mode(const VideoMode &mode) const
+const VideoMode *Display::find_mode(const VideoMode &mode, float rate_tolerance) const
 {
+       const VideoMode *closest = 0;
+       float rate_diff = mode.rate;
        for(list<VideoMode>::const_iterator i=modes.begin(); i!=modes.end(); ++i)
        {
                if(mode.monitor && i->monitor!=mode.monitor)
                        continue;
-               if(mode.rate && i->rate!=mode.rate)
+               if(mode.rate && (i->rate<mode.rate-rate_tolerance || i->rate>mode.rate+rate_tolerance))
                        continue;
-               if(i->width==mode.width && i->height==mode.height)
+               if(i->width!=mode.width || i->height!=mode.height)
+                       continue;
+
+               if(mode.rate)
+               {
+                       float d = abs(i->rate-mode.rate);
+                       if(d<rate_diff)
+                       {
+                               closest = &*i;
+                               rate_diff = d;
+                       }
+               }
+               else
                        return &*i;
        }
 
-       return 0;
+       return closest;
 }
 
 const VideoMode *Display::find_mode(unsigned width, unsigned height) const
@@ -51,11 +71,28 @@ const VideoMode *Display::find_mode(unsigned width, unsigned height) const
        return find_mode(VideoMode(width, height));
 }
 
+void Display::window_got_focus(Window &w)
+{
+       focus_window = &w;
+}
+
+void Display::window_lost_focus()
+{
+       focus_window = 0;
+}
+
 void Display::tick()
 {
        check_error();
 
+       Window *old_focus = focus_window;
+
        while(process_events()) ;
+
+       if(old_focus && !focus_window)
+               signal_lost_focus.emit();
+       else if(!old_focus && focus_window)
+               signal_got_focus.emit();
 }
 
 } // namespace Graphics