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