Some improvements for xrandr

- choose best available refresh rate
 - if resolution doesn't exist, choose first available
 - other minor changes.

Works fine with Gnome, but I notices some issues on Openbox and Unity.
This commit is contained in:
Deve 2014-07-28 19:20:46 +02:00
parent dbe722316a
commit 46f73e8ecc
2 changed files with 84 additions and 71 deletions

View File

@ -245,26 +245,21 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
#ifdef _IRR_LINUX_X11_RANDR_ #ifdef _IRR_LINUX_X11_RANDR_
if (UseXRandR && CreationParams.Fullscreen) if (UseXRandR && CreationParams.Fullscreen)
{ {
if (old_mode == -1 || output_id == -1)
return false;
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
XRROutputInfo* output = XRRGetOutputInfo(display, res, res->outputs[output_id]); XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc); XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime, Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
crtc->x, crtc->y, res->modes[old_mode].id, crtc->x, crtc->y, old_mode,
crtc->rotation, &res->outputs[output_id], 1); crtc->rotation, &output_id, 1);
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output);
XRRFreeCrtcInfo(crtc); XRRFreeCrtcInfo(crtc);
XRRFreeScreenResources(res); XRRFreeScreenResources(res);
if (s != Success) if (s != Success)
{
return false; return false;
} }
}
#endif #endif
return true; return true;
} }
@ -336,41 +331,62 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
#ifdef _IRR_LINUX_X11_RANDR_ #ifdef _IRR_LINUX_X11_RANDR_
if (XRRQueryExtension(display, &eventbase, &errorbase)) if (XRRQueryExtension(display, &eventbase, &errorbase))
{ {
if (output_id == -1)
return false;
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res) if (!res)
{ {
return false; CreationParams.Fullscreen = false;
return CreationParams.Fullscreen;
} }
XRROutputInfo* output = XRRGetOutputInfo(display, res, res->outputs[output_id]); XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc); XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
float refresh_rate, refresh_rate_new;
for (int i = 0; i < res->nmode; i++) for (int i = 0; i < res->nmode; i++)
{ {
const XRRModeInfo* info = &res->modes[i]; const XRRModeInfo* mode = &res->modes[i];
if (bestMode == -1 && info->width == Width && info->height == Height) if (bestMode == -1 && mode->width == Width && mode->height == Height)
{ {
for (int j = 0; j < output->nmode; j++) for (int j = 0; j < output->nmode; j++)
{ {
if (res->modes[i].id != output->modes[j]) if (mode->id == output->modes[j])
continue; {
bestMode = j;
bestMode = i; refresh_rate = (mode->dotClock * 1000.0) / (mode->hTotal * mode->vTotal);
break; break;
} }
} }
} }
else if (bestMode != -1 && mode->width == Width && mode->height == Height)
if (bestMode != -1)
{ {
refresh_rate_new = (mode->dotClock * 1000.0) / (mode->hTotal * mode->vTotal);
if (refresh_rate_new <= refresh_rate)
break;
for (int j = 0; j < output->nmode; j++)
{
if (mode->id == output->modes[j])
{
bestMode = j;
refresh_rate = refresh_rate_new;
break;
}
}
}
}
// If video mode not found, try to use first available
if (bestMode == -1)
{
bestMode = 0;
}
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime, Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
crtc->x, crtc->y, res->modes[bestMode].id, crtc->x, crtc->y, output->modes[bestMode],
crtc->rotation, &res->outputs[output_id], 1); crtc->rotation, &output_id, 1);
XRRFreeCrtcInfo(crtc); XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output);
@ -378,12 +394,12 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
if (s != Success) if (s != Success)
{ {
return false; CreationParams.Fullscreen = false;
return CreationParams.Fullscreen;
} }
UseXRandR=true; UseXRandR=true;
} }
}
else else
#endif #endif
{ {
@ -1538,15 +1554,10 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
#ifdef _IRR_LINUX_X11_RANDR_ #ifdef _IRR_LINUX_X11_RANDR_
if (XRRQueryExtension(display, &eventbase, &errorbase)) if (XRRQueryExtension(display, &eventbase, &errorbase))
{ {
old_mode = -1;
output_id = -1;
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res) if (!res)
{
return NULL; return NULL;
}
XRROutputInfo *output = NULL; XRROutputInfo *output = NULL;
XRRCrtcInfo* crtc = NULL; XRRCrtcInfo* crtc = NULL;
@ -1570,7 +1581,7 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
continue; continue;
} }
output_id = i; output_id = res->outputs[i];
break; break;
} }
@ -1588,17 +1599,19 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
for (int j = 0; j < output->nmode; j++) for (int j = 0; j < output->nmode; j++)
{ {
if (res->modes[i].id == output->modes[j]) if (mode->id == output->modes[j])
{ {
VideoModeList.addMode(core::dimension2d<u32>( VideoModeList.addMode(core::dimension2d<u32>(
mode->width, mode->height), defaultDepth); mode->width, mode->height), defaultDepth);
break;
}
} }
if (res->modes[i].id == crtc->mode) if (mode->id == crtc->mode)
{ {
old_mode = i; old_mode = crtc->mode;
VideoModeList.setDesktop(defaultDepth, core::dimension2d<u32>(mode->width, mode->height)); VideoModeList.setDesktop(defaultDepth,
} core::dimension2d<u32>(mode->width, mode->height));
} }
} }

View File

@ -394,8 +394,8 @@ namespace irr
XF86VidModeModeInfo oldVideoMode; XF86VidModeModeInfo oldVideoMode;
#endif #endif
#ifdef _IRR_LINUX_X11_RANDR_ #ifdef _IRR_LINUX_X11_RANDR_
int output_id; RROutput output_id;
int old_mode; RRMode old_mode;
#endif #endif
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
GLXWindow glxWin; GLXWindow glxWin;