ClangFormat: apply to source, most of intern
[blender.git] / intern / ghost / intern / GHOST_DisplayManagerX11.cpp
index b8fe271fd4de72dd673e46bd954ab8bf6655bde6..4626955ac7ffc68ee2c6ccea3e516f973c2c1cb5 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
  * Video mode switching
  * Copyright (C) 1997-2001 Id Software, Inc.
  * Ported from Quake 2 by Alex Fraser <alex@phatcore.com>
- *
- * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file ghost/intern/GHOST_DisplayManagerX11.cpp
- *  \ingroup GHOST
+/** \file
+ * \ingroup GHOST
  */
 
 #ifdef WITH_X11_XF86VMODE
 #include "GHOST_DisplayManagerX11.h"
 #include "GHOST_SystemX11.h"
 
-
-
-GHOST_DisplayManagerX11::
-GHOST_DisplayManagerX11(
-       GHOST_SystemX11 *system
-) :
-       GHOST_DisplayManager(),
-       m_system(system)
+GHOST_DisplayManagerX11::GHOST_DisplayManagerX11(GHOST_SystemX11 *system)
+    : GHOST_DisplayManager(), m_system(system)
 {
-       //nothing to do.
+  /* nothing to do. */
 }
 
-       GHOST_TSuccess 
-GHOST_DisplayManagerX11::
-getNumDisplays(
-       GHOST_TUns8& numDisplays
-) const{       
-       numDisplays =  m_system->getNumDisplays();
-       return GHOST_kSuccess;
+GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplays(GHOST_TUns8 &numDisplays) const
+{
+  numDisplays = m_system->getNumDisplays();
+  return GHOST_kSuccess;
 }
 
-
-       GHOST_TSuccess 
-GHOST_DisplayManagerX11::
-getNumDisplaySettings(
-       GHOST_TUns8 display,
-       GHOST_TInt32& numSettings
-) const{
+GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplaySettings(GHOST_TUns8 display,
+                                                              GHOST_TInt32 &numSettings) const
+{
 #ifdef WITH_X11_XF86VMODE
-       int majorVersion, minorVersion;
-       XF86VidModeModeInfo **vidmodes;
-       Display *dpy = m_system->getXDisplay();
+  int majorVersion, minorVersion;
+  XF86VidModeModeInfo **vidmodes;
+  Display *dpy = m_system->getXDisplay();
 
-       GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+  GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
 
-       if (dpy == NULL)
-               return GHOST_kFailure;
+  if (dpy == NULL)
+    return GHOST_kFailure;
 
-       majorVersion = minorVersion = 0;
-       if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
-               fprintf(stderr, "Error: XF86VidMode extension missing!\n");
-               return GHOST_kFailure;
-       }
+  majorVersion = minorVersion = 0;
+  if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+    fprintf(stderr, "Error: XF86VidMode extension missing!\n");
+    return GHOST_kFailure;
+  }
 
-       /* The X11 man page says vidmodes needs to be freed, but doing so causes a
-        * segfault. - z0r */
-       XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes);
+  if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
+    XFree(vidmodes);
+  }
 
 #else
-       // We only have one X11 setting at the moment.
-       GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");    
-       numSettings = GHOST_TInt32(1);
+  /* We only have one X11 setting at the moment. */
+  GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+  numSettings = 1;
 #endif
 
-       return GHOST_kSuccess;
+  (void)display;
+  return GHOST_kSuccess;
 }
 
-       GHOST_TSuccess 
-GHOST_DisplayManagerX11::
-getDisplaySetting(
-       GHOST_TUns8 display,
-       GHOST_TInt32 index,
-       GHOST_DisplaySetting& setting
-) const {
-
+/* from SDL2 */
 #ifdef WITH_X11_XF86VMODE
-       int majorVersion, minorVersion;
-       XF86VidModeModeInfo **vidmodes;
-       Display *dpy = m_system->getXDisplay();
-       int numSettings;
-
-       GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
-
-       if (dpy == NULL)
-               return GHOST_kFailure;
-
-       majorVersion = minorVersion = 0;
-       if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
-               fprintf(stderr, "Error: XF86VidMode extension missing!\n");
-               return GHOST_kFailure;
-       }
-
-       /* The X11 man page says vidmodes needs to be freed, but doing so causes a
-        * segfault. - z0r */
-       XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes);
-       GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");
+static int calculate_rate(XF86VidModeModeInfo *info)
+{
+  return (info->htotal && info->vtotal) ? (1000 * info->dotclock / (info->htotal * info->vtotal)) :
+                                          0;
+}
+#endif
 
-       setting.xPixels = vidmodes[index]->hdisplay;
-       setting.yPixels = vidmodes[index]->vdisplay;
-       setting.bpp = DefaultDepth(dpy,DefaultScreen(dpy));
+GHOST_TSuccess GHOST_DisplayManagerX11::getDisplaySetting(GHOST_TUns8 display,
+                                                          GHOST_TInt32 index,
+                                                          GHOST_DisplaySetting &setting) const
+{
+  Display *dpy = m_system->getXDisplay();
 
-#else
-       GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");    
-       GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); 
-       
-       Display * x_display = m_system->getXDisplay();
-
-       if (x_display == NULL) {
-               return GHOST_kFailure;
-       }
-
-       setting.xPixels  = DisplayWidth(x_display, DefaultScreen(x_display));
-       setting.yPixels = DisplayHeight(x_display, DefaultScreen(x_display));
-       setting.bpp = DefaultDepth(x_display,DefaultScreen(x_display));
-#endif
+  if (dpy == NULL)
+    return GHOST_kFailure;
 
-       // Don't think it's possible to get this value from X!
-       // So let's guess!!
-       setting.frequency = 60;
+  (void)display;
 
-       return GHOST_kSuccess;
-}
-       
-       GHOST_TSuccess 
-GHOST_DisplayManagerX11::
-getCurrentDisplaySetting(
-       GHOST_TUns8 display,
-       GHOST_DisplaySetting& setting
-) const {
-       /* According to the xf86vidmodegetallmodelines man page,
-        * "The first element of the array corresponds to the current video mode."
-        */
-       return getDisplaySetting(display,GHOST_TInt32(0),setting);
+#ifdef WITH_X11_XF86VMODE
+  int majorVersion, minorVersion;
+
+  GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+
+  majorVersion = minorVersion = 0;
+  if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+    XF86VidModeModeInfo **vidmodes;
+    int numSettings;
+
+    if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
+      GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");
+
+      setting.xPixels = vidmodes[index]->hdisplay;
+      setting.yPixels = vidmodes[index]->vdisplay;
+      setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
+      setting.frequency = calculate_rate(vidmodes[index]);
+      XFree(vidmodes);
+
+      return GHOST_kSuccess;
+    }
+  }
+  else {
+    fprintf(stderr, "Warning: XF86VidMode extension missing!\n");
+    /* fallback to non xf86vmode below */
+  }
+#endif /* WITH_X11_XF86VMODE */
+
+  GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+  GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
+  (void)index;
+
+  setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy));
+  setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy));
+  setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
+  setting.frequency = 60.0f;
+
+  return GHOST_kSuccess;
 }
 
+GHOST_TSuccess GHOST_DisplayManagerX11::getCurrentDisplaySetting(
+    GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
+{
+  /* According to the xf86vidmodegetallmodelines man page,
+   * "The first element of the array corresponds to the current video mode."
+   */
+  return getDisplaySetting(display, 0, setting);
+}
 
-       GHOST_TSuccess 
-GHOST_DisplayManagerX11::
-setCurrentDisplaySetting(
-       GHOST_TUns8 display,
-       const GHOST_DisplaySetting& setting
-){
+GHOST_TSuccess GHOST_DisplayManagerX11::setCurrentDisplaySetting(
+    GHOST_TUns8 /*display*/, const GHOST_DisplaySetting &setting)
+{
 #ifdef WITH_X11_XF86VMODE
-       //
-       // Mode switching code ported from Quake 2:
-       // ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
-       // See linux/gl_glx.c:GLimp_SetMode
-       //
-       int majorVersion, minorVersion;
-       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;
-
-       scrnum = DefaultScreen(dpy);
-
-       // Get video mode list
-       majorVersion = minorVersion = 0;
-       if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
-               fprintf(stderr, "Error: XF86VidMode extension missing!\n");
-               return GHOST_kFailure;
-       }
-#  ifdef _DEBUG
-       printf("Using XFree86-VidModeExtension Version %d.%d\n",
-                       majorVersion, minorVersion);
+  /* Mode switching code ported from SDL:
+   * See: src/video/x11/SDL_x11modes.c:set_best_resolution
+   */
+  int majorVersion, minorVersion;
+  XF86VidModeModeInfo **vidmodes;
+  Display *dpy = m_system->getXDisplay();
+  int scrnum, num_vidmodes;
+
+  if (dpy == NULL)
+    return GHOST_kFailure;
+
+  scrnum = DefaultScreen(dpy);
+
+  /* Get video mode list */
+  majorVersion = minorVersion = 0;
+  if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+    fprintf(stderr, "Error: XF86VidMode extension missing!\n");
+    return GHOST_kFailure;
+  }
+#  ifdef DEBUG
+  printf("Using XFree86-VidModeExtension Version %d.%d\n", 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 (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);
+  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
+      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);
-       } else
-               return GHOST_kFailure;
+    XFree(vidmodes);
+  }
+  else {
+    return GHOST_kFailure;
+  }
 
-       XFlush(dpy);
-       return GHOST_kSuccess;
+  XFlush(dpy);
+  return GHOST_kSuccess;
 
 #else
-       // Just pretend the request was successful.
-       return GHOST_kSuccess;
+  (void)setting;
+
+  /* Just pretend the request was successful. */
+  return GHOST_kSuccess;
 #endif
 }
-
-
-
-