return 0;
}
+inline Msp::Graphics::VideoRotation rotation_from_sys(Rotation r)
+{
+ switch(r)
+ {
+ case RR_Rotate_90: return Msp::Graphics::ROTATE_RIGHT;
+ case RR_Rotate_180: return Msp::Graphics::ROTATE_INVERTED;
+ case RR_Rotate_270: return Msp::Graphics::ROTATE_LEFT;
+ default: return Msp::Graphics::ROTATE_NORMAL;
+ }
+}
+
+inline Rotation rotation_to_sys(Msp::Graphics::VideoRotation r)
+{
+ switch(r)
+ {
+ case Msp::Graphics::ROTATE_RIGHT: return RR_Rotate_90;
+ case Msp::Graphics::ROTATE_INVERTED: return RR_Rotate_180;
+ case Msp::Graphics::ROTATE_LEFT: return RR_Rotate_270;
+ default: return RR_Rotate_0;
+ }
+}
+
+bool monitor_x_compare(const Msp::Graphics::Monitor &m1, const Msp::Graphics::Monitor &m2)
+{
+ if(m1.desktop_mode && !m2.desktop_mode)
+ return true;
+ return m1.x<m2.x;
+}
+
+inline unsigned mode_width(const Msp::Graphics::VideoMode &m, Msp::Graphics::VideoRotation r)
+{
+ if(r==Msp::Graphics::ROTATE_RIGHT || r==Msp::Graphics::ROTATE_LEFT)
+ return m.height;
+ else
+ return m.width;
+}
+
}
monitor.index = monitors.size()-1;
priv->monitors.push_back(res->outputs[i]);
+ if(crtc)
+ {
+ monitor.desktop_rotation = rotation_from_sys(crtc->rotation);
+ monitor.current_rotation = monitor.desktop_rotation;
+ monitor.x = crtc->x;
+ monitor.y = crtc->y;
+ }
+
if(res->outputs[i]==primary)
primary_monitor = &monitor;
monitor.video_modes.push_back(&modes.back());
if(crtc && info->id==crtc->mode)
+ {
monitor.desktop_mode = &modes.back();
+ monitor.current_mode = monitor.desktop_mode;
+ }
}
XRRFreeOutputInfo(output);
}
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_mode)
+ {
+ i->next_left = prev_enabled;
+ if(prev_enabled)
+ prev_enabled->next_right = &*i;
+ prev_enabled = &*i;
+ }
}
}
#endif
if(!mode)
throw unsupported_video_mode(requested_mode);
+ VideoRotation requested_rotation = requested_mode.rotation;
+ if(requested_rotation==ROTATE_ANY)
+ requested_rotation = mode->monitor->desktop_rotation;
+
WindowHandle root = DefaultRootWindow(priv->display);
XRRScreenResources *res = XRRGetScreenResources(priv->display, root);
RROutput output = priv->monitors[mode->monitor->index];
}
}
+ int x = 0;
+ int y = 0;
+
if(exclusive)
{
// Disable other outputs for exclusive mode
- for(unsigned i=0; i<priv->monitors.size(); ++i)
- if(i!=mode->monitor->index)
+ for(list<Monitor>::iterator i=monitors.begin(); i!=monitors.end(); ++i)
+ if(&*i!=mode->monitor)
{
- XRROutputInfo *o = XRRGetOutputInfo(priv->display, res, priv->monitors[i]);
+ XRROutputInfo *o = XRRGetOutputInfo(priv->display, res, priv->monitors[i->index]);
if(o->crtc)
XRRSetCrtcConfig(priv->display, res, o->crtc, CurrentTime, 0, 0, 0, RR_Rotate_0, 0, 0);
XRRFreeOutputInfo(o);
+
+ i->current_mode = 0;
+ i->current_rotation = ROTATE_NORMAL;
+ i->x = 0;
+ i->y = 0;
}
}
+ else
+ {
+ const Monitor *left = mode->monitor->next_left;
+ while(left && !left->current_mode)
+ left = left->next_left;
- XRRSetCrtcConfig(priv->display, res, crtc, CurrentTime, 0, 0, priv->modes[mode->index], RR_Rotate_0, &output, 1);
+ if(left)
+ {
+ x = left->x+mode_width(*left->current_mode, left->current_rotation);
+ y = left->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_mode = mode;
+ i->current_rotation = requested_rotation;
+ i->x = x;
+ i->y = y;
+
+ x += mode_width(*mode, requested_rotation);
+ ++i;
+ break;
+ }
+
+ for(; i!=monitors.end(); ++i)
+ if(i->current_mode)
+ {
+ XRROutputInfo *o = XRRGetOutputInfo(priv->display, res, priv->monitors[i->index]);
+ XRRSetCrtcConfig(priv->display, res, o->crtc, CurrentTime, x, y, priv->modes[i->current_mode->index], rotation_to_sys(i->current_rotation), &priv->monitors[i->index], 1);
+ XRRFreeOutputInfo(o);
+
+ i->x = x;
+ i->y = y;
+
+ x += mode_width(*i->current_mode, i->current_rotation);
+ }
XRRFreeOutputInfo(output_info);
XRRFreeCrtcInfo(crtc_info);