Remove LiveTV menu.
[vuplus_xbmc] / xbmc / settings / DisplaySettings.cpp
index 6c304ff..daa1b18 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *      Copyright (C) 2013 Team XBMC
- *      http://www.xbmc.org
+ *      http://xbmc.org
  *
  *  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
@@ -26,8 +26,9 @@
 #include "guilib/GraphicContext.h"
 #include "guilib/gui3d.h"
 #include "guilib/LocalizeStrings.h"
+#include "guilib/StereoscopicsManager.h"
 #include "settings/AdvancedSettings.h"
-#include "settings/Setting.h"
+#include "settings/lib/Setting.h"
 #include "settings/Settings.h"
 #include "threads/SingleLock.h"
 #include "utils/log.h"
@@ -50,6 +51,26 @@ float square_error(float x, float y)
   return std::max(yonx, xony);
 }
 
+static CStdString ModeFlagsToString(unsigned int flags, bool identifier)
+{
+  CStdString res;
+  if(flags & D3DPRESENTFLAG_INTERLACED)
+    res += "i";
+  else
+    res += "p";
+
+  if(!identifier)
+    res += " ";
+
+  if(flags & D3DPRESENTFLAG_MODE3DSBS)
+    res += "sbs";
+  else if(flags & D3DPRESENTFLAG_MODE3DTB)
+    res += "tab";
+  else if(identifier)
+    res += "std";
+  return res;
+}
+
 CDisplaySettings::CDisplaySettings()
 {
   m_resolutions.insert(m_resolutions.begin(), RES_CUSTOM, RESOLUTION_INFO());
@@ -204,7 +225,16 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
     if (settingId == "videoscreen.resolution")
       newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue();
     else if (settingId == "videoscreen.screen")
+    {
+      int screen = ((CSettingInt*)setting)->GetValue();
+
+      // if triggered by a change of screenmode, screen may not have changed
+      if (screen == GetCurrentDisplayMode())
+        return true;
+
+      // get desktop resolution for screen
       newRes = GetResolutionForScreen();
+    }
 
     string screenmode = GetStringFromResolution(newRes);
     CSettings::Get().SetString("videoscreen.screenmode", screenmode);
@@ -219,7 +249,7 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
 
     // check if the old or the new resolution was/is windowed
     // in which case we don't show any prompt to the user
-    if (oldRes != RES_WINDOW && newRes != RES_WINDOW)
+    if (oldRes != RES_WINDOW && newRes != RES_WINDOW && oldRes != newRes)
     {
       if (!m_resolutionChangeAborted)
       {
@@ -250,8 +280,21 @@ bool CDisplaySettings::OnSettingUpdate(CSetting* &setting, const char *oldSettin
     std::string screenmode = screenmodeSetting->GetValue();
     // in Eden there was no character ("i" or "p") indicating interlaced/progressive
     // at the end so we just add a "p" and assume progressive
+    // no 3d mode existed before, so just assume std modes
     if (screenmode.size() == 20)
-      return screenmodeSetting->SetValue(screenmode + "p");
+      return screenmodeSetting->SetValue(screenmode + "pstd");
+    if (screenmode.size() == 21)
+      return screenmodeSetting->SetValue(screenmode + "std");
+  }
+  else if (settingId == "videoscreen.vsync")
+  {
+    // This ifdef is intended to catch everything except Linux and FreeBSD
+#if !defined(TARGET_LINUX) || defined(TARGET_DARWIN) || defined(TARGET_ANDROID) || defined(TARGET_RASPBERRY_PI)
+    // in the Gotham alphas through beta3 the default value for darwin and android was set incorrectly.
+    CSettingInt *vsyncSetting = (CSettingInt*)setting;
+    if (vsyncSetting->GetValue() == VSYNC_DRIVER)
+      return vsyncSetting->SetValue(VSYNC_ALWAYS);
+#endif
   }
 
   return false;
@@ -318,7 +361,27 @@ RESOLUTION_INFO& CDisplaySettings::GetResolutionInfo(RESOLUTION resolution)
 void CDisplaySettings::AddResolutionInfo(const RESOLUTION_INFO &resolution)
 {
   CSingleLock lock(m_critical);
-  m_resolutions.push_back(resolution);
+  RESOLUTION_INFO res(resolution);
+
+  if((res.dwFlags & D3DPRESENTFLAG_MODE3DTB) == 0)
+  {
+    /* add corrections for some special case modes frame packing modes */
+
+    if(res.iScreenWidth  == 1920
+    && res.iScreenHeight == 2205)
+    {
+      res.iBlanking = 45;
+      res.dwFlags  |= D3DPRESENTFLAG_MODE3DTB;
+    }
+
+    if(res.iScreenWidth  == 1280
+    && res.iScreenHeight == 1470)
+    {
+      res.iBlanking = 30;
+      res.dwFlags  |= D3DPRESENTFLAG_MODE3DTB;
+    }
+  }
+  m_resolutions.push_back(res);
 }
 
 void CDisplaySettings::ApplyCalibrations()
@@ -407,23 +470,24 @@ DisplayMode CDisplaySettings::GetCurrentDisplayMode() const
   return GetCurrentResolutionInfo().iScreen;
 }
 
-RESOLUTION CDisplaySettings::FindBestMatchingResolution(const std::map<RESOLUTION, RESOLUTION_INFO> &resolutionInfos, int screen, int width, int height, float refreshrate, bool interlaced)
+RESOLUTION CDisplaySettings::FindBestMatchingResolution(const std::map<RESOLUTION, RESOLUTION_INFO> &resolutionInfos, int screen, int width, int height, float refreshrate, unsigned flags)
 {
-  int interlace = interlaced ? 100 : 200;
-
   // find the closest match to these in our res vector.  If we have the screen, we score the res
   RESOLUTION bestRes = RES_DESKTOP;
   float bestScore = FLT_MAX;
+  flags &= D3DPRESENTFLAG_MODEMASK;
 
   for (std::map<RESOLUTION, RESOLUTION_INFO>::const_iterator it = resolutionInfos.begin(); it != resolutionInfos.end(); ++it)
   {
     const RESOLUTION_INFO &info = it->second;
-    if (info.iScreen != screen)
+
+    if ( info.iScreen               != screen
+    ||  (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != flags)
       continue;
+
     float score = 10 * (square_error((float)info.iScreenWidth, (float)width) +
                   square_error((float)info.iScreenHeight, (float)height) +
-                  square_error(info.fRefreshRate, refreshrate) +
-                  square_error((float)((info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? 100 : 200), (float)interlace));
+                  square_error(info.fRefreshRate, refreshrate));
     if (score < bestScore)
     {
       bestScore = score;
@@ -440,22 +504,29 @@ RESOLUTION CDisplaySettings::GetResolutionFromString(const std::string &strResol
     return RES_DESKTOP;
   else if (strResolution == "WINDOW")
     return RES_WINDOW;
-  else if (strResolution.size() == 21)
+  else if (strResolution.size() >= 21)
   {
-    // format: SWWWWWHHHHHRRR.RRRRRP, where S = screen, W = width, H = height, R = refresh, P = interlace
+    // format: SWWWWWHHHHHRRR.RRRRRP333, where S = screen, W = width, H = height, R = refresh, P = interlace, 3 = stereo mode
     int screen = strtol(StringUtils::Mid(strResolution, 0,1).c_str(), NULL, 10);
     int width = strtol(StringUtils::Mid(strResolution, 1,5).c_str(), NULL, 10);
     int height = strtol(StringUtils::Mid(strResolution, 6,5).c_str(), NULL, 10);
     float refresh = (float)strtod(StringUtils::Mid(strResolution, 11,9).c_str(), NULL);
+    unsigned flags = 0;
+
     // look for 'i' and treat everything else as progressive,
-    // and use 100/200 to get a nice square_error.
-    bool interlaced = StringUtils::EndsWith(strResolution, "i");
+    if(StringUtils::Mid(strResolution, 20,1) == "i")
+      flags |= D3DPRESENTFLAG_INTERLACED;
+
+    if(StringUtils::Mid(strResolution, 21,3) == "sbs")
+      flags |= D3DPRESENTFLAG_MODE3DSBS;
+    else if(StringUtils::Mid(strResolution, 21,3) == "tab")
+      flags |= D3DPRESENTFLAG_MODE3DTB;
 
     std::map<RESOLUTION, RESOLUTION_INFO> resolutionInfos;
     for (size_t resolution = RES_DESKTOP; resolution < CDisplaySettings::Get().ResolutionInfoSize(); resolution++)
       resolutionInfos.insert(make_pair((RESOLUTION)resolution, CDisplaySettings::Get().GetResolutionInfo(resolution)));
 
-    return FindBestMatchingResolution(resolutionInfos, screen, width, height, refresh, interlaced);
+    return FindBestMatchingResolution(resolutionInfos, screen, width, height, refresh, flags);
   }
 
   return RES_DESKTOP;
@@ -474,8 +545,7 @@ std::string CDisplaySettings::GetStringFromResolution(RESOLUTION resolution, flo
     {
       return StringUtils::Format("%1i%05i%05i%09.5f%s", info.iScreen,
                                  info.iScreenWidth, info.iScreenHeight,
-                                 refreshrate > 0.0f ? refreshrate : info.fRefreshRate,
-                                 (info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? "i":"p");
+                                 refreshrate > 0.0f ? refreshrate : info.fRefreshRate, ModeFlagsToString(info.dwFlags, true).c_str());
     }
   }
 
@@ -525,7 +595,7 @@ void CDisplaySettings::SettingOptionsRefreshRatesFiller(const CSetting *setting,
   vector<REFRESHRATE> refreshrates = g_Windowing.RefreshRates(resInfo.iScreen, resInfo.iScreenWidth, resInfo.iScreenHeight, resInfo.dwFlags);
 
   bool match = false;
-  for (vector<REFRESHRATE>::const_iterator refreshrate = refreshrates.begin(); refreshrate != refreshrates.end(); refreshrate++)
+  for (vector<REFRESHRATE>::const_iterator refreshrate = refreshrates.begin(); refreshrate != refreshrates.end(); ++refreshrate)
   {
     std::string screenmode = GetStringFromResolution((RESOLUTION)refreshrate->ResInfo_Index, refreshrate->RefreshRate);
     if (!match && StringUtils::EqualsNoCase(((CSettingString*)setting)->GetValue(), screenmode))
@@ -550,11 +620,11 @@ void CDisplaySettings::SettingOptionsResolutionsFiller(const CSetting *setting,
   {
     std::map<RESOLUTION, RESOLUTION_INFO> resolutionInfos;
     vector<RESOLUTION_WHR> resolutions = g_Windowing.ScreenResolutions(info.iScreen, info.fRefreshRate);
-    for (vector<RESOLUTION_WHR>::const_iterator resolution = resolutions.begin(); resolution != resolutions.end(); resolution++)
+    for (vector<RESOLUTION_WHR>::const_iterator resolution = resolutions.begin(); resolution != resolutions.end(); ++resolution)
     {
       list.push_back(make_pair(
         StringUtils::Format("%dx%d%s", resolution->width, resolution->height,
-                            (resolution->interlaced == D3DPRESENTFLAG_INTERLACED) ? "i" : "p"),
+                            ModeFlagsToString(resolution->flags, false).c_str()),
                             resolution->ResInfo_Index));
 
       resolutionInfos.insert(make_pair((RESOLUTION)resolution->ResInfo_Index, CDisplaySettings::Get().GetResolutionInfo(resolution->ResInfo_Index)));
@@ -562,7 +632,7 @@ void CDisplaySettings::SettingOptionsResolutionsFiller(const CSetting *setting,
 
     current = FindBestMatchingResolution(resolutionInfos, info.iScreen,
                                          info.iScreenWidth, info.iScreenHeight,
-                                         info.fRefreshRate, info.dwFlags & D3DPRESENTFLAG_INTERLACED);
+                                         info.fRefreshRate, info.dwFlags);
   }
 }
 
@@ -589,10 +659,27 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std:
 
 void CDisplaySettings::SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
 {
-#if defined(_LINUX) && !defined(TARGET_DARWIN)
+  // This ifdef is intended to catch everything except Linux and FreeBSD
+#if defined(TARGET_LINUX) && !defined(TARGET_DARWIN) && !defined(TARGET_ANDROID) && !defined(TARGET_RASPBERRY_PI)
   list.push_back(make_pair(g_localizeStrings.Get(13101), VSYNC_DRIVER));
 #endif
   list.push_back(make_pair(g_localizeStrings.Get(13106), VSYNC_DISABLED));
   list.push_back(make_pair(g_localizeStrings.Get(13107), VSYNC_VIDEO));
   list.push_back(make_pair(g_localizeStrings.Get(13108), VSYNC_ALWAYS));
 }
+
+void CDisplaySettings::SettingOptionsStereoscopicModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
+{
+  for (int i = RENDER_STEREO_MODE_OFF; i < RENDER_STEREO_MODE_COUNT; i++)
+  {
+    RENDER_STEREO_MODE mode = (RENDER_STEREO_MODE) i;
+    if (g_Windowing.SupportsStereo(mode))
+      list.push_back(make_pair(CStereoscopicsManager::Get().GetLabelForStereoMode(mode), mode));
+  }
+}
+
+void CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
+{
+  SettingOptionsStereoscopicModesFiller(setting, list, current);
+  list.push_back(make_pair(g_localizeStrings.Get(36525), RENDER_STEREO_MODE_AUTO)); // option for autodetect
+}