#include <windows.h>
#include "display.h"
+#include "display_private.h"
using namespace std;
namespace Msp {
namespace Graphics {
-Display::Display(const string &)
+Display::Display(const string &):
+ primary_monitor(0),
+ priv(new Private)
{
+ static ErrorDialog err_dlg(0);
+
for(unsigned i=0;; ++i)
{
- DEVMODE info;
- if(!EnumDisplaySettings(0, i, &info))
+ DISPLAY_DEVICE adapter_dev;
+ adapter_dev.cb = sizeof(adapter_dev);
+ if(!EnumDisplayDevices(0, i, &adapter_dev, 0))
break;
- VideoMode mode(info.dmPelsWidth, info.dmPelsHeight);
- mode.rate = info.dmDisplayFrequency;
- modes.push_back(mode);
- }
-
- DEVMODE info;
- if(EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &info))
- {
- orig_mode = VideoMode(info.dmPelsWidth, info.dmPelsHeight);
- orig_mode.rate = info.dmDisplayFrequency;
+ if(adapter_dev.StateFlags&DISPLAY_DEVICE_MIRRORING_DRIVER)
+ continue;
+
+ monitors.push_back(Monitor());
+ Monitor &monitor = monitors.back();
+ monitor.index = monitors.size()-1;
+ priv->monitors.push_back(adapter_dev.DeviceName);
+
+ if(adapter_dev.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE)
+ primary_monitor = &monitor;
+
+ DEVMODE current;
+ bool have_current = EnumDisplaySettings(adapter_dev.DeviceName, ENUM_CURRENT_SETTINGS, ¤t);
+
+ for(unsigned j=0;; ++j)
+ {
+ DEVMODE info;
+ if(!EnumDisplaySettings(adapter_dev.DeviceName, j, &info))
+ break;
+
+ VideoMode mode(info.dmPelsWidth, info.dmPelsHeight);
+ mode.index = modes.size();
+ mode.monitor = &monitor;
+ mode.rate = info.dmDisplayFrequency;
+ if(find_mode(mode))
+ continue;
+
+ modes.push_back(mode);
+ monitor.video_modes.push_back(&modes.back());
+
+ if(have_current && info.dmPelsWidth==current.dmPelsWidth && info.dmPelsHeight==current.dmPelsHeight && info.dmDisplayFrequency==current.dmDisplayFrequency)
+ monitor.desktop_mode = &modes.back();
+ }
}
}
{
}
-void Display::set_mode(const VideoMode &mode)
+void Display::set_mode(const VideoMode &requested_mode, bool)
{
+ const VideoMode *mode = find_mode(requested_mode);
+ if(!mode)
+ throw unsupported_video_mode(requested_mode);
+
DEVMODE info;
+ info.dmDeviceName[0] = 0;
+ info.dmSpecVersion = DM_SPECVERSION;
+ info.dmDriverVersion = 0;
info.dmSize = sizeof(DEVMODE);
+ info.dmDriverExtra = 0;
info.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT;
- info.dmPelsWidth = mode.width;
- info.dmPelsHeight = mode.height;
- if(mode.rate)
+ info.dmPelsWidth = mode->width;
+ info.dmPelsHeight = mode->height;
+ if(requested_mode.rate)
{
info.dmFields |= DM_DISPLAYFREQUENCY;
- info.dmDisplayFrequency = mode.rate;
+ info.dmDisplayFrequency = mode->rate;
}
- LONG ret = ChangeDisplaySettings(&info, CDS_FULLSCREEN);
+ LONG ret = ChangeDisplaySettingsEx(priv->monitors[mode->monitor->index].c_str(), &info, NULL, CDS_FULLSCREEN, NULL);
if(ret!=DISP_CHANGE_SUCCESSFUL)
- throw unsupported_video_mode(mode);
+ throw unsupported_video_mode(requested_mode);
+
+ for(list<Monitor>::iterator i=monitors.begin(); i!=monitors.end(); ++i)
+ if(&*i==mode->monitor)
+ i->current_mode = mode;
}
bool Display::process_events()