X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fx11%2Fdisplay.cpp;h=368b67cecdc5b6953db9e113664e16f30bed9889;hb=0913ba6fdd0e28740e0b521f275b9ce82c4a1b7a;hp=2f276a32d5246666aeae56b722379fd46dff2d34;hpb=9a1b03ad820b49c4ed73f20d2cf82e445d245254;p=libs%2Fgui.git diff --git a/source/graphics/x11/display.cpp b/source/graphics/x11/display.cpp index 2f276a3..368b67c 100644 --- a/source/graphics/x11/display.cpp +++ b/source/graphics/x11/display.cpp @@ -38,6 +38,43 @@ int x_error_handler(Display *display, XErrorEvent *event) 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.xmonitors.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; @@ -107,7 +152,10 @@ Display::Display(const string &disp_name): 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); @@ -116,6 +164,17 @@ Display::Display(const string &disp_name): } XRRFreeScreenResources(res); + + monitors.sort(monitor_x_compare); + Monitor *prev_enabled = 0; + for(list::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 @@ -134,6 +193,10 @@ void Display::set_mode(const VideoMode &requested_mode, bool exclusive) 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]; @@ -164,20 +227,67 @@ void Display::set_mode(const VideoMode &requested_mode, bool exclusive) } } + int x = 0; + int y = 0; + if(exclusive) { // Disable other outputs for exclusive mode - for(unsigned i=0; imonitors.size(); ++i) - if(i!=mode->monitor->index) + for(list::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::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);