Merge pull request #4775 from jmarshallnz/empty_episode_playcount
[vuplus_xbmc] / xbmc / windowing / WinSystem.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "WinSystem.h"
22 #include "guilib/GraphicContext.h"
23 #include "settings/DisplaySettings.h"
24 #include "settings/lib/Setting.h"
25 #include "settings/Settings.h"
26 #include "utils/StringUtils.h"
27
28 using namespace std;
29
30 CWinSystemBase::CWinSystemBase()
31 {
32   m_eWindowSystem = WINDOW_SYSTEM_WIN32; // this is the 0 value enum
33   m_nWidth = 0;
34   m_nHeight = 0;
35   m_nTop = 0;
36   m_nLeft = 0;
37   m_bWindowCreated = false;
38   m_bFullScreen = false;
39   m_nScreen = 0;
40   m_bBlankOtherDisplay = false;
41   m_fRefreshRate = 0.0f;
42 }
43
44 CWinSystemBase::~CWinSystemBase()
45 {
46
47 }
48
49 bool CWinSystemBase::InitWindowSystem()
50 {
51   UpdateResolutions();
52   CDisplaySettings::Get().ApplyCalibrations();
53   return true;
54 }
55
56 void CWinSystemBase::UpdateDesktopResolution(RESOLUTION_INFO& newRes, int screen, int width, int height, float refreshRate, uint32_t dwFlags)
57 {
58   newRes.Overscan.left = 0;
59   newRes.Overscan.top = 0;
60   newRes.Overscan.right = width;
61   newRes.Overscan.bottom = height;
62   newRes.iScreen = screen;
63   newRes.bFullScreen = true;
64   newRes.iSubtitles = (int)(0.965 * height);
65   newRes.dwFlags = dwFlags;
66   newRes.fRefreshRate = refreshRate;
67   newRes.fPixelRatio = 1.0f;
68   newRes.iWidth = width;
69   newRes.iHeight = height;
70   newRes.iScreenWidth = width;
71   newRes.iScreenHeight = height;
72   newRes.strMode = StringUtils::Format("%dx%d", width, height);
73   if (refreshRate > 1)
74     newRes.strMode += StringUtils::Format("@ %.2f", refreshRate);
75   if (dwFlags & D3DPRESENTFLAG_INTERLACED)
76     newRes.strMode += "i";
77   if (dwFlags & D3DPRESENTFLAG_MODE3DTB)
78     newRes.strMode += "tab";
79   if (dwFlags & D3DPRESENTFLAG_MODE3DSBS)
80     newRes.strMode += "sbs";
81   if (screen > 0)
82     newRes.strMode = StringUtils::Format("%s #%d", newRes.strMode.c_str(), screen + 1);
83   if (refreshRate > 1)
84     newRes.strMode += " - Full Screen";
85 }
86
87 void CWinSystemBase::UpdateResolutions()
88 {
89   // add the window res - defaults are fine.
90   RESOLUTION_INFO& window = CDisplaySettings::Get().GetResolutionInfo(RES_WINDOW);
91   window.bFullScreen = false;
92   if (window.iWidth == 0)
93     window.iWidth = 720;
94   if (window.iHeight == 0)
95     window.iHeight = 480;
96   window.iScreenWidth  = window.iWidth;
97   window.iScreenHeight = window.iHeight;
98   if (window.iSubtitles == 0)
99     window.iSubtitles = (int)(0.965 * window.iHeight);
100   window.fPixelRatio = 1.0f;
101   window.strMode = "Windowed";
102 }
103
104 void CWinSystemBase::SetWindowResolution(int width, int height)
105 {
106   RESOLUTION_INFO& window = CDisplaySettings::Get().GetResolutionInfo(RES_WINDOW);
107   window.iWidth = width;
108   window.iHeight = height;
109   window.iScreenWidth = width;
110   window.iScreenHeight = height;
111   window.iSubtitles = (int)(0.965 * window.iHeight);
112   g_graphicsContext.ResetOverscan(window);
113 }
114
115 int CWinSystemBase::DesktopResolution(int screen)
116 {
117   for (int idx = 0; idx < GetNumScreens(); idx++)
118     if (CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP + idx).iScreen == screen)
119       return RES_DESKTOP + idx;
120   // Uh? something's wrong, fallback to default res of main screen
121   return RES_DESKTOP;
122 }
123
124 static void AddResolution(vector<RESOLUTION_WHR> &resolutions, unsigned int addindex, float bestRefreshrate)
125 {
126   RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(addindex);
127   int width  = resInfo.iScreenWidth;
128   int height = resInfo.iScreenHeight;
129   int flags  = resInfo.dwFlags & D3DPRESENTFLAG_MODEMASK;
130   float refreshrate = resInfo.fRefreshRate;
131
132   // don't touch RES_DESKTOP
133   for (unsigned int idx = 1; idx < resolutions.size(); idx++)
134     if (   resolutions[idx].width == width
135         && resolutions[idx].height == height
136         &&(resolutions[idx].flags & D3DPRESENTFLAG_MODEMASK) == flags)
137     {
138       // check if the refresh rate of this resolution is better suited than
139       // the refresh rate of the resolution with the same width/height/interlaced
140       // property and if so replace it
141       if (bestRefreshrate > 0.0 && refreshrate == bestRefreshrate)
142         resolutions[idx].ResInfo_Index = addindex;
143
144       // no need to add the resolution again
145       return;
146     }
147
148   RESOLUTION_WHR res = {width, height, flags, (int)addindex};
149   resolutions.push_back(res);
150 }
151
152 static bool resSortPredicate(RESOLUTION_WHR i, RESOLUTION_WHR j)
153 {
154   // note: this comparison must obey "strict weak ordering"
155   // a "!=" on the flags comparison resulted in memory corruption
156   return (    i.width < j.width
157           || (i.width == j.width && i.height < j.height)
158           || (i.width == j.width && i.height == j.height && i.flags < j.flags) );
159 }
160
161 vector<RESOLUTION_WHR> CWinSystemBase::ScreenResolutions(int screen, float refreshrate)
162 {
163   vector<RESOLUTION_WHR> resolutions;
164
165   for (unsigned int idx = RES_DESKTOP; idx < CDisplaySettings::Get().ResolutionInfoSize(); idx++)
166   {
167     RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(idx);
168     if (info.iScreen == screen)
169       AddResolution(resolutions, idx, refreshrate);
170   }
171
172   // Can't assume a sort order
173   // don't touch RES_DESKTOP which is index 0
174   sort(resolutions.begin()+1, resolutions.end(), resSortPredicate);
175
176   return resolutions;
177 }
178
179 static void AddRefreshRate(vector<REFRESHRATE> &refreshrates, unsigned int addindex)
180 {
181   float RefreshRate = CDisplaySettings::Get().GetResolutionInfo(addindex).fRefreshRate;
182
183   for (unsigned int idx = 0; idx < refreshrates.size(); idx++)
184     if (   refreshrates[idx].RefreshRate == RefreshRate)
185       return; // already taken care of.
186
187   REFRESHRATE rr = {RefreshRate, (int)addindex};
188   refreshrates.push_back(rr);
189 }
190
191 static bool rrSortPredicate(REFRESHRATE i, REFRESHRATE j)
192 {
193   return (i.RefreshRate < j.RefreshRate);
194 }
195
196 vector<REFRESHRATE> CWinSystemBase::RefreshRates(int screen, int width, int height, uint32_t dwFlags)
197 {
198   vector<REFRESHRATE> refreshrates;
199
200   for (unsigned int idx = RES_DESKTOP; idx < CDisplaySettings::Get().ResolutionInfoSize(); idx++)
201     if (   CDisplaySettings::Get().GetResolutionInfo(idx).iScreen == screen
202         && CDisplaySettings::Get().GetResolutionInfo(idx).iScreenWidth  == width
203         && CDisplaySettings::Get().GetResolutionInfo(idx).iScreenHeight == height
204         && (CDisplaySettings::Get().GetResolutionInfo(idx).dwFlags & D3DPRESENTFLAG_MODEMASK) == (dwFlags & D3DPRESENTFLAG_MODEMASK))
205       AddRefreshRate(refreshrates, idx);
206
207   // Can't assume a sort order
208   sort(refreshrates.begin(), refreshrates.end(), rrSortPredicate);
209
210   return refreshrates;
211 }
212
213 REFRESHRATE CWinSystemBase::DefaultRefreshRate(int screen, vector<REFRESHRATE> rates)
214 {
215   REFRESHRATE bestmatch = rates[0];
216   float bestfitness = -1.0f;
217   float targetfps = CDisplaySettings::Get().GetResolutionInfo(DesktopResolution(screen)).fRefreshRate;
218
219   for (unsigned i = 0; i < rates.size(); i++)
220   {
221     float fitness = fabs(targetfps - rates[i].RefreshRate);
222
223     if (bestfitness <0 || fitness < bestfitness)
224     {
225       bestfitness = fitness;
226       bestmatch = rates[i];
227       if (bestfitness == 0.0f) // perfect match
228         break;
229     }
230   }
231   return bestmatch;
232 }
233
234 bool CWinSystemBase::UseLimitedColor()
235 {
236 #if defined(HAS_GL) || defined(HAS_DX)
237   static CSettingBool* setting = (CSettingBool*)CSettings::Get().GetSetting("videoscreen.limitedrange");
238   return setting->GetValue();
239 #else
240   return false;
241 #endif
242 }
243
244 std::string CWinSystemBase::GetClipboardText(void)
245 {
246   return "";
247 }