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