diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-02-24 02:48:16 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-02-24 02:48:16 +0400 |
commit | 233b69f0bd0251d8b3a78398d67844b45fcf77b2 (patch) | |
tree | a67a1a6d518d8f09df20825a19b8c90c91975c61 /intern | |
parent | 92189ab35331a238aee946b2cd2e542de26f0474 (diff) |
GHOST/X11 support for frequency, from SDL's mode switching.
also free the modes when done.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_DisplayManagerX11.cpp | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 754218191a5..8d5ac9d77eb 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -40,7 +40,6 @@ #include "GHOST_SystemX11.h" - GHOST_DisplayManagerX11:: GHOST_DisplayManagerX11( GHOST_SystemX11 *system @@ -95,6 +94,17 @@ getNumDisplaySettings( return GHOST_kSuccess; } +/* from SDL2 */ +#ifdef WITH_X11_XF86VMODE +static int +calculate_rate(XF86VidModeModeInfo *info) +{ + return (info->htotal + && info->vtotal) ? (1000 * info->dotclock / (info->htotal * + info->vtotal)) : 0; +} +#endif + GHOST_TSuccess GHOST_DisplayManagerX11:: getDisplaySetting( @@ -128,6 +138,7 @@ getDisplaySetting( setting.xPixels = vidmodes[index]->hdisplay; setting.yPixels = vidmodes[index]->vdisplay; setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); + setting.frequency = (float)calculate_rate(vidmodes[index]); #else GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); @@ -142,11 +153,9 @@ getDisplaySetting( setting.xPixels = DisplayWidth(x_display, DefaultScreen(x_display)); setting.yPixels = DisplayHeight(x_display, DefaultScreen(x_display)); setting.bpp = DefaultDepth(x_display, DefaultScreen(x_display)); + setting.frequency = 60.0f; #endif - /* Don't think it's possible to get this value from X! - * So let's guess!! */ - setting.frequency = 60; return GHOST_kSuccess; } @@ -179,7 +188,6 @@ setCurrentDisplaySetting( XF86VidModeModeInfo **vidmodes; Display *dpy = m_system->getXDisplay(); int scrnum, num_vidmodes; - int best_fit, best_dist, dist, x, y; if (dpy == NULL) return GHOST_kFailure; @@ -197,41 +205,62 @@ setCurrentDisplaySetting( majorVersion, minorVersion); # endif - /* The X11 man page says vidmodes needs to be freed, but doing so causes a - * segfault. - z0r */ - XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); - - best_dist = 9999999; - best_fit = -1; - - for (int i = 0; i < num_vidmodes; i++) { - if (setting.xPixels > vidmodes[i]->hdisplay || - setting.yPixels > vidmodes[i]->vdisplay) - continue; - - x = setting.xPixels - vidmodes[i]->hdisplay; - y = setting.yPixels - vidmodes[i]->vdisplay; - dist = (x * x) + (y * y); - if (dist < best_dist) { - best_dist = dist; - best_fit = i; + if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) { + int best_fit = -1; + + for (int i = 0; i < num_vidmodes; i++) { + if (vidmodes[i]->hdisplay < setting.xPixels || + vidmodes[i]->vdisplay < setting.yPixels) + { + continue; + } + + if (best_fit == -1 || + (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) || + (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay && + vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay)) + { + best_fit = i; + continue; + } + + if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) && + (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay)) + { + if (!setting.frequency) { + /* Higher is better, right? */ + if (calculate_rate(vidmodes[i]) > + calculate_rate(vidmodes[best_fit])) + { + best_fit = i; + } + } + else { + if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) < + abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency)) + { + best_fit = i; + } + } + } } - } - if (best_fit != -1) { -# ifdef _DEBUG - int actualWidth, actualHeight; - actualWidth = vidmodes[best_fit]->hdisplay; - actualHeight = vidmodes[best_fit]->vdisplay; - printf("Switching to video mode %dx%d\n", - actualWidth, actualHeight); -# endif + if (best_fit != -1) { + # ifdef _DEBUG + printf("Switching to video mode %dx%d %dx%d %d\n", + vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay, + vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal, + calculate_rate(vidmodes[best_fit])); + # endif - /* change to the mode */ - XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + /* change to the mode */ + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + + /* Move the viewport to top left */ + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + } - /* Move the viewport to top left */ - XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + XFree(vidmodes); } else { return GHOST_kFailure; @@ -245,7 +274,3 @@ setCurrentDisplaySetting( return GHOST_kSuccess; #endif } - - - - |