2 #include "display_private.h"
11 Display::Display(const string &):
14 static ErrorDialog err_dlg(nullptr);
16 int primary_index = -1;
17 vector<unsigned> mode_monitor_indices;
18 vector<int> desktop_mode_indices;
19 for(unsigned i=0;; ++i)
21 DISPLAY_DEVICE adapter_dev;
22 adapter_dev.cb = sizeof(adapter_dev);
23 if(!EnumDisplayDevices(nullptr, i, &adapter_dev, 0))
26 if(adapter_dev.StateFlags&DISPLAY_DEVICE_MIRRORING_DRIVER)
29 monitors.push_back(Monitor());
30 Monitor &monitor = monitors.back();
31 monitor.index = monitors.size()-1;
32 priv->monitors.push_back(adapter_dev.DeviceName);
34 DISPLAY_DEVICE monitor_dev;
35 monitor_dev.cb = sizeof(monitor_dev);
36 if(EnumDisplayDevices(adapter_dev.DeviceName, 0, &monitor_dev, 0))
37 monitor.name = monitor_dev.DeviceString;
39 if(adapter_dev.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE)
43 bool have_current = EnumDisplaySettings(adapter_dev.DeviceName, ENUM_CURRENT_SETTINGS, ¤t);
45 unsigned first_mode = modes.size();
46 int desktop_mode_index = -1;
47 for(unsigned j=0;; ++j)
50 if(!EnumDisplaySettings(adapter_dev.DeviceName, j, &info))
53 if(any_of(modes.begin()+first_mode, modes.end(), [&info](const VideoMode &m){
54 return (m.width==info.dmPelsWidth && m.height==info.dmPelsHeight && m.rate==info.dmDisplayFrequency);
58 VideoMode mode(info.dmPelsWidth, info.dmPelsHeight);
59 mode.index = modes.size();
60 mode.rate = info.dmDisplayFrequency;
62 modes.push_back(mode);
63 mode_monitor_indices.push_back(monitor.index);
65 if(have_current && info.dmPelsWidth==current.dmPelsWidth && info.dmPelsHeight==current.dmPelsHeight && info.dmDisplayFrequency==current.dmDisplayFrequency)
66 desktop_mode_index = mode.index;
68 desktop_mode_indices.push_back(desktop_mode_index);
71 for(unsigned i=0; i<monitors.size(); ++i)
73 int j = desktop_mode_indices[i];
75 monitors[i].desktop_settings.mode = &modes[j];
76 monitors[i].current_settings = monitors[i].desktop_settings;
79 for(unsigned i=0; i<modes.size(); ++i)
81 Monitor &monitor = monitors[mode_monitor_indices[i]];
82 modes[i].monitor = &monitor;
83 monitor.video_modes.push_back(&modes[i]);
87 primary_monitor = &monitors[primary_index];
95 void Display::set_mode(const VideoMode &requested_mode, bool)
97 const VideoMode *mode = find_mode(requested_mode);
99 throw unsupported_video_mode(requested_mode);
102 info.dmDeviceName[0] = 0;
103 info.dmSpecVersion = DM_SPECVERSION;
104 info.dmDriverVersion = 0;
105 info.dmSize = sizeof(DEVMODE);
106 info.dmDriverExtra = 0;
107 info.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT;
108 info.dmPelsWidth = mode->width;
109 info.dmPelsHeight = mode->height;
110 if(requested_mode.rate)
112 info.dmFields |= DM_DISPLAYFREQUENCY;
113 info.dmDisplayFrequency = mode->rate;
116 LONG ret = ChangeDisplaySettingsEx(priv->monitors[mode->monitor->index].c_str(), &info, NULL, CDS_FULLSCREEN, NULL);
117 if(ret!=DISP_CHANGE_SUCCESSFUL)
118 throw unsupported_video_mode(requested_mode);
120 for(Monitor &m: monitors)
121 if(&m==mode->monitor)
122 m.current_settings.mode = mode;
125 bool Display::process_events()
128 if(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
130 TranslateMessage(&msg);
131 DispatchMessage(&msg);
138 void Display::check_error()
143 } // namespace Graphics