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