]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/display.cpp
Use nullptr in place of 0 or NULL
[libs/gui.git] / source / graphics / display.cpp
1 #include "display.h"
2 #include <cmath>
3 #include <sigc++/bind.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 = nullptr;
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(const Monitor &m: monitors)
36                 if(m.desktop_settings.mode)
37                         set_mode(*m.desktop_settings.mode, false);
38 }
39
40 const VideoMode *Display::find_mode(const VideoMode &mode, float rate_tolerance) const
41 {
42         const VideoMode *closest = nullptr;
43         float rate_diff = 0.0f;
44
45         float target_rate = mode.rate;
46         if(!target_rate && mode.monitor)
47                 if(const VideoMode *current_mode = mode.monitor->current_settings.mode)
48                         target_rate = current_mode->rate;
49
50         for(const VideoMode &m: modes)
51         {
52                 if(mode.monitor && m.monitor!=mode.monitor)
53                         continue;
54                 // Only check rate tolerance against an explicitly requested rate
55                 if(mode.rate && (m.rate<mode.rate-rate_tolerance || m.rate>mode.rate+rate_tolerance))
56                         continue;
57                 if(m.width!=mode.width || m.height!=mode.height)
58                         continue;
59
60                 float ref_rate = target_rate;
61                 if(!ref_rate)
62                         if(const VideoMode *current_mode = m.monitor->current_settings.mode)
63                                 ref_rate = current_mode->rate;
64
65                 float d = abs(m.rate-ref_rate);
66                 if(!closest || d<rate_diff)
67                 {
68                         closest = &m;
69                         rate_diff = d;
70                 }
71         }
72
73         return closest;
74 }
75
76 const VideoMode *Display::find_mode(unsigned width, unsigned height) const
77 {
78         return find_mode(VideoMode(width, height));
79 }
80
81 void Display::window_got_focus(Window &w)
82 {
83         focus_window = &w;
84 }
85
86 void Display::window_lost_focus()
87 {
88         focus_window = nullptr;
89 }
90
91 void Display::tick()
92 {
93         check_error();
94
95         Window *old_focus = focus_window;
96
97         while(process_events()) ;
98
99         if(old_focus && !focus_window)
100                 signal_lost_focus.emit();
101         else if(!old_focus && focus_window)
102                 signal_got_focus.emit();
103 }
104
105 } // namespace Graphics
106 } // namespace Msp