]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/display.cpp
Refactor storage of monitor settings
[libs/gui.git] / source / graphics / display.cpp
1 #include <cmath>
2 #include <sigc++/bind.h>
3 #include "display.h"
4 #include "display_private.h"
5 #include "window.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace Graphics {
11
12 void Display::add_window(Window &wnd)
13 {
14         priv->windows[wnd.get_private().window] = &wnd;
15         wnd.signal_got_focus.connect(sigc::bind(sigc::mem_fun(this, &Display::window_got_focus), sigc::ref(wnd)));
16         wnd.signal_lost_focus.connect(sigc::mem_fun(this, &Display::window_lost_focus));
17 }
18
19 void Display::remove_window(Window &wnd)
20 {
21         priv->windows.erase(wnd.get_private().window);
22         if(&wnd==focus_window)
23                 focus_window = 0;
24 }
25
26 const VideoMode &Display::get_desktop_mode() const
27 {
28         if(!primary_monitor || !primary_monitor->desktop_settings.mode)
29                 throw logic_error("no desktop mode");
30         return *primary_monitor->desktop_settings.mode;
31 }
32
33 void Display::restore_mode()
34 {
35         for(list<Monitor>::const_iterator i=monitors.begin(); i!=monitors.end(); ++i)
36                 if(i->desktop_settings.mode)
37                         set_mode(*i->desktop_settings.mode, false);
38 }
39
40 const VideoMode *Display::find_mode(const VideoMode &mode, float rate_tolerance) const
41 {
42         const VideoMode *closest = 0;
43         float rate_diff = mode.rate;
44         for(list<VideoMode>::const_iterator i=modes.begin(); i!=modes.end(); ++i)
45         {
46                 if(mode.monitor && i->monitor!=mode.monitor)
47                         continue;
48                 if(mode.rate && (i->rate<mode.rate-rate_tolerance || i->rate>mode.rate+rate_tolerance))
49                         continue;
50                 if(i->width!=mode.width || i->height!=mode.height)
51                         continue;
52
53                 if(mode.rate)
54                 {
55                         float d = abs(i->rate-mode.rate);
56                         if(d<rate_diff)
57                         {
58                                 closest = &*i;
59                                 rate_diff = d;
60                         }
61                 }
62                 else
63                         return &*i;
64         }
65
66         return closest;
67 }
68
69 const VideoMode *Display::find_mode(unsigned width, unsigned height) const
70 {
71         return find_mode(VideoMode(width, height));
72 }
73
74 void Display::window_got_focus(Window &w)
75 {
76         focus_window = &w;
77 }
78
79 void Display::window_lost_focus()
80 {
81         focus_window = 0;
82 }
83
84 void Display::tick()
85 {
86         check_error();
87
88         Window *old_focus = focus_window;
89
90         while(process_events()) ;
91
92         if(old_focus && !focus_window)
93                 signal_lost_focus.emit();
94         else if(!old_focus && focus_window)
95                 signal_got_focus.emit();
96 }
97
98 } // namespace Graphics
99 } // namespace Msp