X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fwindows%2Fdisplay.cpp;h=2364f6d9c05422a3413550fceef94ae5a63389f7;hb=207eec91afc6b538753ddc44905ac9ddbc907ac0;hp=5cc04c1674f6707ac3c3f3fa50a53220943572ad;hpb=1aca77b93853ee127ac3bbf6886f7f04920542ef;p=libs%2Fgui.git diff --git a/source/graphics/windows/display.cpp b/source/graphics/windows/display.cpp index 5cc04c1..2364f6d 100644 --- a/source/graphics/windows/display.cpp +++ b/source/graphics/windows/display.cpp @@ -1,52 +1,96 @@ #include #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), + focus_window(0) { + 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; + monitor.name = adapter_dev.DeviceString; + 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_settings.mode = &modes.back(); + } } } Display::~Display() { + delete priv; } -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::iterator i=monitors.begin(); i!=monitors.end(); ++i) + if(&*i==mode->monitor) + i->current_settings.mode = mode; } bool Display::process_events() @@ -54,6 +98,7 @@ bool Display::process_events() MSG msg; if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); DispatchMessage(&msg); return true; }