diff options
-rw-r--r-- | system/settings/darwin_osx.xml | 2 | ||||
-rwxr-xr-x | system/settings/settings.xml | 17 | ||||
-rw-r--r-- | xbmc/settings/DisplaySettings.cpp | 26 | ||||
-rw-r--r-- | xbmc/settings/DisplaySettings.h | 1 | ||||
-rw-r--r-- | xbmc/settings/SettingConditions.cpp | 3 | ||||
-rw-r--r-- | xbmc/windowing/WinSystem.cpp | 5 | ||||
-rw-r--r-- | xbmc/windowing/osx/WinSystemOSX.h | 6 | ||||
-rw-r--r-- | xbmc/windowing/osx/WinSystemOSX.mm | 166 |
8 files changed, 130 insertions, 96 deletions
diff --git a/system/settings/darwin_osx.xml b/system/settings/darwin_osx.xml index b48031c2aa..5d73f3be53 100644 --- a/system/settings/darwin_osx.xml +++ b/system/settings/darwin_osx.xml @@ -10,5 +10,3 @@ </category> </section> </settings> - - diff --git a/system/settings/settings.xml b/system/settings/settings.xml index ca8a28caf6..c4035f1435 100755 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -789,33 +789,33 @@ <!-- Hidden settings edited using CGUIDialogMusicExportSettings --> <setting id="musiclibrary.exportfiletype" type="integer" label="38304" help=""> <level>4</level> - <default>0</default> + <default>0</default> </setting> <setting id="musiclibrary.exportfolder" type="string" label="38305" help=""> - <level>4</level> + <level>4</level> <default></default> <constraints> <allowempty>true</allowempty> </constraints> </setting> <setting id="musiclibrary.exportitems" type="integer" label="" help=""> - <level>4</level> + <level>4</level> <default>48</default> <!-- Albums + Album Artists --> </setting> <setting id="musiclibrary.exportunscraped" type="boolean" label="" help=""> - <level>4</level> + <level>4</level> <default>false</default> </setting> <setting id="musiclibrary.exportoverwrite" type="boolean" label="" help=""> - <level>4</level> + <level>4</level> <default>false</default> </setting> <setting id="musiclibrary.exportartwork" type="boolean" label="" help=""> - <level>4</level> + <level>4</level> <default>false</default> - </setting> + </setting> <setting id="musiclibrary.exportskipnfo" type="boolean" label="" help=""> - <level>4</level> + <level>4</level> <default>false</default> </setting> <setting id="musiclibrary.import" type="action" label="14249" help="36263"> @@ -1993,6 +1993,7 @@ <or> <condition>HAVE_X11</condition> <condition>HAVE_WAYLAND</condition> + <condition>HAVE_OSX</condition> </or> </requirement> <level>0</level> diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp index 806e3fb4ea..cc4586f7ab 100644 --- a/xbmc/settings/DisplaySettings.cpp +++ b/xbmc/settings/DisplaySettings.cpp @@ -50,6 +50,8 @@ #if defined(HAVE_X11) #include "windowing/X11/WinSystemX11.h" +#elif defined(TARGET_DARWIN_OSX) +#include "windowing/osx/WinSystemOSX.h" #elif defined(HAVE_WAYLAND) #include "windowing/wayland/WinSystemWayland.h" #endif @@ -384,6 +386,16 @@ bool CDisplaySettings::OnSettingUpdate(std::shared_ptr<CSetting> setting, const return false; } +void CDisplaySettings::SetMonitor(std::string monitor) +{ + std::string curMonitor = CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR); + if (curMonitor != monitor) + { + m_resolutionChangeAborted = true; + CServiceBroker::GetSettings().SetString(CSettings::SETTING_VIDEOSCREEN_MONITOR, monitor); + } +} + void CDisplaySettings::SetCurrentResolution(RESOLUTION resolution, bool save /* = false */) { if (resolution == RES_WINDOW && !CServiceBroker::GetWinSystem()->CanDoWindowed()) @@ -763,18 +775,13 @@ void CDisplaySettings::SettingOptionsScreensFiller(SettingConstPtr setting, std: if (g_advancedSettings.m_canWindowed && CServiceBroker::GetWinSystem()->CanDoWindowed()) list.push_back(std::make_pair(g_localizeStrings.Get(242), DM_WINDOWED)); -#if defined(HAVE_X11) || defined(HAVE_WAYLAND) +#if defined(HAVE_X11) || defined(HAVE_WAYLAND) || defined(TARGET_DARWIN_OSX) list.push_back(std::make_pair(g_localizeStrings.Get(244), 0)); #else for (int idx = 0; idx < CServiceBroker::GetWinSystem()->GetNumScreens(); idx++) { int screen = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP + idx).iScreen; -#if defined(TARGET_DARWIN_OSX) - if (!CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP + idx).strOutput.empty()) - list.push_back(std::make_pair(CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP + idx).strOutput, screen)); - else -#endif list.push_back(std::make_pair(StringUtils::Format(g_localizeStrings.Get(241).c_str(), screen + 1), screen)); } @@ -822,9 +829,14 @@ void CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller(Settin void CDisplaySettings::SettingOptionsMonitorsFiller(SettingConstPtr setting, std::vector< std::pair<std::string, std::string> > &list, std::string ¤t, void *data) { -#if defined(HAVE_X11) +#if defined(HAVE_X11) || defined(TARGET_DARWIN_OSX) std::vector<std::string> monitors; + +#if defined(HAVE_X11) CWinSystemX11 *winSystem = dynamic_cast<CWinSystemX11*>(CServiceBroker::GetWinSystem()); +#elif defined(TARGET_DARWIN_OSX) + CWinSystemOSX *winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem()); +#endif winSystem->GetConnectedOutputs(&monitors); std::string currentMonitor = CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR); for (unsigned int i=0; i<monitors.size(); ++i) diff --git a/xbmc/settings/DisplaySettings.h b/xbmc/settings/DisplaySettings.h index f03d9f6061..5b1a8395a7 100644 --- a/xbmc/settings/DisplaySettings.h +++ b/xbmc/settings/DisplaySettings.h @@ -91,6 +91,7 @@ public: void SetVerticalShift(float verticalShift) { m_verticalShift = verticalShift; } bool IsNonLinearStretched() const { return m_nonLinearStretched; } void SetNonLinearStretched(bool nonLinearStretch) { m_nonLinearStretched = nonLinearStretch; } + void SetMonitor(std::string monitor); static void SettingOptionsModesFiller(std::shared_ptr<const CSetting> setting, std::vector< std::pair<std::string, std::string> > &list, std::string ¤t, void *data); static void SettingOptionsRefreshChangeDelaysFiller(std::shared_ptr<const CSetting> setting, std::vector< std::pair<std::string, int> > &list, int ¤t, void *data); diff --git a/xbmc/settings/SettingConditions.cpp b/xbmc/settings/SettingConditions.cpp index 70d995e019..9223d7f8fc 100644 --- a/xbmc/settings/SettingConditions.cpp +++ b/xbmc/settings/SettingConditions.cpp @@ -329,6 +329,9 @@ void CSettingConditions::Initialize(const CProfilesManager &profileManager) #ifdef TARGET_DARWIN m_simpleConditions.insert("HasVTB"); #endif +#ifdef TARGET_DARWIN_OSX + m_simpleConditions.insert("have_osx"); +#endif #ifdef HAS_LIBAMCODEC if (aml_present()) m_simpleConditions.insert("have_amcodec"); diff --git a/xbmc/windowing/WinSystem.cpp b/xbmc/windowing/WinSystem.cpp index 2402d8dd3c..0afd2c0e6a 100644 --- a/xbmc/windowing/WinSystem.cpp +++ b/xbmc/windowing/WinSystem.cpp @@ -168,7 +168,7 @@ std::vector<RESOLUTION_WHR> CWinSystemBase::ScreenResolutions(int screen, float { std::vector<RESOLUTION_WHR> resolutions; - for (unsigned int idx = RES_DESKTOP; idx < CDisplaySettings::GetInstance().ResolutionInfoSize(); idx++) + for (unsigned int idx = RES_CUSTOM; idx < CDisplaySettings::GetInstance().ResolutionInfoSize(); idx++) { RESOLUTION_INFO info = CDisplaySettings::GetInstance().GetResolutionInfo(idx); if (info.iScreen == screen) @@ -176,8 +176,7 @@ std::vector<RESOLUTION_WHR> CWinSystemBase::ScreenResolutions(int screen, float } // Can't assume a sort order - // don't touch RES_DESKTOP which is index 0 - sort(resolutions.begin()+1, resolutions.end(), resSortPredicate); + sort(resolutions.begin(), resolutions.end(), resSortPredicate); return resolutions; } diff --git a/xbmc/windowing/osx/WinSystemOSX.h b/xbmc/windowing/osx/WinSystemOSX.h index 01d579aea5..1211e44141 100644 --- a/xbmc/windowing/osx/WinSystemOSX.h +++ b/xbmc/windowing/osx/WinSystemOSX.h @@ -64,9 +64,6 @@ public: void Register(IDispResource *resource) override; void Unregister(IDispResource *resource) override; - virtual int GetNumScreens() override; - virtual int GetCurrentScreen() override; - virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override; void WindowChangedScreen(); @@ -79,6 +76,7 @@ public: void* GetCGLContextObj(); void* GetNSOpenGLContext(); + void GetConnectedOutputs(std::vector<std::string> *outputs); // winevents override bool MessagePump() override; @@ -91,7 +89,7 @@ protected: void* CreateFullScreenContext(int screen_index, void* shareCtx); void GetScreenResolution(int* w, int* h, double* fps, int screenIdx); void EnableVSync(bool enable); - bool SwitchToVideoMode(int width, int height, double refreshrate, int screenIdx); + bool SwitchToVideoMode(int width, int height, double refreshrate); void FillInVideoModes(); bool FlushBuffer(void); bool IsObscured(void); diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm index 3e3dcd9b63..a14b9796ac 100644 --- a/xbmc/windowing/osx/WinSystemOSX.mm +++ b/xbmc/windowing/osx/WinSystemOSX.mm @@ -387,16 +387,41 @@ NSString* screenNameForDisplay(CGDirectDisplayID displayID) NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName); NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; - if ([localizedNames count] > 0) { - screenName = [[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] retain]; + if ([localizedNames count] > 0) + { + screenName = [[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] retain]; } [deviceInfo release]; [pool release]; + if (screenName == nil) + { + screenName = [NSString stringWithFormat:@"%i", displayID]; + } return [screenName autorelease]; } +int GetDisplayIndex(std::string dispName) +{ + int ret = 0; + + // Add full screen settings for additional monitors + int numDisplays = [[NSScreen screens] count]; + + for (int disp = 0; disp < numDisplays; disp++) + { + NSString *name = screenNameForDisplay(GetDisplayID(disp)); + if ([name UTF8String] == dispName) + { + ret = disp; + break; + } + } + + return ret; +} + void ShowHideNSWindow(NSWindow *wind, bool show) { if (show) @@ -771,8 +796,7 @@ bool CWinSystemOSX::CreateNewWindow(const std::string& name, bool fullScreen, RE // get screen refreshrate - this is needed // when we startup in windowed mode and don't run through SetFullScreen int dummy; - m_lastDisplayNr = resInfo.iScreen; - GetScreenResolution(&dummy, &dummy, &m_refreshRate, GetCurrentScreen()); + GetScreenResolution(&dummy, &dummy, &m_refreshRate, m_lastDisplayNr); // register platform dependent objects CDVDFactoryCodec::ClearHWAccels(); @@ -824,7 +848,20 @@ bool CWinSystemOSX::ResizeWindow(int newWidth, int newHeight, int newLeft, int n window = [view window]; if (window) { - [window setContentSize:NSMakeSize(newWidth, newHeight)]; + int curScreenIdx = GetDisplayIndex(GetDisplayIDFromScreen([window screen])); + int userScreenIdx = GetDisplayIndex(CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR)); + + if (curScreenIdx != userScreenIdx) + { + NSScreen* pScreen = [[NSScreen screens] objectAtIndex:userScreenIdx]; + NSRect visibleRect = [pScreen visibleFrame]; + [window setFrame:NSMakeRect(visibleRect.origin.x, visibleRect.origin.y, newWidth, newHeight) display:YES]; + } + else + { + [window setContentSize:NSMakeSize(newWidth, newHeight)]; + } + [window update]; [view setFrameSize:NSMakeSize(newWidth, newHeight)]; [context update]; @@ -866,8 +903,7 @@ bool CWinSystemOSX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl bool was_fullscreen = m_bFullScreen; NSOpenGLContext* cur_context; - if (m_lastDisplayNr == -1) - m_lastDisplayNr = res.iScreen; + m_lastDisplayNr = GetDisplayIndex(CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR)); // Fade to black to hide resolution-switching flicker and garbage. CGDisplayFadeReservationToken fade_token = DisplayFadeToBlack(needtoshowme); @@ -897,8 +933,7 @@ bool CWinSystemOSX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl if (m_can_display_switch) { // switch videomode - SwitchToVideoMode(res.iWidth, res.iHeight, res.fRefreshRate, res.iScreen); - m_lastDisplayNr = res.iScreen; + SwitchToVideoMode(res.iWidth, res.iHeight, res.fRefreshRate); } } @@ -1035,7 +1070,7 @@ bool CWinSystemOSX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl [NSCursor unhide]; // Show menubar. - if (GetDisplayID(res.iScreen) == kCGDirectMainDisplay || CDarwinUtils::IsMavericksOrHigher() ) + if (GetDisplayID(m_lastDisplayNr) == kCGDirectMainDisplay || CDarwinUtils::IsMavericksOrHigher() ) SetMenuBarVisible(true); if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOSCREEN_FAKEFULLSCREEN)) @@ -1113,37 +1148,15 @@ void CWinSystemOSX::UpdateResolutions() int w, h; double fps; - // first screen goes into the current desktop mode - GetScreenResolution(&w, &h, &fps, 0); + int dispIdx = GetDisplayIndex(CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR)); + GetScreenResolution(&w, &h, &fps, dispIdx); UpdateDesktopResolution(CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP), 0, w, h, fps); - NSString *dispName = screenNameForDisplay(GetDisplayID(0)); + NSString *dispName = screenNameForDisplay(GetDisplayID(dispIdx)); - if (dispName != nil) - { - CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).strOutput = [dispName UTF8String]; - } + CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).strOutput = [dispName UTF8String]; CDisplaySettings::GetInstance().ClearCustomResolutions(); - // see resolution.h enum RESOLUTION for how the resolutions - // have to appear in the resolution info vector in CDisplaySettings - // add the desktop resolutions of the other screens - for(int i = 1; i < GetNumScreens(); i++) - { - RESOLUTION_INFO res; - // get current resolution of screen i - GetScreenResolution(&w, &h, &fps, i); - UpdateDesktopResolution(res, i, w, h, fps); - dispName = screenNameForDisplay(GetDisplayID(i)); - - if (dispName != nil) - { - res.strOutput = [dispName UTF8String]; - } - - CDisplaySettings::GetInstance().AddResolutionInfo(res); - } - if (m_can_display_switch) { // now just fill in the possible resolutions for the attached screens @@ -1289,9 +1302,6 @@ void* CWinSystemOSX::CreateFullScreenContext(int screen_index, void* shareCtx) void CWinSystemOSX::GetScreenResolution(int* w, int* h, double* fps, int screenIdx) { - // Figure out the screen size. (default to main screen) - if (screenIdx >= GetNumScreens()) - return; CGDirectDisplayID display_id = (CGDirectDisplayID)GetDisplayID(screenIdx); CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display_id); *w = CGDisplayModeGetWidth(mode); @@ -1312,15 +1322,13 @@ void CWinSystemOSX::EnableVSync(bool enable) [[NSOpenGLContext currentContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; } -bool CWinSystemOSX::SwitchToVideoMode(int width, int height, double refreshrate, int screenIdx) +bool CWinSystemOSX::SwitchToVideoMode(int width, int height, double refreshrate) { - // SwitchToVideoMode will not return until the display has actually switched over. - // This can take several seconds. - if( screenIdx >= GetNumScreens()) - return false; - boolean_t match = false; CGDisplayModeRef dispMode = NULL; + + int screenIdx = GetDisplayIndex(CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR)); + // Figure out the screen size. (default to main screen) CGDirectDisplayID display_id = GetDisplayID(screenIdx); @@ -1372,11 +1380,16 @@ bool CWinSystemOSX::SwitchToVideoMode(int width, int height, double refreshrate, void CWinSystemOSX::FillInVideoModes() { + int dispIdx = GetDisplayIndex(CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR)); + // Add full screen settings for additional monitors int numDisplays = [[NSScreen screens] count]; for (int disp = 0; disp < numDisplays; disp++) { + if (disp != dispIdx) + continue; + Boolean stretched; Boolean interlaced; Boolean safeForHardware; @@ -1388,10 +1401,7 @@ void CWinSystemOSX::FillInVideoModes() CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(GetDisplayID(disp), nullptr); NSString *dispName = screenNameForDisplay(GetDisplayID(disp)); - if (dispName != nil) - { - CLog::Log(LOGNOTICE, "Display %i has name %s", disp, [dispName UTF8String]); - } + CLog::Log(LOGNOTICE, "Display %i has name %s", disp, [dispName UTF8String]); if (NULL == displayModes) continue; @@ -1407,9 +1417,9 @@ void CWinSystemOSX::FillInVideoModes() safeForHardware = flags & kDisplayModeSafetyFlags ? true : false; televisionoutput = flags & kDisplayModeTelevisionFlag ? true : false; - if ((bitsperpixel == 32) && - (safeForHardware == YES) && - (stretched == NO) && + if ((bitsperpixel == 32) && + (safeForHardware == YES) && + (stretched == NO) && (interlaced == NO)) { w = CGDisplayModeGetWidth(displayMode); @@ -1422,7 +1432,12 @@ void CWinSystemOSX::FillInVideoModes() } CLog::Log(LOGNOTICE, "Found possible resolution for display %d with %d x %d @ %f Hz\n", disp, w, h, refreshrate); - UpdateDesktopResolution(res, disp, w, h, refreshrate); + if (dispName != nil) + { + res.strOutput = [dispName UTF8String]; + } + + UpdateDesktopResolution(res, 0, w, h, refreshrate); // overwrite the mode str because UpdateDesktopResolution adds a // "Full Screen". Since the current resolution is there twice @@ -1436,11 +1451,6 @@ void CWinSystemOSX::FillInVideoModes() // the same resolution twice... - thats why i add a FIXME here. res.strMode = StringUtils::Format("%dx%d @ %.2f", w, h, refreshrate); - if (dispName != nil) - { - res.strOutput = [dispName UTF8String]; - } - CServiceBroker::GetWinSystem()->GetGfxContext().ResetOverscan(res); CDisplaySettings::GetInstance().AddResolutionInfo(res); } @@ -1685,7 +1695,7 @@ void CWinSystemOSX::HandlePossibleRefreshrateChange() Cocoa_CVDisplayLinkUpdate(); int dummy = 0; - GetScreenResolution(&dummy, &dummy, &m_refreshRate, GetCurrentScreen()); + GetScreenResolution(&dummy, &dummy, &m_refreshRate, m_lastDisplayNr); if (oldRefreshRate != m_refreshRate) { @@ -1772,17 +1782,6 @@ bool CWinSystemOSX::Show(bool raise) return true; } -int CWinSystemOSX::GetNumScreens() -{ - int numDisplays = [[NSScreen screens] count]; - return(numDisplays); -} - -int CWinSystemOSX::GetCurrentScreen() -{ - return m_lastDisplayNr; -} - void CWinSystemOSX::WindowChangedScreen() { // user has moved the window to a @@ -1803,7 +1802,17 @@ void CWinSystemOSX::WindowChangedScreen() window = [view window]; if (window) { - m_lastDisplayNr = GetDisplayIndex(GetDisplayIDFromScreen( [window screen] )); + m_lastDisplayNr = GetDisplayIndex(GetDisplayIDFromScreen([window screen])); + std::string curMonitor = CServiceBroker::GetSettings().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR); + if (curMonitor != "Default") + { + NSString *dispName = screenNameForDisplay(GetDisplayID(m_lastDisplayNr)); + if (curMonitor != [dispName UTF8String]) + { + CDisplaySettings::GetInstance().SetMonitor([dispName UTF8String]); + UpdateResolutions(); + } + } } } } @@ -1840,7 +1849,7 @@ void CWinSystemOSX::AnnounceOnResetDevice() double currentFps = m_refreshRate; int w = 0; int h = 0; - int currentScreenIdx = GetCurrentScreen(); + int currentScreenIdx = m_lastDisplayNr; // ensure that graphics context knows about the current refreshrate before // doing the callbacks GetScreenResolution(&w, &h, ¤tFps, currentScreenIdx); @@ -1885,3 +1894,16 @@ bool CWinSystemOSX::MessagePump() { return m_winEvents->MessagePump(); } + +void CWinSystemOSX::GetConnectedOutputs(std::vector<std::string> *outputs) +{ + outputs->push_back("Default"); + + int numDisplays = [[NSScreen screens] count]; + + for (int disp = 0; disp < numDisplays; disp++) + { + NSString *dispName = screenNameForDisplay(GetDisplayID(disp)); + outputs->push_back([dispName UTF8String]); + } +} |