Merge pull request #2231 from stupid-boy/CpuFreq
[vuplus_xbmc] / xbmc / settings / DisplaySettings.cpp
1 /*
2  *      Copyright (C) 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 <float.h>
22 #include <stdlib.h>
23
24 #include "DisplaySettings.h"
25 #include "dialogs/GUIDialogYesNo.h"
26 #include "guilib/GraphicContext.h"
27 #include "guilib/gui3d.h"
28 #include "guilib/LocalizeStrings.h"
29 #include "guilib/StereoscopicsManager.h"
30 #include "settings/AdvancedSettings.h"
31 #include "settings/Setting.h"
32 #include "settings/Settings.h"
33 #include "threads/SingleLock.h"
34 #include "utils/log.h"
35 #include "utils/StringUtils.h"
36 #include "utils/XMLUtils.h"
37 #include "windowing/WindowingFactory.h"
38
39 // 0.1 second increments
40 #define MAX_REFRESH_CHANGE_DELAY 200
41
42 using namespace std;
43
44 static RESOLUTION_INFO EmptyResolution;
45 static RESOLUTION_INFO EmptyModifiableResolution;
46
47 float square_error(float x, float y)
48 {
49   float yonx = (x > 0) ? y / x : 0;
50   float xony = (y > 0) ? x / y : 0;
51   return std::max(yonx, xony);
52 }
53
54 static CStdString ModeFlagsToString(unsigned int flags, bool identifier)
55 {
56   CStdString res;
57   if(flags & D3DPRESENTFLAG_INTERLACED)
58     res += "i";
59   else
60     res += "p";
61
62   if(!identifier)
63     res += " ";
64
65   if(flags & D3DPRESENTFLAG_MODE3DSBS)
66     res += "sbs";
67   else if(flags & D3DPRESENTFLAG_MODE3DTB)
68     res += "tab";
69   else if(identifier)
70     res += "std";
71   return res;
72 }
73
74 CDisplaySettings::CDisplaySettings()
75 {
76   m_resolutions.insert(m_resolutions.begin(), RES_CUSTOM, RESOLUTION_INFO());
77
78   m_zoomAmount = 1.0f;
79   m_pixelRatio = 1.0f;
80   m_verticalShift = 0.0f;
81   m_nonLinearStretched = false;
82   m_resolutionChangeAborted = false;
83 }
84
85 CDisplaySettings::~CDisplaySettings()
86 { }
87
88 CDisplaySettings& CDisplaySettings::Get()
89 {
90   static CDisplaySettings sDisplaySettings;
91   return sDisplaySettings;
92 }
93
94 bool CDisplaySettings::Load(const TiXmlNode *settings)
95 {
96   CSingleLock lock(m_critical);
97   m_calibrations.clear();
98
99   if (settings == NULL)
100     return false;
101
102   const TiXmlElement *pElement = settings->FirstChildElement("resolutions");
103   if (!pElement)
104   {
105     CLog::Log(LOGERROR, "CDisplaySettings: settings file doesn't contain <resolutions>");
106     return false;
107   }
108
109   const TiXmlElement *pResolution = pElement->FirstChildElement("resolution");
110   while (pResolution)
111   {
112     // get the data for this calibration
113     RESOLUTION_INFO cal;
114
115     XMLUtils::GetString(pResolution, "description", cal.strMode);
116     XMLUtils::GetInt(pResolution, "subtitles", cal.iSubtitles);
117     XMLUtils::GetFloat(pResolution, "pixelratio", cal.fPixelRatio);
118 #ifdef HAS_XRANDR
119     XMLUtils::GetFloat(pResolution, "refreshrate", cal.fRefreshRate);
120     XMLUtils::GetString(pResolution, "output", cal.strOutput);
121     XMLUtils::GetString(pResolution, "xrandrid", cal.strId);
122 #endif
123
124     const TiXmlElement *pOverscan = pResolution->FirstChildElement("overscan");
125     if (pOverscan)
126     {
127       XMLUtils::GetInt(pOverscan, "left", cal.Overscan.left);
128       XMLUtils::GetInt(pOverscan, "top", cal.Overscan.top);
129       XMLUtils::GetInt(pOverscan, "right", cal.Overscan.right);
130       XMLUtils::GetInt(pOverscan, "bottom", cal.Overscan.bottom);
131     }
132
133     // mark calibration as not updated
134     // we must not delete those, resolution just might not be available
135     cal.iWidth = cal.iHeight = 0;
136
137     // store calibration, avoid adding duplicates
138     bool found = false;
139     for (ResolutionInfos::const_iterator  it = m_calibrations.begin(); it != m_calibrations.end(); ++it)
140     {
141       if (it->strMode.Equals(cal.strMode))
142       {
143         found = true;
144         break;
145       }
146     }
147     if (!found)
148       m_calibrations.push_back(cal);
149
150     // iterate around
151     pResolution = pResolution->NextSiblingElement("resolution");
152   }
153
154   ApplyCalibrations();
155   return true;
156 }
157
158 bool CDisplaySettings::Save(TiXmlNode *settings) const
159 {
160   if (settings == NULL)
161     return false;
162
163   CSingleLock lock(m_critical);
164   TiXmlElement xmlRootElement("resolutions");
165   TiXmlNode *pRoot = settings->InsertEndChild(xmlRootElement);
166   if (pRoot == NULL)
167     return false;
168
169   // save calibrations
170   for (ResolutionInfos::const_iterator it = m_calibrations.begin(); it != m_calibrations.end(); ++it)
171   {
172     // Write the resolution tag
173     TiXmlElement resElement("resolution");
174     TiXmlNode *pNode = pRoot->InsertEndChild(resElement);
175     if (pNode == NULL)
176       return false;
177
178     // Now write each of the pieces of information we need...
179     XMLUtils::SetString(pNode, "description", it->strMode);
180     XMLUtils::SetInt(pNode, "subtitles", it->iSubtitles);
181     XMLUtils::SetFloat(pNode, "pixelratio", it->fPixelRatio);
182 #ifdef HAS_XRANDR
183     XMLUtils::SetFloat(pNode, "refreshrate", it->fRefreshRate);
184     XMLUtils::SetString(pNode, "output", it->strOutput);
185     XMLUtils::SetString(pNode, "xrandrid", it->strId);
186 #endif
187
188     // create the overscan child
189     TiXmlElement overscanElement("overscan");
190     TiXmlNode *pOverscanNode = pNode->InsertEndChild(overscanElement);
191     if (pOverscanNode == NULL)
192       return false;
193
194     XMLUtils::SetInt(pOverscanNode, "left", it->Overscan.left);
195     XMLUtils::SetInt(pOverscanNode, "top", it->Overscan.top);
196     XMLUtils::SetInt(pOverscanNode, "right", it->Overscan.right);
197     XMLUtils::SetInt(pOverscanNode, "bottom", it->Overscan.bottom);
198   }
199
200   return true;
201 }
202
203 void CDisplaySettings::Clear()
204 {
205   CSingleLock lock(m_critical);
206   m_calibrations.clear();
207   m_resolutions.clear();
208
209   m_zoomAmount = 1.0f;
210   m_pixelRatio = 1.0f;
211   m_verticalShift = 0.0f;
212   m_nonLinearStretched = false;
213 }
214
215 bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
216 {
217   if (setting == NULL)
218     return false;
219
220   const std::string &settingId = setting->GetId();
221   if (settingId == "videoscreen.resolution" ||
222       settingId == "videoscreen.screen")
223   {
224     RESOLUTION newRes = RES_DESKTOP;
225     if (settingId == "videoscreen.resolution")
226       newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue();
227     else if (settingId == "videoscreen.screen")
228       newRes = GetResolutionForScreen();
229
230     string screenmode = GetStringFromResolution(newRes);
231     CSettings::Get().SetString("videoscreen.screenmode", screenmode);
232   }
233   if (settingId == "videoscreen.screenmode")
234   {
235     RESOLUTION oldRes = GetCurrentResolution();
236     RESOLUTION newRes = GetResolutionFromString(((CSettingString*)setting)->GetValue());
237
238     SetCurrentResolution(newRes, false);
239     g_graphicsContext.SetVideoResolution(newRes);
240
241     // check if the old or the new resolution was/is windowed
242     // in which case we don't show any prompt to the user
243     if (oldRes != RES_WINDOW && newRes != RES_WINDOW)
244     {
245       if (!m_resolutionChangeAborted)
246       {
247         bool cancelled = false;
248         if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000))
249         {
250           m_resolutionChangeAborted = true;
251           return false;
252         }
253       }
254       else
255         m_resolutionChangeAborted = false;
256     }
257   }
258
259   return true;
260 }
261
262 bool CDisplaySettings::OnSettingUpdate(CSetting* &setting, const char *oldSettingId, const TiXmlNode *oldSettingNode)
263 {
264   if (setting == NULL)
265     return false;
266
267   const std::string &settingId = setting->GetId();
268   if (settingId == "videoscreen.screenmode")
269   {
270     CSettingString *screenmodeSetting = (CSettingString*)setting;
271     std::string screenmode = screenmodeSetting->GetValue();
272     // in Eden there was no character ("i" or "p") indicating interlaced/progressive
273     // at the end so we just add a "p" and assume progressive
274     // no 3d mode existed before, so just assume std modes
275     if (screenmode.size() == 20)
276       return screenmodeSetting->SetValue(screenmode + "pstd");
277     if (screenmode.size() == 21)
278       return screenmodeSetting->SetValue(screenmode + "std");
279   }
280
281   return false;
282 }
283
284 void CDisplaySettings::SetCurrentResolution(RESOLUTION resolution, bool save /* = false */)
285 {
286   if (save)
287   {
288     string mode = GetStringFromResolution(resolution);
289     CSettings::Get().SetString("videoscreen.screenmode", mode.c_str());
290   }
291
292   m_currentResolution = resolution;
293
294   SetChanged();
295 }
296
297 RESOLUTION CDisplaySettings::GetDisplayResolution() const
298 {
299   return GetResolutionFromString(CSettings::Get().GetString("videoscreen.screenmode"));
300 }
301
302 const RESOLUTION_INFO& CDisplaySettings::GetResolutionInfo(size_t index) const
303 {
304   CSingleLock lock(m_critical);
305   if (index >= m_resolutions.size())
306     return EmptyResolution;
307
308   return m_resolutions[index];
309 }
310
311 const RESOLUTION_INFO& CDisplaySettings::GetResolutionInfo(RESOLUTION resolution) const
312 {
313   if (resolution <= RES_INVALID)
314     return EmptyResolution;
315
316   return GetResolutionInfo((size_t)resolution);
317 }
318
319 RESOLUTION_INFO& CDisplaySettings::GetResolutionInfo(size_t index)
320 {
321   CSingleLock lock(m_critical);
322   if (index >= m_resolutions.size())
323   {
324     EmptyModifiableResolution = RESOLUTION_INFO();
325     return EmptyModifiableResolution;
326   }
327
328   return m_resolutions[index];
329 }
330
331 RESOLUTION_INFO& CDisplaySettings::GetResolutionInfo(RESOLUTION resolution)
332 {
333   if (resolution <= RES_INVALID)
334   {
335     EmptyModifiableResolution = RESOLUTION_INFO();
336     return EmptyModifiableResolution;
337   }
338
339   return GetResolutionInfo((size_t)resolution);
340 }
341
342 void CDisplaySettings::AddResolutionInfo(const RESOLUTION_INFO &resolution)
343 {
344   CSingleLock lock(m_critical);
345   RESOLUTION_INFO res(resolution);
346
347   if((res.dwFlags & D3DPRESENTFLAG_MODE3DTB) == 0)
348   {
349     /* add corrections for some special case modes frame packing modes */
350
351     if(res.iScreenWidth  == 1920
352     && res.iScreenHeight == 2205)
353     {
354       res.iBlanking = 45;
355       res.dwFlags  |= D3DPRESENTFLAG_MODE3DTB;
356     }
357
358     if(res.iScreenWidth  == 1280
359     && res.iScreenHeight == 1470)
360     {
361       res.iBlanking = 30;
362       res.dwFlags  |= D3DPRESENTFLAG_MODE3DTB;
363     }
364   }
365   m_resolutions.push_back(res);
366 }
367
368 void CDisplaySettings::ApplyCalibrations()
369 {
370   CSingleLock lock(m_critical);
371   // apply all calibrations to the resolutions
372   for (ResolutionInfos::const_iterator itCal = m_calibrations.begin(); itCal != m_calibrations.end(); ++itCal)
373   {
374     // find resolutions
375     for (size_t res = 0; res < m_resolutions.size(); ++res)
376     {
377       if (res == RES_WINDOW)
378         continue;
379       if (itCal->strMode.Equals(m_resolutions[res].strMode))
380       {
381         // overscan
382         m_resolutions[res].Overscan.left = itCal->Overscan.left;
383         if (m_resolutions[res].Overscan.left < -m_resolutions[res].iWidth/4)
384           m_resolutions[res].Overscan.left = -m_resolutions[res].iWidth/4;
385         if (m_resolutions[res].Overscan.left > m_resolutions[res].iWidth/4)
386           m_resolutions[res].Overscan.left = m_resolutions[res].iWidth/4;
387
388         m_resolutions[res].Overscan.top = itCal->Overscan.top;
389         if (m_resolutions[res].Overscan.top < -m_resolutions[res].iHeight/4)
390           m_resolutions[res].Overscan.top = -m_resolutions[res].iHeight/4;
391         if (m_resolutions[res].Overscan.top > m_resolutions[res].iHeight/4)
392           m_resolutions[res].Overscan.top = m_resolutions[res].iHeight/4;
393
394         m_resolutions[res].Overscan.right = itCal->Overscan.right;
395         if (m_resolutions[res].Overscan.right < m_resolutions[res].iWidth / 2)
396           m_resolutions[res].Overscan.right = m_resolutions[res].iWidth / 2;
397         if (m_resolutions[res].Overscan.right > m_resolutions[res].iWidth * 3/2)
398           m_resolutions[res].Overscan.right = m_resolutions[res].iWidth *3/2;
399
400         m_resolutions[res].Overscan.bottom = itCal->Overscan.bottom;
401         if (m_resolutions[res].Overscan.bottom < m_resolutions[res].iHeight / 2)
402           m_resolutions[res].Overscan.bottom = m_resolutions[res].iHeight / 2;
403         if (m_resolutions[res].Overscan.bottom > m_resolutions[res].iHeight * 3/2)
404           m_resolutions[res].Overscan.bottom = m_resolutions[res].iHeight * 3/2;
405
406         m_resolutions[res].iSubtitles = itCal->iSubtitles;
407         if (m_resolutions[res].iSubtitles < m_resolutions[res].iHeight / 2)
408           m_resolutions[res].iSubtitles = m_resolutions[res].iHeight / 2;
409         if (m_resolutions[res].iSubtitles > m_resolutions[res].iHeight* 5/4)
410           m_resolutions[res].iSubtitles = m_resolutions[res].iHeight* 5/4;
411
412         m_resolutions[res].fPixelRatio = itCal->fPixelRatio;
413         if (m_resolutions[res].fPixelRatio < 0.5f)
414           m_resolutions[res].fPixelRatio = 0.5f;
415         if (m_resolutions[res].fPixelRatio > 2.0f)
416           m_resolutions[res].fPixelRatio = 2.0f;
417         break;
418       }
419     }
420   }
421 }
422
423 void CDisplaySettings::UpdateCalibrations()
424 {
425   CSingleLock lock(m_critical);
426   for (size_t res = RES_DESKTOP; res < m_resolutions.size(); ++res)
427   {
428     // find calibration
429     bool found = false;
430     for (ResolutionInfos::iterator itCal = m_calibrations.begin(); itCal != m_calibrations.end(); ++itCal)
431     {
432       if (itCal->strMode.Equals(m_resolutions[res].strMode))
433       {
434         // TODO: erase calibrations with default values
435         *itCal = m_resolutions[res];
436         found = true;
437         break;
438       }
439     }
440
441     if (!found)
442       m_calibrations.push_back(m_resolutions[res]);
443   }
444 }
445
446 DisplayMode CDisplaySettings::GetCurrentDisplayMode() const
447 {
448   if (GetCurrentResolution() == RES_WINDOW)
449     return DM_WINDOWED;
450
451   return GetCurrentResolutionInfo().iScreen;
452 }
453
454 RESOLUTION CDisplaySettings::FindBestMatchingResolution(const std::map<RESOLUTION, RESOLUTION_INFO> &resolutionInfos, int screen, int width, int height, float refreshrate, unsigned flags)
455 {
456   // find the closest match to these in our res vector.  If we have the screen, we score the res
457   RESOLUTION bestRes = RES_DESKTOP;
458   float bestScore = FLT_MAX;
459   flags &= D3DPRESENTFLAG_MODEMASK;
460
461   for (std::map<RESOLUTION, RESOLUTION_INFO>::const_iterator it = resolutionInfos.begin(); it != resolutionInfos.end(); ++it)
462   {
463     const RESOLUTION_INFO &info = it->second;
464
465     if ( info.iScreen               != screen
466     ||  (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != flags)
467       continue;
468
469     float score = 10 * (square_error((float)info.iScreenWidth, (float)width) +
470                   square_error((float)info.iScreenHeight, (float)height) +
471                   square_error(info.fRefreshRate, refreshrate));
472     if (score < bestScore)
473     {
474       bestScore = score;
475       bestRes = it->first;
476     }
477   }
478
479   return bestRes;
480 }
481
482 RESOLUTION CDisplaySettings::GetResolutionFromString(const std::string &strResolution)
483 {
484   if (strResolution == "DESKTOP")
485     return RES_DESKTOP;
486   else if (strResolution == "WINDOW")
487     return RES_WINDOW;
488   else if (strResolution.size() >= 21)
489   {
490     // format: SWWWWWHHHHHRRR.RRRRRP333, where S = screen, W = width, H = height, R = refresh, P = interlace, 3 = stereo mode
491     int screen = strtol(StringUtils::Mid(strResolution, 0,1).c_str(), NULL, 10);
492     int width = strtol(StringUtils::Mid(strResolution, 1,5).c_str(), NULL, 10);
493     int height = strtol(StringUtils::Mid(strResolution, 6,5).c_str(), NULL, 10);
494     float refresh = (float)strtod(StringUtils::Mid(strResolution, 11,9).c_str(), NULL);
495     unsigned flags = 0;
496
497     // look for 'i' and treat everything else as progressive,
498     if(StringUtils::Mid(strResolution, 20,1) == "i")
499       flags |= D3DPRESENTFLAG_INTERLACED;
500
501     if(StringUtils::Mid(strResolution, 21,3) == "sbs")
502       flags |= D3DPRESENTFLAG_MODE3DSBS;
503     else if(StringUtils::Mid(strResolution, 21,3) == "tab")
504       flags |= D3DPRESENTFLAG_MODE3DTB;
505
506     std::map<RESOLUTION, RESOLUTION_INFO> resolutionInfos;
507     for (size_t resolution = RES_DESKTOP; resolution < CDisplaySettings::Get().ResolutionInfoSize(); resolution++)
508       resolutionInfos.insert(make_pair((RESOLUTION)resolution, CDisplaySettings::Get().GetResolutionInfo(resolution)));
509
510     return FindBestMatchingResolution(resolutionInfos, screen, width, height, refresh, flags);
511   }
512
513   return RES_DESKTOP;
514 }
515
516 std::string CDisplaySettings::GetStringFromResolution(RESOLUTION resolution, float refreshrate /* = 0.0f */)
517 {
518   if (resolution == RES_WINDOW)
519     return "WINDOW";
520
521   if (resolution >= RES_DESKTOP && resolution < (RESOLUTION)CDisplaySettings::Get().ResolutionInfoSize())
522   {
523     const RESOLUTION_INFO &info = CDisplaySettings::Get().GetResolutionInfo(resolution);
524     // also handle RES_DESKTOP resolutions with non-default refresh rates
525     if (resolution != RES_DESKTOP || (refreshrate > 0.0f && refreshrate != info.fRefreshRate))
526     {
527       return StringUtils::Format("%1i%05i%05i%09.5f%s", info.iScreen,
528                                  info.iScreenWidth, info.iScreenHeight,
529                                  refreshrate > 0.0f ? refreshrate : info.fRefreshRate, ModeFlagsToString(info.dwFlags, true).c_str());
530     }
531   }
532
533   return "DESKTOP";
534 }
535
536 RESOLUTION CDisplaySettings::GetResolutionForScreen()
537 {
538   DisplayMode mode = CSettings::Get().GetInt("videoscreen.screen");
539   if (mode == DM_WINDOWED)
540     return RES_WINDOW;
541
542   for (int idx=0; idx < g_Windowing.GetNumScreens(); idx++)
543   {
544     if (CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP + idx).iScreen == mode)
545       return (RESOLUTION)(RES_DESKTOP + idx);
546   }
547
548   return RES_DESKTOP;
549 }
550
551 void CDisplaySettings::SettingOptionsRefreshChangeDelaysFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
552 {
553   list.push_back(make_pair(g_localizeStrings.Get(13551), 0));
554           
555   for (int i = 1; i <= MAX_REFRESH_CHANGE_DELAY; i++)
556     list.push_back(make_pair(StringUtils::Format(g_localizeStrings.Get(13553).c_str(), (double)i / 10.0), i));
557 }
558
559 void CDisplaySettings::SettingOptionsRefreshRatesFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current)
560 {
561   // get the proper resolution
562   RESOLUTION res = CDisplaySettings::Get().GetDisplayResolution();
563   if (res < RES_WINDOW)
564     return;
565
566   // only add "Windowed" if in windowed mode
567   if (res == RES_WINDOW)
568   {
569     current = "WINDOW";
570     list.push_back(make_pair(g_localizeStrings.Get(242), current));
571     return;
572   }
573
574   RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(res);
575   // The only meaningful parts of res here are iScreen, iScreenWidth, iScreenHeight
576   vector<REFRESHRATE> refreshrates = g_Windowing.RefreshRates(resInfo.iScreen, resInfo.iScreenWidth, resInfo.iScreenHeight, resInfo.dwFlags);
577
578   bool match = false;
579   for (vector<REFRESHRATE>::const_iterator refreshrate = refreshrates.begin(); refreshrate != refreshrates.end(); ++refreshrate)
580   {
581     std::string screenmode = GetStringFromResolution((RESOLUTION)refreshrate->ResInfo_Index, refreshrate->RefreshRate);
582     if (!match && StringUtils::EqualsNoCase(((CSettingString*)setting)->GetValue(), screenmode))
583       match = true;
584     list.push_back(make_pair(StringUtils::Format("%.02f", refreshrate->RefreshRate), screenmode));
585   }
586
587   if (!match)
588     current = GetStringFromResolution(res, g_Windowing.DefaultRefreshRate(resInfo.iScreen, refreshrates).RefreshRate);
589 }
590
591 void CDisplaySettings::SettingOptionsResolutionsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
592 {
593   RESOLUTION res = CDisplaySettings::Get().GetDisplayResolution();
594   RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(res);
595   if (res == RES_WINDOW)
596   {
597     current = res;
598     list.push_back(make_pair(g_localizeStrings.Get(242), res));
599   }
600   else
601   {
602     std::map<RESOLUTION, RESOLUTION_INFO> resolutionInfos;
603     vector<RESOLUTION_WHR> resolutions = g_Windowing.ScreenResolutions(info.iScreen, info.fRefreshRate);
604     for (vector<RESOLUTION_WHR>::const_iterator resolution = resolutions.begin(); resolution != resolutions.end(); ++resolution)
605     {
606       list.push_back(make_pair(
607         StringUtils::Format("%dx%d%s", resolution->width, resolution->height,
608                             ModeFlagsToString(resolution->flags, false).c_str()),
609                             resolution->ResInfo_Index));
610
611       resolutionInfos.insert(make_pair((RESOLUTION)resolution->ResInfo_Index, CDisplaySettings::Get().GetResolutionInfo(resolution->ResInfo_Index)));
612     }
613
614     current = FindBestMatchingResolution(resolutionInfos, info.iScreen,
615                                          info.iScreenWidth, info.iScreenHeight,
616                                          info.fRefreshRate, info.dwFlags);
617   }
618 }
619
620 void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
621 {
622   if (g_advancedSettings.m_canWindowed)
623     list.push_back(make_pair(g_localizeStrings.Get(242), DM_WINDOWED));
624
625   for (int idx = 0; idx < g_Windowing.GetNumScreens(); idx++)
626   {
627     int screen = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP + idx).iScreen;
628     list.push_back(make_pair(StringUtils::Format(g_localizeStrings.Get(241), screen + 1), screen));
629   }
630
631   RESOLUTION res = CDisplaySettings::Get().GetDisplayResolution();
632   if (res == RES_WINDOW)
633     current = DM_WINDOWED;
634   else
635   {
636     RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(res);
637     current = resInfo.iScreen;
638   }
639 }
640
641 void CDisplaySettings::SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
642 {
643 #if defined(TARGET_POSIX) && !defined(TARGET_DARWIN)
644   list.push_back(make_pair(g_localizeStrings.Get(13101), VSYNC_DRIVER));
645 #endif
646   list.push_back(make_pair(g_localizeStrings.Get(13106), VSYNC_DISABLED));
647   list.push_back(make_pair(g_localizeStrings.Get(13107), VSYNC_VIDEO));
648   list.push_back(make_pair(g_localizeStrings.Get(13108), VSYNC_ALWAYS));
649 }
650
651 void CDisplaySettings::SettingOptionsStereoscopicModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
652 {
653   for (int i = RENDER_STEREO_MODE_OFF; i < RENDER_STEREO_MODE_COUNT; i++)
654   {
655     RENDER_STEREO_MODE mode = (RENDER_STEREO_MODE) i;
656     if (g_Windowing.SupportsStereo(mode))
657       list.push_back(make_pair(CStereoscopicsManager::Get().GetLabelForStereoMode(mode), mode));
658   }
659 }
660
661 void CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
662 {
663   SettingOptionsStereoscopicModesFiller(setting, list, current);
664   list.push_back(make_pair(g_localizeStrings.Get(36525), RENDER_STEREO_MODE_AUTO)); // option for autodetect
665 }