2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
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"
30 CWinSystemBase::CWinSystemBase()
32 m_eWindowSystem = WINDOW_SYSTEM_WIN32; // this is the 0 value enum
37 m_bWindowCreated = false;
38 m_bFullScreen = false;
40 m_bBlankOtherDisplay = false;
41 m_fRefreshRate = 0.0f;
44 CWinSystemBase::~CWinSystemBase()
49 bool CWinSystemBase::InitWindowSystem()
52 CDisplaySettings::Get().ApplyCalibrations();
56 void CWinSystemBase::UpdateDesktopResolution(RESOLUTION_INFO& newRes, int screen, int width, int height, float refreshRate, uint32_t dwFlags)
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);
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";
82 newRes.strMode = StringUtils::Format("%s #%d", newRes.strMode.c_str(), screen + 1);
84 newRes.strMode += " - Full Screen";
87 void CWinSystemBase::UpdateResolutions()
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)
94 if (window.iHeight == 0)
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";
104 void CWinSystemBase::SetWindowResolution(int width, int height)
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);
115 int CWinSystemBase::DesktopResolution(int screen)
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
124 static void AddResolution(vector<RESOLUTION_WHR> &resolutions, unsigned int addindex, float bestRefreshrate)
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;
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)
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;
144 // no need to add the resolution again
148 RESOLUTION_WHR res = {width, height, flags, (int)addindex};
149 resolutions.push_back(res);
152 static bool resSortPredicate(RESOLUTION_WHR i, RESOLUTION_WHR j)
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) );
161 vector<RESOLUTION_WHR> CWinSystemBase::ScreenResolutions(int screen, float refreshrate)
163 vector<RESOLUTION_WHR> resolutions;
165 for (unsigned int idx = RES_DESKTOP; idx < CDisplaySettings::Get().ResolutionInfoSize(); idx++)
167 RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(idx);
168 if (info.iScreen == screen)
169 AddResolution(resolutions, idx, refreshrate);
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);
179 static void AddRefreshRate(vector<REFRESHRATE> &refreshrates, unsigned int addindex)
181 float RefreshRate = CDisplaySettings::Get().GetResolutionInfo(addindex).fRefreshRate;
183 for (unsigned int idx = 0; idx < refreshrates.size(); idx++)
184 if ( refreshrates[idx].RefreshRate == RefreshRate)
185 return; // already taken care of.
187 REFRESHRATE rr = {RefreshRate, (int)addindex};
188 refreshrates.push_back(rr);
191 static bool rrSortPredicate(REFRESHRATE i, REFRESHRATE j)
193 return (i.RefreshRate < j.RefreshRate);
196 vector<REFRESHRATE> CWinSystemBase::RefreshRates(int screen, int width, int height, uint32_t dwFlags)
198 vector<REFRESHRATE> refreshrates;
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);
207 // Can't assume a sort order
208 sort(refreshrates.begin(), refreshrates.end(), rrSortPredicate);
213 REFRESHRATE CWinSystemBase::DefaultRefreshRate(int screen, vector<REFRESHRATE> rates)
215 REFRESHRATE bestmatch = rates[0];
216 float bestfitness = -1.0f;
217 float targetfps = CDisplaySettings::Get().GetResolutionInfo(DesktopResolution(screen)).fRefreshRate;
219 for (unsigned i = 0; i < rates.size(); i++)
221 float fitness = fabs(targetfps - rates[i].RefreshRate);
223 if (bestfitness <0 || fitness < bestfitness)
225 bestfitness = fitness;
226 bestmatch = rates[i];
227 if (bestfitness == 0.0f) // perfect match
234 bool CWinSystemBase::UseLimitedColor()
236 #if defined(HAS_GL) || defined(HAS_DX)
237 static CSettingBool* setting = (CSettingBool*)CSettings::Get().GetSetting("videoscreen.limitedrange");
238 return setting->GetValue();
244 std::string CWinSystemBase::GetClipboardText(void)