+#include "display.h"
+#include "display_private.h"
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#ifdef WITH_XRANDR
#include <msp/io/print.h>
#include <msp/strings/format.h>
#include <msp/strings/lexicalcast.h>
-#include "display.h"
-#include "display_private.h"
using namespace std;
namespace {
bool error_flag = false;
-std::string error_msg;
+string error_msg;
int x_error_handler(Display *display, XErrorEvent *event)
{
namespace Graphics {
Display::Display(const string &disp_name):
- primary_monitor(0),
- priv(new Private),
- focus_window(0)
+ priv(new Private)
{
if(disp_name.empty())
- priv->display = XOpenDisplay(0);
+ priv->display = XOpenDisplay(nullptr);
else
priv->display = XOpenDisplay(disp_name.c_str());
if(!priv->display)
for(int i=0; i<res->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(priv->display, res, res->outputs[i]);
- XRRCrtcInfo *crtc = (output->crtc ? XRRGetCrtcInfo(priv->display, res, output->crtc) : 0);
+ XRRCrtcInfo *crtc = (output->crtc ? XRRGetCrtcInfo(priv->display, res, output->crtc) : nullptr);
monitors.push_back(Monitor());
Monitor &monitor = monitors.back();
int prop_format;
unsigned long length;
unsigned long overflow;
- unsigned char *edid = 0;
+ unsigned char *edid = nullptr;
XRRGetOutputProperty(priv->display, res->outputs[i], edid_prop, 0, 32, false, false, XA_INTEGER, &prop_type, &prop_format, &length, &overflow, &edid);
if(prop_type==XA_INTEGER && prop_format==8)
{
for(int j=0; j<output->nmode; ++j)
{
- map<RRMode, XRRModeInfo *>::iterator k = modes_by_id.find(output->modes[j]);
+ auto k = modes_by_id.find(output->modes[j]);
if(k==modes_by_id.end())
continue;
XRRFreeScreenResources(res);
monitors.sort(monitor_x_compare);
- Monitor *prev_enabled = 0;
- for(list<Monitor>::iterator i=monitors.begin(); i!=monitors.end(); ++i)
- if(i->desktop_settings.mode)
+ Monitor *prev_enabled = nullptr;
+ for(Monitor &m: monitors)
+ if(m.desktop_settings.mode)
{
- i->next_left = prev_enabled;
+ m.next_left = prev_enabled;
if(prev_enabled)
- prev_enabled->next_right = &*i;
- prev_enabled = &*i;
+ prev_enabled->next_right = &m;
+ prev_enabled = &m;
}
if(!primary_monitor || !primary_monitor->desktop_settings.mode)
{
// XRandR didn't give a sensible primary monitor. Try to guess one.
unsigned largest = 0;
- for(list<Monitor>::iterator i=monitors.begin(); i!=monitors.end(); ++i)
- if(const VideoMode *desktop_mode = i->desktop_settings.mode)
+ for(Monitor &m: monitors)
+ if(const VideoMode *desktop_mode = m.desktop_settings.mode)
{
unsigned size = desktop_mode->width*desktop_mode->height;
if(size>largest)
{
largest = size;
- primary_monitor = &*i;
+ primary_monitor = &m;
}
}
}
// Check if the output already has a CRTC and find a free one if it doesn't
RRCrtc crtc = output_info->crtc;
- XRRCrtcInfo *crtc_info = 0;
+ XRRCrtcInfo *crtc_info = nullptr;
if(crtc)
crtc_info = XRRGetCrtcInfo(priv->display, res, crtc);
else
}
}
- int x = 0;
- int y = 0;
+ /* Due to the semantics of find_mode, the mode's monitor pointer must point
+ to one of the elements of the monitors list, which is non-const here. */
+ Monitor *monitor = const_cast<Monitor *>(mode->monitor);
if(exclusive)
{
+ monitor->current_settings.mode = mode;
+ monitor->current_settings.rotation = requested_rotation;
+ monitor->current_settings.x = 0;
+ monitor->current_settings.y = 0;
+
// Disable other outputs for exclusive mode
- for(list<Monitor>::iterator i=monitors.begin(); i!=monitors.end(); ++i)
- if(&*i!=mode->monitor)
+ for(Monitor &m: monitors)
+ if(&m!=mode->monitor)
{
- XRROutputInfo *o = XRRGetOutputInfo(priv->display, res, priv->monitors[i->index]);
+ XRROutputInfo *o = XRRGetOutputInfo(priv->display, res, priv->monitors[m.index]);
if(o->crtc)
- XRRSetCrtcConfig(priv->display, res, o->crtc, CurrentTime, 0, 0, 0, RR_Rotate_0, 0, 0);
+ XRRSetCrtcConfig(priv->display, res, o->crtc, CurrentTime, 0, 0, 0, RR_Rotate_0, nullptr, 0);
XRRFreeOutputInfo(o);
- i->current_settings.mode = 0;
- i->current_settings.rotation = ROTATE_NORMAL;
- i->current_settings.x = 0;
- i->current_settings.y = 0;
+ m.current_settings.mode = nullptr;
+ m.current_settings.rotation = ROTATE_NORMAL;
+ m.current_settings.x = 0;
+ m.current_settings.y = 0;
}
}
else
{
- const Monitor *left = mode->monitor->next_left;
- while(left && !left->current_settings.mode)
- left = left->next_left;
-
- if(left)
- {
- const Monitor::Settings &cs = left->current_settings;
- x = cs.x+mode_width(*cs.mode, cs.rotation);
- y = cs.y;
- }
+ monitor->current_settings.x = monitor->desktop_settings.x;
+ monitor->current_settings.y = monitor->desktop_settings.y;
}
- XRRSetCrtcConfig(priv->display, res, crtc, CurrentTime, x, y, priv->modes[mode->index], rotation_to_sys(requested_rotation), &output, 1);
-
- list<Monitor>::iterator i;
- for(i=monitors.begin(); i!=monitors.end(); ++i)
- if(&*i==mode->monitor)
- {
- i->current_settings.mode = mode;
- i->current_settings.rotation = requested_rotation;
- i->current_settings.x = x;
- i->current_settings.y = y;
-
- x += mode_width(*mode, requested_rotation);
- ++i;
- break;
- }
-
- for(; i!=monitors.end(); ++i)
- if(i->current_settings.mode)
- {
- XRROutputInfo *o = XRRGetOutputInfo(priv->display, res, priv->monitors[i->index]);
- XRRSetCrtcConfig(priv->display, res, o->crtc, CurrentTime, x, y, priv->modes[i->current_settings.mode->index], rotation_to_sys(i->current_settings.rotation), &priv->monitors[i->index], 1);
-
- XRRPanning panning;
- panning.timestamp = CurrentTime;
- panning.left = x;
- panning.top = y;
- panning.width = i->current_settings.mode->width;
- panning.height = i->current_settings.mode->height;
- panning.track_left = panning.left;
- panning.track_top = panning.top;
- panning.track_width = panning.width;
- panning.track_height = panning.height;
- panning.border_left = 0;
- panning.border_top = 0;
- panning.border_right = 0;
- panning.border_bottom = 0;
- XRRSetPanning(priv->display, res, o->crtc, &panning);
-
- XRRFreeOutputInfo(o);
-
- i->current_settings.x = x;
- i->current_settings.y = y;
-
- x += mode_width(*i->current_settings.mode, i->current_settings.rotation);
- }
+ RRMode mode_id = priv->modes[mode->index];
+ int x = monitor->current_settings.x;
+ int y = monitor->current_settings.y;
+ Rotation sys_rot = rotation_to_sys(requested_rotation);
+ XRRSetCrtcConfig(priv->display, res, crtc, CurrentTime, x, y, mode_id, sys_rot, &output, 1);
XRRFreeOutputInfo(output_info);
XRRFreeCrtcInfo(crtc_info);
check_error();
- map<WindowHandle, Window *>::iterator j = priv->windows.find(event.xevent.xany.window);
+ auto j = priv->windows.find(event.xevent.xany.window);
if(j!=priv->windows.end())
{
/* Filter keyboard autorepeat. If this packet is a KeyRelease and