#ifndef MSP_GRAPHICS_DISPLAY_PLATFORM_H_
#define MSP_GRAPHICS_DISPLAY_PLATFORM_H_
+#include <deque>
#include <android/input.h>
#include <android/native_window.h>
#include <sigc++/trackable.h>
struct PlatformDisplayPrivate: public sigc::trackable
{
AInputQueue *input_queue = nullptr;
- std::list<Window::Event> events;
+ std::deque<Window::Event> events;
Mutex event_mutex;
WindowHandle native_window = nullptr;
Mutex window_mutex;
#ifndef MSP_GRAPHICS_DISPLAY_H_
#define MSP_GRAPHICS_DISPLAY_H_
-#include <list>
#include <stdexcept>
#include <string>
+#include <vector>
#include <sigc++/signal.h>
#include "errordialog.h"
#include "monitor.h"
sigc::signal<void> signal_lost_focus;
private:
- std::list<Monitor> monitors;
+ std::vector<Monitor> monitors;
Monitor *primary_monitor = nullptr;
- std::list<VideoMode> modes;
+ std::vector<VideoMode> modes;
Private *priv = nullptr;
ErrorDialog *err_dialog = nullptr;
Window *focus_window = nullptr;
void add_window(Window &);
void remove_window(Window &);
- const std::list<Monitor> &get_monitors() const { return monitors; }
- const std::list<VideoMode> &get_modes() const { return modes; }
+ const std::vector<Monitor> &get_monitors() const { return monitors; }
+ const std::vector<VideoMode> &get_modes() const { return modes; }
const VideoMode &get_desktop_mode() const;
void set_mode(const VideoMode &, bool = false);
void restore_mode();
#include "imageloader.h"
+#include <msp/core/algorithm.h>
#include <msp/core/refptr.h>
#include <msp/io/file.h>
#include <msp/strings/format.h>
if(registry.changed)
{
registry.changed = false;
- registry.loaders.sort(signature_size_compare);
+ sort(registry.loaders, signature_size_compare);
}
if(registry.loaders.empty())
struct Registry
{
- std::list<RegisterBase *> loaders;
+ std::vector<RegisterBase *> loaders;
bool changed = false;
~Registry();
#ifndef MSP_GRAPHICS_MONITOR_H_
#define MSP_GRAPHICS_MONITOR_H_
-#include <list>
#include <string>
+#include <vector>
#include "videomode.h"
namespace Msp {
unsigned index = 0;
std::string name;
- std::list<const VideoMode *> video_modes;
+ std::vector<const VideoMode *> video_modes;
Settings desktop_settings;
Settings current_settings;
const Monitor *next_left = nullptr;
#include "display.h"
#include "display_private.h"
+#include <algorithm>
#include <windows.h>
using namespace std;
{
static ErrorDialog err_dlg(nullptr);
+ int primary_index = -1;
+ vector<unsigned> mode_monitor_indices;
+ vector<int> desktop_mode_indices;
for(unsigned i=0;; ++i)
{
DISPLAY_DEVICE adapter_dev;
priv->monitors.push_back(adapter_dev.DeviceName);
if(adapter_dev.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE)
- primary_monitor = &monitor;
+ primary_index = i;
DEVMODE current;
bool have_current = EnumDisplaySettings(adapter_dev.DeviceName, ENUM_CURRENT_SETTINGS, ¤t);
+ unsigned first_mode = modes.size();
+ int desktop_mode_index = -1;
for(unsigned j=0;; ++j)
{
DEVMODE info;
if(!EnumDisplaySettings(adapter_dev.DeviceName, j, &info))
break;
+ if(any_of(modes.begin()+first_mode, modes.end(), [&info](const VideoMode &m){
+ return (m.width==info.dmPelsWidth && m.height==info.dmPelsHeight && m.rate==info.dmDisplayFrequency);
+ }))
+ continue;
+
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());
+ mode_monitor_indices.push_back(monitor.index);
if(have_current && info.dmPelsWidth==current.dmPelsWidth && info.dmPelsHeight==current.dmPelsHeight && info.dmDisplayFrequency==current.dmDisplayFrequency)
- monitor.desktop_settings.mode = &modes.back();
+ desktop_mode_index = mode.index;
}
+ desktop_mode_indices.push_back(desktop_mode_index);
+ }
- monitor.current_settings = monitor.desktop_settings;
+ for(unsigned i=0; i<monitors.size(); ++i)
+ {
+ int j = desktop_mode_indices[i];
+ if(j>=0)
+ monitors[i].desktop_settings.mode = &modes[j];
+ monitors[i].current_settings = monitors[i].desktop_settings;
}
+
+ for(unsigned i=0; i<modes.size(); ++i)
+ {
+ Monitor &monitor = monitors[mode_monitor_indices[i]];
+ modes[i].monitor = &monitor;
+ monitor.video_modes.push_back(&modes[i]);
+ }
+
+ if(primary_index>=0)
+ primary_monitor = &monitors[primary_index];
}
Display::~Display()
#ifdef WITH_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
+#include <msp/core/algorithm.h>
#include <msp/io/print.h>
#include <msp/strings/format.h>
#include <msp/strings/lexicalcast.h>
for(int i=0; i<res->nmode; ++i)
modes_by_id[res->modes[i].id] = &res->modes[i];
+ int primary_index = -1;
+ vector<unsigned> mode_monitor_indices;
+ vector<int> desktop_mode_indices;
for(int i=0; i<res->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(priv->display, res, res->outputs[i]);
}
if(res->outputs[i]==primary)
- primary_monitor = &monitor;
+ primary_index = monitor.index;
+ unsigned first_mode = modes.size();
+ int desktop_mode_index = -1;
for(int j=0; j<output->nmode; ++j)
{
auto k = modes_by_id.find(output->modes[j]);
continue;
XRRModeInfo *info = k->second;
+ float rate = static_cast<float>(info->dotClock)/(info->hTotal*info->vTotal);
+
+ if(any_of(modes.begin()+first_mode, modes.end(), [&info, rate](const VideoMode &m){
+ return (m.width==info->width && m.height==info->height && abs(m.rate-rate)<0.01f);
+ }))
+ continue;
VideoMode mode(info->width, info->height);
mode.index = modes.size();
- mode.monitor = &monitor;
- mode.rate = static_cast<float>(info->dotClock)/(info->hTotal*info->vTotal);
- if(find_mode(mode, 0.01f))
- continue;
+ mode.rate = rate;
modes.push_back(mode);
priv->modes.push_back(info->id);
- monitor.video_modes.push_back(&modes.back());
+ mode_monitor_indices.push_back(monitor.index);
if(crtc && info->id==crtc->mode)
- monitor.desktop_settings.mode = &modes.back();
+ desktop_mode_index = mode.index;
}
-
- monitor.current_settings = monitor.desktop_settings;
+ desktop_mode_indices.push_back(desktop_mode_index);
XRRFreeOutputInfo(output);
if(crtc)
XRRFreeScreenResources(res);
- monitors.sort(monitor_x_compare);
+ for(unsigned i=0; i<monitors.size(); ++i)
+ {
+ int j = desktop_mode_indices[i];
+ if(j>=0)
+ monitors[i].desktop_settings.mode = &modes[j];
+ monitors[i].current_settings = monitors[i].desktop_settings;
+ }
+
+ sort(monitors, monitor_x_compare);
+
+ for(unsigned i=0; i<modes.size(); ++i)
+ {
+ auto j = find_member(monitors, mode_monitor_indices[i], &Monitor::index);
+ modes[i].monitor = &*j;
+ j->video_modes.push_back(&modes[i]);
+ }
+
Monitor *prev_enabled = nullptr;
for(Monitor &m: monitors)
if(m.desktop_settings.mode)
prev_enabled = &m;
}
+ if(primary_index>=0)
+ primary_monitor = &*find_member(monitors, static_cast<unsigned>(primary_index), &Monitor::index);
+
if(!primary_monitor || !primary_monitor->desktop_settings.mode)
{
// XRandR didn't give a sensible primary monitor. Try to guess one.