]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/windows/display.cpp
bea18a64d0f8b05d372e8e900f2e89c4f7d1608f
[libs/gui.git] / source / graphics / windows / display.cpp
1 #include "display.h"
2 #include "display_private.h"
3 #include <windows.h>
4
5 using namespace std;
6
7 namespace Msp {
8 namespace Graphics {
9
10 Display::Display(const string &):
11         priv(new Private)
12 {
13         static ErrorDialog err_dlg(nullptr);
14
15         for(unsigned i=0;; ++i)
16         {
17                 DISPLAY_DEVICE adapter_dev;
18                 adapter_dev.cb = sizeof(adapter_dev);
19                 if(!EnumDisplayDevices(nullptr, i, &adapter_dev, 0))
20                         break;
21
22                 if(adapter_dev.StateFlags&DISPLAY_DEVICE_MIRRORING_DRIVER)
23                         continue;
24
25                 monitors.push_back(Monitor());
26                 Monitor &monitor = monitors.back();
27                 monitor.index = monitors.size()-1;
28                 monitor.name = adapter_dev.DeviceString;
29                 priv->monitors.push_back(adapter_dev.DeviceName);
30
31                 if(adapter_dev.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE)
32                         primary_monitor = &monitor;
33
34                 DEVMODE current;
35                 bool have_current = EnumDisplaySettings(adapter_dev.DeviceName, ENUM_CURRENT_SETTINGS, &current);
36
37                 for(unsigned j=0;; ++j)
38                 {
39                         DEVMODE info;
40                         if(!EnumDisplaySettings(adapter_dev.DeviceName, j, &info))
41                                 break;
42
43                         VideoMode mode(info.dmPelsWidth, info.dmPelsHeight);
44                         mode.index = modes.size();
45                         mode.monitor = &monitor;
46                         mode.rate = info.dmDisplayFrequency;
47                         if(find_mode(mode))
48                                 continue;
49
50                         modes.push_back(mode);
51                         monitor.video_modes.push_back(&modes.back());
52
53                         if(have_current && info.dmPelsWidth==current.dmPelsWidth && info.dmPelsHeight==current.dmPelsHeight && info.dmDisplayFrequency==current.dmDisplayFrequency)
54                                 monitor.desktop_settings.mode = &modes.back();
55                 }
56
57                 monitor.current_settings = monitor.desktop_settings;
58         }
59 }
60
61 Display::~Display()
62 {
63         delete priv;
64 }
65
66 void Display::set_mode(const VideoMode &requested_mode, bool)
67 {
68         const VideoMode *mode = find_mode(requested_mode);
69         if(!mode)
70                 throw unsupported_video_mode(requested_mode);
71
72         DEVMODE info;
73         info.dmDeviceName[0] = 0;
74         info.dmSpecVersion = DM_SPECVERSION;
75         info.dmDriverVersion = 0;
76         info.dmSize = sizeof(DEVMODE);
77         info.dmDriverExtra = 0;
78         info.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT;
79         info.dmPelsWidth = mode->width;
80         info.dmPelsHeight = mode->height;
81         if(requested_mode.rate)
82         {
83                 info.dmFields |= DM_DISPLAYFREQUENCY;
84                 info.dmDisplayFrequency = mode->rate;
85         }
86
87         LONG ret = ChangeDisplaySettingsEx(priv->monitors[mode->monitor->index].c_str(), &info, NULL, CDS_FULLSCREEN, NULL);
88         if(ret!=DISP_CHANGE_SUCCESSFUL)
89                 throw unsupported_video_mode(requested_mode);
90
91         for(Monitor &m: monitors)
92                 if(&m==mode->monitor)
93                         m.current_settings.mode = mode;
94 }
95
96 bool Display::process_events()
97 {
98         MSG msg;
99         if(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
100         {
101                 TranslateMessage(&msg);
102                 DispatchMessage(&msg);
103                 return true;
104         }
105         else
106                 return false;
107 }
108
109 void Display::check_error()
110 {
111 }
112
113 } // namespace Msp
114 } // namespace Graphics