[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54796] trunk/blender/intern/ghost/intern/ GHOST_DisplayManagerX11.cpp: GHOST/X11 support for frequency, from SDL' s mode switching.

Campbell Barton ideasman42 at gmail.com
Sat Feb 23 23:48:17 CET 2013


Revision: 54796
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54796
Author:   campbellbarton
Date:     2013-02-23 22:48:16 +0000 (Sat, 23 Feb 2013)
Log Message:
-----------
GHOST/X11 support for frequency, from SDL's mode switching.
also free the modes when done.

Modified Paths:
--------------
    trunk/blender/intern/ghost/intern/GHOST_DisplayManagerX11.cpp

Modified: trunk/blender/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_DisplayManagerX11.cpp	2013-02-23 20:42:15 UTC (rev 54795)
+++ trunk/blender/intern/ghost/intern/GHOST_DisplayManagerX11.cpp	2013-02-23 22:48:16 UTC (rev 54796)
@@ -40,7 +40,6 @@
 #include "GHOST_SystemX11.h"
 
 
-
 GHOST_DisplayManagerX11::
 GHOST_DisplayManagerX11(
     GHOST_SystemX11 *system
@@ -95,6 +94,17 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	       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);
+	if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) {
+		int best_fit = -1;
 
-	best_dist = 9999999;
-	best_fit = -1;
+		for (int i = 0; i < num_vidmodes; i++) {
+			if (vidmodes[i]->hdisplay < setting.xPixels ||
+			    vidmodes[i]->vdisplay < setting.yPixels)
+			{
+				continue;
+			}
 
-	for (int i = 0; i < num_vidmodes; i++) {
-		if (setting.xPixels > vidmodes[i]->hdisplay ||
-		    setting.yPixels > vidmodes[i]->vdisplay)
-			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;
+			}
 
-		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 ((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 @@
 	return GHOST_kSuccess;
 #endif
 }
-
-
-
-




More information about the Bf-blender-cvs mailing list