const DisplayResVector& DisplayResOSX::GetVideoModes() const { if (m_video_modes.size()) return m_video_modes; CGDirectDisplayID d = GetOSXDisplay(MythDisplay::GetWindowID()); CFArrayRef displayModes = CGDisplayAvailableModes(d); if (NULL == displayModes) return m_video_modes; DisplayResMap screen_map; for (int i=0; i<CFArrayGetCount(displayModes); ++i) { CFDictionaryRef displayMode = (CFDictionaryRef) CFArrayGetValueAtIndex(displayModes, i); int width = get_int_CF(displayMode, kCGDisplayWidth); int height = get_int_CF(displayMode, kCGDisplayHeight); int refresh = get_int_CF(displayMode, kCGDisplayRefreshRate); uint64_t key = DisplayResScreen::CalcKey(width, height, 0.0); if (screen_map.find(key)==screen_map.end()) screen_map[key] = DisplayResScreen(width, height, 0, 0, -1.0, (double) refresh); else screen_map[key].AddRefreshRate(refresh); } //CFRelease(displayModes); // this release causes a segfault DisplayResMapCIt it = screen_map.begin(); for (; screen_map.end() != it; ++it) m_video_modes.push_back(it->second); return m_video_modes; }
const DisplayResVector& DisplayResX::GetVideoModes(void) const { if (!m_videoModes.empty()) return m_videoModes; MythXDisplay *display = NULL; XRRScreenConfiguration *cfg = GetScreenConfig(display); if (!cfg) return m_videoModes; int num_sizes, num_rates; XRRScreenSize *sizes = NULL; sizes = XRRConfigSizes(cfg, &num_sizes); for (int i = 0; i < num_sizes; ++i) { short *rates = NULL; rates = XRRRates(display->GetDisplay(), display->GetScreen(), i, &num_rates); DisplayResScreen scr(sizes[i].width, sizes[i].height, sizes[i].mwidth, sizes[i].mheight, rates, num_rates); m_videoModes.push_back(scr); } t_screenrate screenmap; int nvidiarate = GetNvidiaRates(screenmap); if (nvidiarate > 0) { // Update existing DisplayResScreen vector, and update it with // new frequencies for (uint i = 0; i < m_videoModes.size(); i++) { DisplayResScreen scr = m_videoModes[i]; int w = scr.Width(); int h = scr.Height(); int mw = scr.Width_mm(); int mh = scr.Height_mm(); std::vector<double> newrates; std::map<double, short> realRates; const std::vector<double>& rates = scr.RefreshRates(); bool found = false; for (std::vector<double>::const_iterator it = rates.begin(); it != rates.end(); ++it) { uint64_t key = DisplayResScreen::CalcKey(w, h, *it); if (screenmap.find(key) != screenmap.end()) { // Rate is defined in NV-CONTROL extension, use it newrates.push_back(screenmap[key]); realRates[screenmap[key]] = (int) round(*it); found = true; #if 0 LOG(VB_PLAYBACK, LOG_INFO, QString("CustomRate Found, set %1x%2@%3 as %4Hz") .arg(w) .arg(h) .arg(*it) .arg(screenmap[key])); #endif } } if (found) { m_videoModes.erase(m_videoModes.begin() + i); std::sort(newrates.begin(), newrates.end()); m_videoModes.insert(m_videoModes.begin() + i, DisplayResScreen(w, h, mw, mh, newrates, realRates)); } } } m_videoModesUnsorted = m_videoModes; std::sort(m_videoModes.begin(), m_videoModes.end()); XRRFreeScreenConfigInfo(cfg); delete display; return m_videoModes; }