diff options
478 files changed, 9339 insertions, 5841 deletions
diff --git a/.gitignore b/.gitignore index 61f534aca4..88753aaea0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ testMain *.sublime-* # KDevelop 4 *.kdev4 +# gedit +*~ # generated files etc config.cache @@ -91,9 +93,9 @@ config.log /Makefile.depend /config.status /configure -/xbmc.bin -/xbmc-test -/xbmc-xrandr +/kodi.bin +/kodi-test +/kodi-xrandr /git_revision.h /libtool /*.patch @@ -337,6 +339,7 @@ lib/cpluff/stamp-h1 /project/output # /project/cmake +/project/cmake/kodi-config.cmake /project/cmake/xbmc-config.cmake /project/cmake/*.error /project/cmake/addons/build @@ -450,9 +453,16 @@ lib/cpluff/stamp-h1 # /skin/Confluence/ /skin/Confluence/BUILD -# +#/tools/android /tools/android/packaging/xbmc/AndroidManifest.xml -/tools/darwin/packaging/xbmc-osx/mkdmg-xbmc-osx.sh +/tools/android/packaging/Makefile +/tools/android/packaging/xbmc/src/org/xbmc/kodi/Main.java +/tools/android/packaging/xbmc/src/org/xbmc/kodi/Splash.java +/tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCBroadcastReceiver.java +/tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCOnFrameAvailableListener.java +/tools/android/packaging/xbmc/strings.xml + +#/tools/depends /tools/depends/native/JsonSchemaBuilder/bin/ /tools/depends/native/JsonSchemaBuilder/native/ /tools/depends/target/ffmpeg/.ffmpeg-installed @@ -462,6 +472,7 @@ lib/cpluff/stamp-h1 # /tools/EventClients/ /tools/EventClients/*.pyc +/tools/EventClients/Makefile /tools/EventClients/Clients/OSXRemote/Makefile /tools/EventClients/Clients/OSXRemote/build/ /tools/EventClients/Clients/WiiRemote/WiiRemote @@ -469,12 +480,18 @@ lib/cpluff/stamp-h1 # /tools/darwin/ /tools/darwin/Configurations/App.xcconfig /tools/darwin/Configurations/Common.xcconfig -/tools/darwin/packaging/xbmc-ios/mkdeb-xbmc-ios.sh -/tools/darwin/packaging/xbmc-atv2/mkdeb-xbmc-atv2.sh +/tools/darwin/packaging/ios/mkdeb-ios.sh +/tools/darwin/packaging/atv2/mkdeb-atv2.sh +/tools/darwin/packaging/osx/mkdmg-osx.sh +/tools/darwin/packaging/migrate_to_kodi_ios.sh +/tools/darwin/packaging/seatbeltunlock/mkdeb-seatbeltunlock.sh # /tools/Linux/ -/tools/Linux/xbmc.sh -/tools/Linux/xbmc-standalone.sh +/tools/Linux/kodi.sh +/tools/Linux/kodi-standalone.sh +/tools/Linux/kodi-xsession.desktop +/tools/Linux/FEH-ARM.py +/tools/Linux/FEH.py # /tools/osx /tools/osx/XBMCHelper @@ -582,6 +599,8 @@ lib/cpluff/stamp-h1 # /xbmc/osx/ /xbmc/osx/Makefile /xbmc/osx/Info.plist +/xbmc/osx/ios/XBMCIOS-Info.plist +/xbmc/osx/atv2/XBMCATV2-Info.plist # /xbmc/peripherals/ /xbmc/peripherals/bus/Makefile diff --git a/XBMC.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 4924acd4cf..bf49f6402f 100644 --- a/XBMC.xcodeproj/project.pbxproj +++ b/Kodi.xcodeproj/project.pbxproj @@ -7,9 +7,9 @@ objects = { /* Begin PBXAggregateTarget section */ - 6E2FACBA0E26DF7A00DF79EA /* XBMC.app */ = { + 6E2FACBA0E26DF7A00DF79EA /* Kodi.app */ = { isa = PBXAggregateTarget; - buildConfigurationList = 6E2FACC10E26DFA300DF79EA /* Build configuration list for PBXAggregateTarget "XBMC.app" */; + buildConfigurationList = 6E2FACC10E26DFA300DF79EA /* Build configuration list for PBXAggregateTarget "Kodi.app" */; buildPhases = ( F5DEC3580E6DEBB2005A4E24 /* copy root files */, 6E2FACC70E26E22400DF79EA /* copy frameworks */, @@ -19,8 +19,8 @@ dependencies = ( 6E2FACC40E26E08100DF79EA /* PBXTargetDependency */, ); - name = XBMC.app; - productName = XBMC.app; + name = Kodi.app; + productName = Kodi.app; }; /* End PBXAggregateTarget section */ @@ -1113,15 +1113,18 @@ AE84CB5A15A5B8A600A3810E /* TagLibVFSStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE84CB5915A5B8A600A3810E /* TagLibVFSStream.cpp */; }; AE89ACA61621DAB800E17DBC /* DVDDemuxBXA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE89ACA41621DAB800E17DBC /* DVDDemuxBXA.cpp */; }; AEC0083115ACAC6E0099888C /* TagLoaderTagLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEC0083015ACAC6E0099888C /* TagLoaderTagLib.cpp */; }; - B542632B197D353B00726998 /* PosixInterfaceForCLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5426329197D353B00726998 /* PosixInterfaceForCLog.cpp */; }; - B542632C197D353B00726998 /* PosixInterfaceForCLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5426329197D353B00726998 /* PosixInterfaceForCLog.cpp */; }; - B542632D197D353B00726998 /* PosixInterfaceForCLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5426329197D353B00726998 /* PosixInterfaceForCLog.cpp */; }; - B5011E4119AF3B56005ADF89 /* PosixFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */; }; - B5011E4219AF3B56005ADF89 /* PosixFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */; }; - B5011E4319AF3B56005ADF89 /* PosixFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */; }; B5011E3C19AA4989005ADF89 /* MarkWatchedJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3B19AA4989005ADF89 /* MarkWatchedJob.cpp */; }; B5011E3D19AA4989005ADF89 /* MarkWatchedJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3B19AA4989005ADF89 /* MarkWatchedJob.cpp */; }; B5011E3E19AA4989005ADF89 /* MarkWatchedJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3B19AA4989005ADF89 /* MarkWatchedJob.cpp */; }; + B5011E4119AF3B56005ADF89 /* PosixFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */; }; + B5011E4219AF3B56005ADF89 /* PosixFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */; }; + B5011E4319AF3B56005ADF89 /* PosixFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */; }; + B5101B5819DFF8DD00294D1E /* BlurayFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5101B5719DFF8DD00294D1E /* BlurayFile.cpp */; }; + B5101B5919DFF8E300294D1E /* BlurayFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5101B5719DFF8DD00294D1E /* BlurayFile.cpp */; }; + B5101B5A19DFF8E400294D1E /* BlurayFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5101B5719DFF8DD00294D1E /* BlurayFile.cpp */; }; + B542632B197D353B00726998 /* PosixInterfaceForCLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5426329197D353B00726998 /* PosixInterfaceForCLog.cpp */; }; + B542632C197D353B00726998 /* PosixInterfaceForCLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5426329197D353B00726998 /* PosixInterfaceForCLog.cpp */; }; + B542632D197D353B00726998 /* PosixInterfaceForCLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5426329197D353B00726998 /* PosixInterfaceForCLog.cpp */; }; C807114D135DB5CC002F601B /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C807114B135DB5CC002F601B /* InputOperations.cpp */; }; C84828C0156CFCD8005A996F /* PVRClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8482874156CFCD8005A996F /* PVRClient.cpp */; }; C84828C1156CFCD8005A996F /* PVRClients.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8482876156CFCD8005A996F /* PVRClients.cpp */; }; @@ -1197,6 +1200,9 @@ DF28EDA7170E1A11005FA9D2 /* ProfilesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF28ED9C170E1A11005FA9D2 /* ProfilesManager.cpp */; }; DF28EDA8170E1A11005FA9D2 /* GUIWindowSettingsProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF28ED9F170E1A11005FA9D2 /* GUIWindowSettingsProfile.cpp */; }; DF28EE03170E1E51005FA9D2 /* DisplaySettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF28EE01170E1E51005FA9D2 /* DisplaySettings.cpp */; }; + DF32466219E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF32466019E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp */; }; + DF32466319E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF32466019E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp */; }; + DF32466419E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF32466019E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp */; }; DF3488E713FD958F0026A711 /* GUIAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF3488E513FD958F0026A711 /* GUIAction.cpp */; }; DF34892A13FD9C780026A711 /* AirPlayServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF34892813FD9C780026A711 /* AirPlayServer.cpp */; }; DF34898213FDAAF60026A711 /* HttpParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF34898113FDAAF60026A711 /* HttpParser.cpp */; }; @@ -1205,6 +1211,8 @@ DF3C3C0E1752A7EE000989C3 /* IOSEAGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = E49910D7174E4A6400741B6D /* IOSEAGLView.mm */; }; DF3C3C0F1752A7EE000989C3 /* IOSExternalTouchController.mm in Sources */ = {isa = PBXBuildFile; fileRef = E49910D9174E4A6400741B6D /* IOSExternalTouchController.mm */; }; DF3C3C101752A7EE000989C3 /* IOSScreenManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = E49910DB174E4A6400741B6D /* IOSScreenManager.mm */; }; + DF3E5EFA199D41300039675D /* kodiclientwrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF3E5EF9199D41300039675D /* kodiclientwrapper.mm */; }; + DF3E5EFD199D4B340039675D /* KodiController.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF3E5EFC199D4B340039675D /* KodiController.mm */; }; DF402A581644613B001C56B8 /* AddonModuleXbmc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF1ACFD115FCE50700E10810 /* AddonModuleXbmc.cpp */; }; DF402A591644613B001C56B8 /* AddonModuleXbmcaddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF1ACFD515FCE50700E10810 /* AddonModuleXbmcaddon.cpp */; }; DF402A5A1644613B001C56B8 /* AddonModuleXbmcgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF1ACFD915FCE50700E10810 /* AddonModuleXbmcgui.cpp */; }; @@ -1277,6 +1285,9 @@ DF93D7F61444B568007C6459 /* HDHomeRunDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7F51444B568007C6459 /* HDHomeRunDirectory.cpp */; }; DF98D98C1434F47D00A6EBE1 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D98A1434F47D00A6EBE1 /* SkinVariable.cpp */; }; DF9A71EE1639C8F6005ECB2E /* HTTPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9A71EC1639C8F6005ECB2E /* HTTPFile.cpp */; }; + DFA0E8C519FD6BEE00269A92 /* VideoSyncCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA0E8C319FD6BEE00269A92 /* VideoSyncCocoa.cpp */; }; + DFA0E8C719FD7BD100269A92 /* VideoSyncCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA0E8C319FD6BEE00269A92 /* VideoSyncCocoa.cpp */; }; + DFA0E8C819FD7BD100269A92 /* VideoSyncCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA0E8C319FD6BEE00269A92 /* VideoSyncCocoa.cpp */; }; DFA8157E16713B1200E4E597 /* WakeOnAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA8157C16713B1200E4E597 /* WakeOnAccess.cpp */; }; DFAB049813F8376700B70BFB /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB049613F8376700B70BFB /* InertialScrollingHandler.cpp */; }; DFAF6A4F16EBAE3800D6AE12 /* RssManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAF6A4D16EBAE3800D6AE12 /* RssManager.cpp */; }; @@ -1332,6 +1343,8 @@ DFCA6ACB152245CD000BFAAE /* IHTTPRequestHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AC3152245CD000BFAAE /* IHTTPRequestHandler.cpp */; }; DFD5812516C828500008EEA0 /* DAVCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5812116C8284F0008EEA0 /* DAVCommon.cpp */; }; DFD5812616C828500008EEA0 /* DAVFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5812316C828500008EEA0 /* DAVFile.cpp */; }; + DFD7C7AD19D1DDA90071942C /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DFD7C7AB19D1DDA90071942C /* Default-667h@2x.png */; }; + DFD7C7AE19D1DDA90071942C /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DFD7C7AC19D1DDA90071942C /* Default-736h@3x.png */; }; DFD882E717DD189E001516FE /* StringValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD882E517DD189E001516FE /* StringValidation.cpp */; }; DFD882E817DD189E001516FE /* StringValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD882E517DD189E001516FE /* StringValidation.cpp */; }; DFD882E917DD189E001516FE /* StringValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD882E517DD189E001516FE /* StringValidation.cpp */; }; @@ -1341,6 +1354,9 @@ DFD928F316384B6800709DAE /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD928F116384B6800709DAE /* Timer.cpp */; }; DFDA3153160E34230047A626 /* DVDOverlayCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */; }; DFE4095B17417FDF00473BD9 /* LegacyPathTranslation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4095917417FDF00473BD9 /* LegacyPathTranslation.cpp */; }; + DFEB902819E9337200728978 /* AEResampleFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEB902619E9337200728978 /* AEResampleFactory.cpp */; }; + DFEB902919E9337200728978 /* AEResampleFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEB902619E9337200728978 /* AEResampleFactory.cpp */; }; + DFEB902A19E9337200728978 /* AEResampleFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEB902619E9337200728978 /* AEResampleFactory.cpp */; }; DFECFADF172D9C5100A43CF7 /* GUIControlSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFECFADD172D9C5100A43CF7 /* GUIControlSettings.cpp */; }; DFECFB09172D9CAB00A43CF7 /* SettingAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFECFAF4172D9CAB00A43CF7 /* SettingAddon.cpp */; }; DFECFB0C172D9CAB00A43CF7 /* SettingControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFECFAFA172D9CAB00A43CF7 /* SettingControl.cpp */; }; @@ -2243,11 +2259,8 @@ DFF0F48917528350002DA3A4 /* cc_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = E38E15350D25F9F900618676 /* cc_decoder.c */; }; DFF0F48A17528350002DA3A4 /* yuv2rgb.neon.S in Sources */ = {isa = PBXBuildFile; fileRef = E4991595174E70BF00741B6D /* yuv2rgb.neon.S */; }; DFF0F49D1752838E002DA3A4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DFF0F4901752838E002DA3A4 /* InfoPlist.strings */; }; - DFF0F49F1752838E002DA3A4 /* XBMCAppliance.mm in Sources */ = {isa = PBXBuildFile; fileRef = DFF0F4951752838E002DA3A4 /* XBMCAppliance.mm */; }; - DFF0F4A11752838E002DA3A4 /* xbmcclientwrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = DFF0F4991752838E002DA3A4 /* xbmcclientwrapper.mm */; }; - DFF0F4A21752838E002DA3A4 /* XBMCController.mm in Sources */ = {isa = PBXBuildFile; fileRef = DFF0F49B1752838E002DA3A4 /* XBMCController.mm */; }; + DFF1FE23199D2FFF0008211F /* KodiAppliance.mm in Sources */ = {isa = PBXBuildFile; fileRef = DFC8B7CE199C2B3A00424777 /* KodiAppliance.mm */; }; DFFA43FF19104C0800C3923B /* AppIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D019104BFA00C3923B /* AppIcon.png */; }; - DFFA440019104C0800C3923B /* XBMC.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D119104BFA00C3923B /* XBMC.png */; }; DFFA440119104C1300C3923B /* AppIcon29x29.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D619104BFA00C3923B /* AppIcon29x29.png */; }; DFFA440219104C1300C3923B /* AppIcon29x29@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D719104BFA00C3923B /* AppIcon29x29@2x.png */; }; DFFA440319104C1300C3923B /* AppIcon40x40.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D819104BFA00C3923B /* AppIcon40x40.png */; }; @@ -3619,19 +3632,16 @@ F5CC228F1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */; }; F5CC22DF1814FF3B006B5E91 /* ActiveAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */; }; F5CC22E01814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */; }; - F5CC22E11814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */; }; F5CC22E21814FF3B006B5E91 /* ActiveAESink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */; }; F5CC22E31814FF3B006B5E91 /* ActiveAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */; }; F5CC22E41814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */; }; F5CC22E51814FF3B006B5E91 /* ActiveAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */; }; F5CC22E61814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */; }; - F5CC22E71814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */; }; F5CC22E81814FF3B006B5E91 /* ActiveAESink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */; }; F5CC22E91814FF3B006B5E91 /* ActiveAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */; }; F5CC22EA1814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */; }; F5CC22EB1814FF3B006B5E91 /* ActiveAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */; }; F5CC22EC1814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */; }; - F5CC22ED1814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */; }; F5CC22EE1814FF3B006B5E91 /* ActiveAESink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */; }; F5CC22EF1814FF3B006B5E91 /* ActiveAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */; }; F5CC22F01814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */; }; @@ -3703,7 +3713,7 @@ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 8DD76F740486A8DE00D96B5E; - remoteInfo = XBMC; + remoteInfo = Kodi; }; /* End PBXContainerItemProxy section */ @@ -4642,7 +4652,7 @@ 88ACB01D0DCF409E0083CFDF /* ASAPCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASAPCodec.h; sourceTree = "<group>"; }; 88ACB01E0DCF409E0083CFDF /* DllASAP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DllASAP.h; sourceTree = "<group>"; }; 88ECB6580DE013C4003396A7 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = /System/Library/Frameworks/DiskArbitration.framework; sourceTree = "<absolute>"; }; - 8DD76F7E0486A8DE00D96B5E /* XBMC */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = XBMC; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DD76F7E0486A8DE00D96B5E /* Kodi */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Kodi; sourceTree = BUILT_PRODUCTS_DIR; }; AE4E87A517354C4A00D15206 /* XSLTUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XSLTUtils.cpp; sourceTree = "<group>"; }; AE4E87A617354C4A00D15206 /* XSLTUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XSLTUtils.h; sourceTree = "<group>"; }; AE84CB5915A5B8A600A3810E /* TagLibVFSStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TagLibVFSStream.cpp; sourceTree = "<group>"; }; @@ -4651,13 +4661,15 @@ AE89ACA51621DAB800E17DBC /* DVDDemuxBXA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDDemuxBXA.h; sourceTree = "<group>"; }; AEC0083015ACAC6E0099888C /* TagLoaderTagLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TagLoaderTagLib.cpp; sourceTree = "<group>"; }; AEC0083315ACAC7C0099888C /* TagLoaderTagLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagLoaderTagLib.h; sourceTree = "<group>"; }; - B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PosixFile.cpp; sourceTree = "<group>"; }; - B5011E4019AF3B56005ADF89 /* PosixFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PosixFile.h; sourceTree = "<group>"; }; B5011E3A19AA496D005ADF89 /* MarkWatchedJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkWatchedJob.h; sourceTree = "<group>"; }; B5011E3B19AA4989005ADF89 /* MarkWatchedJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkWatchedJob.cpp; sourceTree = "<group>"; }; - B542632E19917D3500726998 /* params_check_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = params_check_macros.h; sourceTree = "<group>"; }; + B5011E3F19AF3B56005ADF89 /* PosixFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PosixFile.cpp; sourceTree = "<group>"; }; + B5011E4019AF3B56005ADF89 /* PosixFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PosixFile.h; sourceTree = "<group>"; }; + B5101B5719DFF8DD00294D1E /* BlurayFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlurayFile.cpp; sourceTree = "<group>"; }; + B5101B5B19DFF8FC00294D1E /* BlurayFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlurayFile.h; sourceTree = "<group>"; }; B5426329197D353B00726998 /* PosixInterfaceForCLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PosixInterfaceForCLog.cpp; sourceTree = "<group>"; }; B542632A197D353B00726998 /* PosixInterfaceForCLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PosixInterfaceForCLog.h; sourceTree = "<group>"; }; + B542632E19917D3500726998 /* params_check_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = params_check_macros.h; sourceTree = "<group>"; }; C807114B135DB5CC002F601B /* InputOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputOperations.cpp; sourceTree = "<group>"; }; C807114C135DB5CC002F601B /* InputOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputOperations.h; sourceTree = "<group>"; }; C8482874156CFCD8005A996F /* PVRClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PVRClient.cpp; sourceTree = "<group>"; }; @@ -4866,6 +4878,8 @@ DF28EDA0170E1A11005FA9D2 /* GUIWindowSettingsProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowSettingsProfile.h; sourceTree = "<group>"; }; DF28EE01170E1E51005FA9D2 /* DisplaySettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisplaySettings.cpp; sourceTree = "<group>"; }; DF28EE02170E1E51005FA9D2 /* DisplaySettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplaySettings.h; sourceTree = "<group>"; }; + DF32466019E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAEResampleFFMPEG.cpp; sourceTree = "<group>"; }; + DF32466119E931A8005E8CFB /* ActiveAEResampleFFMPEG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAEResampleFFMPEG.h; sourceTree = "<group>"; }; DF3488E513FD958F0026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; }; DF3488E613FD958F0026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; }; DF34892813FD9C780026A711 /* AirPlayServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirPlayServer.cpp; sourceTree = "<group>"; }; @@ -4882,6 +4896,11 @@ DF3C3D1D1752BED3000989C3 /* genoutputdirlink.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = genoutputdirlink.command; sourceTree = "<group>"; }; DF3C3D1E1752BED3000989C3 /* makepythoninterface.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = makepythoninterface.command; sourceTree = "<group>"; }; DF3C3D1F1752BED3000989C3 /* updateversioninfo-osx.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "updateversioninfo-osx.command"; sourceTree = "<group>"; }; + DF3E5EF5199D400B0039675D /* kodiclientwrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kodiclientwrapper.h; sourceTree = "<group>"; }; + DF3E5EF8199D41300039675D /* kodiclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kodiclient.h; sourceTree = "<group>"; }; + DF3E5EF9199D41300039675D /* kodiclientwrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = kodiclientwrapper.mm; sourceTree = "<group>"; }; + DF3E5EFB199D4B340039675D /* KodiController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KodiController.h; sourceTree = "<group>"; }; + DF3E5EFC199D4B340039675D /* KodiController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KodiController.mm; sourceTree = "<group>"; }; DF404A3416B9896C00D8023E /* cximage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cximage.cpp; sourceTree = "<group>"; }; DF404A3516B9896C00D8023E /* cximage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cximage.h; sourceTree = "<group>"; }; DF404A3616B9896C00D8023E /* iimage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iimage.h; sourceTree = "<group>"; }; @@ -4996,6 +5015,9 @@ DF98D98B1434F47D00A6EBE1 /* SkinVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkinVariable.h; sourceTree = "<group>"; }; DF9A71EC1639C8F6005ECB2E /* HTTPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPFile.cpp; sourceTree = "<group>"; }; DF9A71ED1639C8F6005ECB2E /* HTTPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPFile.h; sourceTree = "<group>"; }; + DFA0E8C219FD6BEE00269A92 /* VideoSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoSync.h; path = videosync/VideoSync.h; sourceTree = "<group>"; }; + DFA0E8C319FD6BEE00269A92 /* VideoSyncCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VideoSyncCocoa.cpp; path = videosync/VideoSyncCocoa.cpp; sourceTree = "<group>"; }; + DFA0E8C419FD6BEE00269A92 /* VideoSyncCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoSyncCocoa.h; path = videosync/VideoSyncCocoa.h; sourceTree = "<group>"; }; DFA8157C16713B1200E4E597 /* WakeOnAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WakeOnAccess.cpp; sourceTree = "<group>"; }; DFA8157D16713B1200E4E597 /* WakeOnAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WakeOnAccess.h; sourceTree = "<group>"; }; DFAB049613F8376700B70BFB /* InertialScrollingHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InertialScrollingHandler.cpp; sourceTree = "<group>"; }; @@ -5038,6 +5060,9 @@ DFBB4317178B5E6F006CC20A /* CompileInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompileInfo.cpp; sourceTree = "<group>"; }; DFBB4318178B5E6F006CC20A /* CompileInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompileInfo.h; sourceTree = "<group>"; }; DFBE803D15F7D72100D7D102 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + DFC8B7CC199C1EC100424777 /* TopShelf.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TopShelf.png; sourceTree = "<group>"; }; + DFC8B7CD199C2B3A00424777 /* KodiAppliance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KodiAppliance.h; sourceTree = "<group>"; }; + DFC8B7CE199C2B3A00424777 /* KodiAppliance.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KodiAppliance.mm; sourceTree = "<group>"; }; DFCA6ABB152245CD000BFAAE /* HTTPJsonRpcHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPJsonRpcHandler.cpp; sourceTree = "<group>"; }; DFCA6ABC152245CD000BFAAE /* HTTPJsonRpcHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPJsonRpcHandler.h; sourceTree = "<group>"; }; DFCA6ABD152245CD000BFAAE /* HTTPVfsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPVfsHandler.cpp; sourceTree = "<group>"; }; @@ -5052,6 +5077,8 @@ DFD5812216C8284F0008EEA0 /* DAVCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAVCommon.h; sourceTree = "<group>"; }; DFD5812316C828500008EEA0 /* DAVFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DAVFile.cpp; sourceTree = "<group>"; }; DFD5812416C828500008EEA0 /* DAVFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAVFile.h; sourceTree = "<group>"; }; + DFD7C7AB19D1DDA90071942C /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = "<group>"; }; + DFD7C7AC19D1DDA90071942C /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = "<group>"; }; DFD882E517DD189E001516FE /* StringValidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringValidation.cpp; sourceTree = "<group>"; }; DFD882E617DD189E001516FE /* StringValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringValidation.h; sourceTree = "<group>"; }; DFD882F417DD1A5B001516FE /* AddonPythonInvoker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AddonPythonInvoker.cpp; path = python/AddonPythonInvoker.cpp; sourceTree = "<group>"; }; @@ -5061,6 +5088,9 @@ DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDOverlayCodec.cpp; sourceTree = "<group>"; }; DFE4095917417FDF00473BD9 /* LegacyPathTranslation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyPathTranslation.cpp; sourceTree = "<group>"; }; DFE4095A17417FDF00473BD9 /* LegacyPathTranslation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyPathTranslation.h; sourceTree = "<group>"; }; + DFEB902519E9335E00728978 /* AEResample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEResample.h; sourceTree = "<group>"; }; + DFEB902619E9337200728978 /* AEResampleFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AEResampleFactory.cpp; sourceTree = "<group>"; }; + DFEB902719E9337200728978 /* AEResampleFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEResampleFactory.h; sourceTree = "<group>"; }; DFECFADD172D9C5100A43CF7 /* GUIControlSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GUIControlSettings.cpp; path = windows/GUIControlSettings.cpp; sourceTree = "<group>"; }; DFECFADE172D9C5100A43CF7 /* GUIControlSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GUIControlSettings.h; path = windows/GUIControlSettings.h; sourceTree = "<group>"; }; DFECFAF4172D9CAB00A43CF7 /* SettingAddon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SettingAddon.cpp; sourceTree = "<group>"; }; @@ -5085,17 +5115,9 @@ DFF0ECA8175282EA002DA3A4 /* README.ios */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.ios; path = docs/README.ios; sourceTree = "<group>"; }; DFF0F4911752838E002DA3A4 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; DFF0F4921752838E002DA3A4 /* substrate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = substrate.h; sourceTree = "<group>"; }; - DFF0F4941752838E002DA3A4 /* XBMCAppliance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCAppliance.h; sourceTree = "<group>"; }; - DFF0F4951752838E002DA3A4 /* XBMCAppliance.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = XBMCAppliance.mm; sourceTree = "<group>"; }; DFF0F4961752838E002DA3A4 /* XBMCATV2-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "XBMCATV2-Info.plist"; sourceTree = "<group>"; }; - DFF0F4971752838E002DA3A4 /* xbmcclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbmcclient.h; sourceTree = "<group>"; }; - DFF0F4981752838E002DA3A4 /* xbmcclientwrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbmcclientwrapper.h; sourceTree = "<group>"; }; - DFF0F4991752838E002DA3A4 /* xbmcclientwrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = xbmcclientwrapper.mm; sourceTree = "<group>"; }; - DFF0F49A1752838E002DA3A4 /* XBMCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCController.h; sourceTree = "<group>"; }; - DFF0F49B1752838E002DA3A4 /* XBMCController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = XBMCController.mm; sourceTree = "<group>"; }; DFF0F49C1752838E002DA3A4 /* XBMCDebugHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCDebugHelpers.h; sourceTree = "<group>"; }; DFFA43D019104BFA00C3923B /* AppIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = AppIcon.png; sourceTree = "<group>"; }; - DFFA43D119104BFA00C3923B /* XBMC.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = XBMC.png; sourceTree = "<group>"; }; DFFA43D319104BFA00C3923B /* iTunesArtwork.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = iTunesArtwork.png; sourceTree = "<group>"; }; DFFA43D419104BFA00C3923B /* iTunesArtwork@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iTunesArtwork@2x.png"; sourceTree = "<group>"; }; DFFA43D619104BFA00C3923B /* AppIcon29x29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = AppIcon29x29.png; sourceTree = "<group>"; }; @@ -5136,7 +5158,7 @@ DFFA43FC19104BFA00C3923B /* icon_32x32@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_32x32@2x.png"; sourceTree = "<group>"; }; DFFA43FD19104BFA00C3923B /* icon_512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_512x512.png; sourceTree = "<group>"; }; DFFA43FE19104BFA00C3923B /* icon_512x512@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_512x512@2x.png"; sourceTree = "<group>"; }; - DFFC52CB17527B3100C937AB /* XBMC.frappliance */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XBMC.frappliance; sourceTree = BUILT_PRODUCTS_DIR; }; + DFFC52CB17527B3100C937AB /* Kodi.frappliance */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Kodi.frappliance; sourceTree = BUILT_PRODUCTS_DIR; }; E306D12C0DDF7B590052C2AD /* XBMCHelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XBMCHelper.cpp; sourceTree = "<group>"; }; E306D12D0DDF7B590052C2AD /* XBMCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCHelper.h; sourceTree = "<group>"; }; E33206370D5070AA00435CE3 /* DVDDemuxVobsub.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDDemuxVobsub.cpp; sourceTree = "<group>"; }; @@ -5204,7 +5226,6 @@ E38E14F50D25F9F900618676 /* SoLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoLoader.h; sourceTree = "<group>"; }; E38E14F60D25F9F900618676 /* DummyVideoPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DummyVideoPlayer.cpp; sourceTree = "<group>"; }; E38E14F70D25F9F900618676 /* DummyVideoPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DummyVideoPlayer.h; sourceTree = "<group>"; }; - E38E14FB0D25F9F900618676 /* dvd_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dvd_config.h; sourceTree = "<group>"; }; E38E14FC0D25F9F900618676 /* DVDAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDAudio.cpp; sourceTree = "<group>"; }; E38E14FD0D25F9F900618676 /* DVDAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDAudio.h; sourceTree = "<group>"; }; E38E14FE0D25F9F900618676 /* DVDClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDClock.cpp; sourceTree = "<group>"; }; @@ -5912,7 +5933,7 @@ E46F7C2B0F77219700C25D29 /* ZeroconfOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZeroconfOSX.h; sourceTree = "<group>"; }; E46F7C2C0F77219700C25D29 /* ZeroconfOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZeroconfOSX.cpp; sourceTree = "<group>"; }; E47252BF175115F9001C1AAA /* Codesign.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = Codesign.command; sourceTree = "<group>"; }; - E4991089174D0D2600741B6D /* XBMC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XBMC.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E4991089174D0D2600741B6D /* Kodi.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Kodi.app; sourceTree = BUILT_PRODUCTS_DIR; }; E499108B174D0D2600741B6D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; E499108D174D0D2600741B6D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; E499108F174D0D2600741B6D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; @@ -6177,8 +6198,6 @@ F5CC22D41814FF3B006B5E91 /* ActiveAE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAE.h; sourceTree = "<group>"; }; F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAEBuffer.cpp; sourceTree = "<group>"; }; F5CC22D61814FF3B006B5E91 /* ActiveAEBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAEBuffer.h; sourceTree = "<group>"; }; - F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAEResample.cpp; sourceTree = "<group>"; }; - F5CC22D81814FF3B006B5E91 /* ActiveAEResample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAEResample.h; sourceTree = "<group>"; }; F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAESink.cpp; sourceTree = "<group>"; }; F5CC22DA1814FF3B006B5E91 /* ActiveAESink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAESink.h; sourceTree = "<group>"; }; F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAESound.cpp; sourceTree = "<group>"; }; @@ -6365,7 +6384,7 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* XBMC */ = { + 08FB7794FE84155DC02AAC07 /* Kodi */ = { isa = PBXGroup; children = ( 08FB7795FE84155DC02AAC07 /* Source */, @@ -6376,7 +6395,7 @@ E499108A174D0D2600741B6D /* Frameworks */, 19C28FBDFE9D53C911CA2CBB /* Products */, ); - name = XBMC; + name = Kodi; sourceTree = "<group>"; }; 08FB7795FE84155DC02AAC07 /* Source */ = { @@ -6774,9 +6793,9 @@ 19C28FBDFE9D53C911CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 8DD76F7E0486A8DE00D96B5E /* XBMC */, - E4991089174D0D2600741B6D /* XBMC.app */, - DFFC52CB17527B3100C937AB /* XBMC.frappliance */, + 8DD76F7E0486A8DE00D96B5E /* Kodi */, + E4991089174D0D2600741B6D /* Kodi.app */, + DFFC52CB17527B3100C937AB /* Kodi.frappliance */, ); name = Products; sourceTree = "<group>"; @@ -7200,6 +7219,7 @@ isa = PBXGroup; children = ( 43FAC88612D6363B00F67914 /* dialogs */, + DFA0E8C619FD6BFC00269A92 /* videosync */, 43FAC88812D6364800F67914 /* windows */, 7C62F24010505BC7002AD2C1 /* Bookmark.cpp */, 7C62F24110505BC7002AD2C1 /* Bookmark.h */, @@ -8294,6 +8314,16 @@ path = view; sourceTree = "<group>"; }; + DFA0E8C619FD6BFC00269A92 /* videosync */ = { + isa = PBXGroup; + children = ( + DFA0E8C219FD6BEE00269A92 /* VideoSync.h */, + DFA0E8C319FD6BEE00269A92 /* VideoSyncCocoa.cpp */, + DFA0E8C419FD6BEE00269A92 /* VideoSyncCocoa.h */, + ); + name = videosync; + sourceTree = "<group>"; + }; DFB15B1F15F8FB8100CDF0DE /* osx */ = { isa = PBXGroup; children = ( @@ -8314,6 +8344,8 @@ F5CC22851814F7B5006B5E91 /* Sinks */, DFB65F6515373AE7006B8FF1 /* AEFactory.cpp */, DFB65F6615373AE7006B8FF1 /* AEFactory.h */, + DFEB902619E9337200728978 /* AEResampleFactory.cpp */, + DFEB902719E9337200728978 /* AEResampleFactory.h */, F5CC230A18150118006B5E91 /* AESinkFactory.cpp */, F5CC230B18150118006B5E91 /* AESinkFactory.h */, ); @@ -8342,6 +8374,7 @@ children = ( DFB65F8915373AE7006B8FF1 /* AE.h */, DFB65F8A15373AE7006B8FF1 /* AEEncoder.h */, + DFEB902519E9335E00728978 /* AEResample.h */, DFB65F8C15373AE7006B8FF1 /* AESink.h */, DFB65F8D15373AE7006B8FF1 /* AESound.h */, DFB65F8E15373AE7006B8FF1 /* AEStream.h */, @@ -8408,15 +8441,15 @@ isa = PBXGroup; children = ( DFF0F4901752838E002DA3A4 /* InfoPlist.strings */, + DFC8B7CD199C2B3A00424777 /* KodiAppliance.h */, + DFC8B7CE199C2B3A00424777 /* KodiAppliance.mm */, + DF3E5EF8199D41300039675D /* kodiclient.h */, + DF3E5EF5199D400B0039675D /* kodiclientwrapper.h */, + DF3E5EF9199D41300039675D /* kodiclientwrapper.mm */, + DF3E5EFB199D4B340039675D /* KodiController.h */, + DF3E5EFC199D4B340039675D /* KodiController.mm */, DFF0F4921752838E002DA3A4 /* substrate.h */, - DFF0F4941752838E002DA3A4 /* XBMCAppliance.h */, - DFF0F4951752838E002DA3A4 /* XBMCAppliance.mm */, DFF0F4961752838E002DA3A4 /* XBMCATV2-Info.plist */, - DFF0F4971752838E002DA3A4 /* xbmcclient.h */, - DFF0F4981752838E002DA3A4 /* xbmcclientwrapper.h */, - DFF0F4991752838E002DA3A4 /* xbmcclientwrapper.mm */, - DFF0F49A1752838E002DA3A4 /* XBMCController.h */, - DFF0F49B1752838E002DA3A4 /* XBMCController.mm */, DFF0F49C1752838E002DA3A4 /* XBMCDebugHelpers.h */, ); path = atv2; @@ -8436,8 +8469,8 @@ DFFA43CF19104BFA00C3923B /* atv2 */ = { isa = PBXGroup; children = ( + DFC8B7CC199C1EC100424777 /* TopShelf.png */, DFFA43D019104BFA00C3923B /* AppIcon.png */, - DFFA43D119104BFA00C3923B /* XBMC.png */, ); path = atv2; sourceTree = "<group>"; @@ -8765,7 +8798,6 @@ E38E15480D25F9F900618676 /* DVDDemuxers */, E38E15570D25F9FA00618676 /* DVDInputStreams */, E38E158E0D25F9FA00618676 /* DVDSubtitles */, - E38E14FB0D25F9F900618676 /* dvd_config.h */, E38E14FC0D25F9F900618676 /* DVDAudio.cpp */, E38E14FD0D25F9F900618676 /* DVDAudio.h */, E38E14FE0D25F9F900618676 /* DVDClock.cpp */, @@ -9103,6 +9135,8 @@ 88ACB01A0DCF40800083CFDF /* ASAPFileDirectory.h */, F5ED8D6A1551F91400842059 /* BlurayDirectory.cpp */, F5ED8D6B1551F91400842059 /* BlurayDirectory.h */, + B5101B5719DFF8DD00294D1E /* BlurayFile.cpp */, + B5101B5B19DFF8FC00294D1E /* BlurayFile.h */, E38E16990D25F9FA00618676 /* CacheStrategy.cpp */, E38E169A0D25F9FA00618676 /* CacheStrategy.h */, E38E169B0D25F9FA00618676 /* CDDADirectory.cpp */, @@ -9889,6 +9923,8 @@ E49910A6174D0E2A00741B6D /* iOS */ = { isa = PBXGroup; children = ( + DFD7C7AB19D1DDA90071942C /* Default-667h@2x.png */, + DFD7C7AC19D1DDA90071942C /* Default-736h@3x.png */, E49910A7174D0E2A00741B6D /* Default-568h@2x.png */, E49910A8174D0E2A00741B6D /* InfoPlist.strings */, E49910AA174D0E2A00741B6D /* IOSKeyboard.h */, @@ -10161,8 +10197,8 @@ F5CC22D41814FF3B006B5E91 /* ActiveAE.h */, F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */, F5CC22D61814FF3B006B5E91 /* ActiveAEBuffer.h */, - F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */, - F5CC22D81814FF3B006B5E91 /* ActiveAEResample.h */, + DF32466019E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp */, + DF32466119E931A8005E8CFB /* ActiveAEResampleFFMPEG.h */, F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */, F5CC22DA1814FF3B006B5E91 /* ActiveAESink.h */, F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */, @@ -10265,9 +10301,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 8DD76F740486A8DE00D96B5E /* XBMC */ = { + 8DD76F740486A8DE00D96B5E /* Kodi */ = { isa = PBXNativeTarget; - buildConfigurationList = 1DEB924708733DCA0010E9CD /* Build configuration list for PBXNativeTarget "XBMC" */; + buildConfigurationList = 1DEB924708733DCA0010E9CD /* Build configuration list for PBXNativeTarget "Kodi" */; buildPhases = ( F502C011160F378F00C96C76 /* Make interface-python */, 8DD76F760486A8DE00D96B5E /* Sources */, @@ -10278,15 +10314,15 @@ ); dependencies = ( ); - name = XBMC; + name = Kodi; productInstallPath = "$(HOME)/bin"; - productName = XBMC; - productReference = 8DD76F7E0486A8DE00D96B5E /* XBMC */; + productName = Kodi; + productReference = 8DD76F7E0486A8DE00D96B5E /* Kodi */; productType = "com.apple.product-type.tool"; }; - DFFC52CA17527B3100C937AB /* XBMC-ATV2 */ = { + DFFC52CA17527B3100C937AB /* Kodi-ATV2 */ = { isa = PBXNativeTarget; - buildConfigurationList = DFFC52CE17527B4F00C937AB /* Build configuration list for PBXNativeTarget "XBMC-ATV2" */; + buildConfigurationList = DFFC52CE17527B4F00C937AB /* Build configuration list for PBXNativeTarget "Kodi-ATV2" */; buildPhases = ( DFFC52C617527B3100C937AB /* Resources */, DFF0EB3017527FDE002DA3A4 /* Make interface-python */, @@ -10300,14 +10336,14 @@ ); dependencies = ( ); - name = "XBMC-ATV2"; - productName = "XBMC-ATV2"; - productReference = DFFC52CB17527B3100C937AB /* XBMC.frappliance */; + name = "Kodi-ATV2"; + productName = "Kodi-ATV2"; + productReference = DFFC52CB17527B3100C937AB /* Kodi.frappliance */; productType = "com.apple.product-type.bundle"; }; - E4991088174D0D2600741B6D /* XBMC-iOS */ = { + E4991088174D0D2600741B6D /* Kodi-iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = E49910A5174D0D2600741B6D /* Build configuration list for PBXNativeTarget "XBMC-iOS" */; + buildConfigurationList = E49910A5174D0D2600741B6D /* Build configuration list for PBXNativeTarget "Kodi-iOS" */; buildPhases = ( E49910C1174D1F6600741B6D /* Make interface-python */, E4991085174D0D2600741B6D /* Sources */, @@ -10322,9 +10358,9 @@ ); dependencies = ( ); - name = "XBMC-iOS"; - productName = "XBMC-iOS"; - productReference = E4991089174D0D2600741B6D /* XBMC.app */; + name = "Kodi-iOS"; + productName = "Kodi-iOS"; + productReference = E4991089174D0D2600741B6D /* Kodi.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -10335,7 +10371,7 @@ attributes = { LastUpgradeCheck = 0430; }; - buildConfigurationList = 1DEB924B08733DCA0010E9CD /* Build configuration list for PBXProject "XBMC" */; + buildConfigurationList = 1DEB924B08733DCA0010E9CD /* Build configuration list for PBXProject "Kodi" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; @@ -10346,14 +10382,14 @@ German, en, ); - mainGroup = 08FB7794FE84155DC02AAC07 /* XBMC */; + mainGroup = 08FB7794FE84155DC02AAC07 /* Kodi */; projectDirPath = ""; projectRoot = ""; targets = ( - 8DD76F740486A8DE00D96B5E /* XBMC */, - 6E2FACBA0E26DF7A00DF79EA /* XBMC.app */, - E4991088174D0D2600741B6D /* XBMC-iOS */, - DFFC52CA17527B3100C937AB /* XBMC-ATV2 */, + 8DD76F740486A8DE00D96B5E /* Kodi */, + 6E2FACBA0E26DF7A00DF79EA /* Kodi.app */, + E4991088174D0D2600741B6D /* Kodi-iOS */, + DFFC52CA17527B3100C937AB /* Kodi-ATV2 */, ); }; /* End PBXProject section */ @@ -10365,7 +10401,6 @@ files = ( DFF0F49D1752838E002DA3A4 /* InfoPlist.strings in Resources */, DFFA43FF19104C0800C3923B /* AppIcon.png in Resources */, - DFFA440019104C0800C3923B /* XBMC.png in Resources */, 7CCDA1AE192753E30074CF51 /* process_scpds.sh in Resources */, 7CCDA1B9192753E30074CF51 /* X_MS_MediaReceiverRegistrarSCPD.xml in Resources */, 7CCDA1C4192753E30074CF51 /* AVTransportSCPD.xml in Resources */, @@ -10408,6 +10443,8 @@ 7CCDA1C3192753E30074CF51 /* AVTransportSCPD.xml in Resources */, 7CCDA1C5192753E30074CF51 /* AVTransportSCPDFull.xml in Resources */, 7CCDA1D9192753E30074CF51 /* process_scpds.sh in Resources */, + DFD7C7AE19D1DDA90071942C /* Default-736h@3x.png in Resources */, + DFD7C7AD19D1DDA90071942C /* Default-667h@2x.png in Resources */, 7CCDA1E4192753E30074CF51 /* RdrConnectionManagerSCPD.xml in Resources */, 7CCDA1EF192753E30074CF51 /* RenderingControlSCPD.xml in Resources */, 7CCDA1F1192753E30074CF51 /* RenderingControlSCPD_Full.xml in Resources */, @@ -10998,6 +11035,7 @@ F5F8E1DA0E427E8000A8E96F /* VGMCodec.cpp in Sources */, F5F8E1E80E427F6700A8E96F /* md5.cpp in Sources */, F506297A0E57B9680066625A /* MultiPathFile.cpp in Sources */, + DFEB902819E9337200728978 /* AEResampleFactory.cpp in Sources */, F5F2EF4B0E593E0D0092C37F /* DVDFileInfo.cpp in Sources */, F5FDF51D0E7218950005B0A6 /* AsyncFileCopy.cpp in Sources */, E4E91BB80E7F7338001F0546 /* NptXbmcFile.cpp in Sources */, @@ -11051,6 +11089,7 @@ F5D8D732102BB3B1004A11AB /* OverlayRendererGL.cpp in Sources */, F5D8D733102BB3B1004A11AB /* OverlayRenderer.cpp in Sources */, E49ACD8C100745C400A86ECD /* ZeroconfDirectory.cpp in Sources */, + B5101B5819DFF8DD00294D1E /* BlurayFile.cpp in Sources */, E49ACD9F10074A4000A86ECD /* ZeroconfBrowserOSX.cpp in Sources */, E49ACDD510074F9200A86ECD /* ZeroconfBrowser.cpp in Sources */, F5D8EF5B103912A4004A11AB /* DVDSubtitleParserVplayer.cpp in Sources */, @@ -11501,6 +11540,7 @@ F56353BF16E9BB3500D21BAD /* BitstreamConverter.cpp in Sources */, DFAF6A4F16EBAE3800D6AE12 /* RssManager.cpp in Sources */, DF89901C1709BB2D00B35C21 /* MediaSettings.cpp in Sources */, + DF32466219E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp in Sources */, DF89901D1709BB2D00B35C21 /* MediaSourceSettings.cpp in Sources */, DF89901E1709BB2D00B35C21 /* SkinSettings.cpp in Sources */, DF8990211709BB5400B35C21 /* ViewStateSettings.cpp in Sources */, @@ -11567,7 +11607,6 @@ F5CC228B1814F7E9006B5E91 /* AESinkDARWINOSX.cpp in Sources */, F5CC22EB1814FF3B006B5E91 /* ActiveAE.cpp in Sources */, F5CC22EC1814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */, - F5CC22ED1814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */, F5CC22EE1814FF3B006B5E91 /* ActiveAESink.cpp in Sources */, F5CC22EF1814FF3B006B5E91 /* ActiveAESound.cpp in Sources */, F5CC22F01814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */, @@ -11624,6 +11663,7 @@ 7CCDA209192753E30074CF51 /* ContentDirectorywSearchSCPD.cpp in Sources */, 7CCDA214192753E30074CF51 /* PltDidl.cpp in Sources */, 7CCDA21D192753E30074CF51 /* PltFileMediaServer.cpp in Sources */, + DFA0E8C519FD6BEE00269A92 /* VideoSyncCocoa.cpp in Sources */, 7CCDA226192753E30074CF51 /* PltMediaBrowser.cpp in Sources */, 7CCDA22F192753E30074CF51 /* PltMediaCache.cpp in Sources */, 7CCDA238192753E30074CF51 /* PltMediaItem.cpp in Sources */, @@ -11956,6 +11996,7 @@ DFF0F16F17528350002DA3A4 /* DVDDemuxPVRClient.cpp in Sources */, DFF0F17017528350002DA3A4 /* DVDDemuxShoutcast.cpp in Sources */, DFF0F17117528350002DA3A4 /* DVDDemuxUtils.cpp in Sources */, + DFA0E8C819FD7BD100269A92 /* VideoSyncCocoa.cpp in Sources */, DFF0F17217528350002DA3A4 /* DVDDemuxVobsub.cpp in Sources */, DFF0F17317528350002DA3A4 /* DVDFactoryDemuxer.cpp in Sources */, DFF0F17417528350002DA3A4 /* DVDFactoryInputStream.cpp in Sources */, @@ -12285,6 +12326,7 @@ DFF0F2BE17528350002DA3A4 /* Shader.cpp in Sources */, DFF0F2BF17528350002DA3A4 /* Texture.cpp in Sources */, DFF0F2C017528350002DA3A4 /* TextureBundle.cpp in Sources */, + DF3E5EFA199D41300039675D /* kodiclientwrapper.mm in Sources */, DFF0F2C117528350002DA3A4 /* TextureBundleXBT.cpp in Sources */, DFF0F2C217528350002DA3A4 /* TextureBundleXPR.cpp in Sources */, DFF0F2C317528350002DA3A4 /* TextureDX.cpp in Sources */, @@ -12299,6 +12341,7 @@ DFF0F2CC17528350002DA3A4 /* SkinVariable.cpp in Sources */, DFF0F2CD17528350002DA3A4 /* AddonsOperations.cpp in Sources */, DFF0F2CE17528350002DA3A4 /* ApplicationOperations.cpp in Sources */, + DFEB902A19E9337200728978 /* AEResampleFactory.cpp in Sources */, DFF0F2CF17528350002DA3A4 /* AudioLibrary.cpp in Sources */, DFF0F2D017528350002DA3A4 /* FavouritesOperations.cpp in Sources */, DFF0F2D117528350002DA3A4 /* FileItemHandler.cpp in Sources */, @@ -12411,6 +12454,7 @@ DFF0F33E17528350002DA3A4 /* Network.cpp in Sources */, DFF0F33F17528350002DA3A4 /* NetworkServices.cpp in Sources */, DFF0F34017528350002DA3A4 /* Socket.cpp in Sources */, + DF3E5EFD199D4B340039675D /* KodiController.mm in Sources */, DFF0F34117528350002DA3A4 /* TCPServer.cpp in Sources */, DFF0F34217528350002DA3A4 /* UdpClient.cpp in Sources */, DFF0F34317528350002DA3A4 /* WakeOnAccess.cpp in Sources */, @@ -12607,6 +12651,7 @@ DFF0F40E17528350002DA3A4 /* GUIViewStateVideo.cpp in Sources */, DFF0F40F17528350002DA3A4 /* PlayerController.cpp in Sources */, DFF0F41017528350002DA3A4 /* Teletext.cpp in Sources */, + B5101B5A19DFF8E400294D1E /* BlurayFile.cpp in Sources */, DFF0F41117528350002DA3A4 /* VideoDatabase.cpp in Sources */, DFF0F41217528350002DA3A4 /* VideoDbUrl.cpp in Sources */, DFF0F41317528350002DA3A4 /* VideoInfoDownloader.cpp in Sources */, @@ -12669,6 +12714,7 @@ DFF0F45517528350002DA3A4 /* Addon.cpp in Sources */, DFF0F45617528350002DA3A4 /* AddonCallback.cpp in Sources */, DFF0F45717528350002DA3A4 /* AddonClass.cpp in Sources */, + DFF1FE23199D2FFF0008211F /* KodiAppliance.mm in Sources */, DFF0F45817528350002DA3A4 /* AddonUtils.cpp in Sources */, DFF0F45917528350002DA3A4 /* CallbackFunction.cpp in Sources */, DFF0F45A17528350002DA3A4 /* CallbackHandler.cpp in Sources */, @@ -12702,6 +12748,7 @@ DFF0F47617528350002DA3A4 /* WinSystemIOS.mm in Sources */, DFF0F47717528350002DA3A4 /* htsatomic.c in Sources */, DFF0F47817528350002DA3A4 /* htsbuf.c in Sources */, + DF32466419E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp in Sources */, DFF0F47917528350002DA3A4 /* htsmsg.c in Sources */, DFF0F47A17528350002DA3A4 /* htsmsg_binary.c in Sources */, DFF0F47B17528350002DA3A4 /* htsstr.c in Sources */, @@ -12717,9 +12764,6 @@ DFF0F48817528350002DA3A4 /* fstrcmp.c in Sources */, DFF0F48917528350002DA3A4 /* cc_decoder.c in Sources */, DFF0F48A17528350002DA3A4 /* yuv2rgb.neon.S in Sources */, - DFF0F49F1752838E002DA3A4 /* XBMCAppliance.mm in Sources */, - DFF0F4A11752838E002DA3A4 /* xbmcclientwrapper.mm in Sources */, - DFF0F4A21752838E002DA3A4 /* XBMCController.mm in Sources */, DF3C3C0E1752A7EE000989C3 /* IOSEAGLView.mm in Sources */, DF3C3C0F1752A7EE000989C3 /* IOSExternalTouchController.mm in Sources */, DF3C3C101752A7EE000989C3 /* IOSScreenManager.mm in Sources */, @@ -12764,7 +12808,6 @@ F5CC228F1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */, F5CC22E51814FF3B006B5E91 /* ActiveAE.cpp in Sources */, F5CC22E61814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */, - F5CC22E71814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */, F5CC22E81814FF3B006B5E91 /* ActiveAESink.cpp in Sources */, F5CC22E91814FF3B006B5E91 /* ActiveAESound.cpp in Sources */, F5CC22EA1814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */, @@ -13311,6 +13354,7 @@ E499127B174E5D8F00741B6D /* MultiPathFile.cpp in Sources */, E499127C174E5D9900741B6D /* DirectoryNode.cpp in Sources */, E499127D174E5D9900741B6D /* DirectoryNodeAlbum.cpp in Sources */, + B5101B5919DFF8E300294D1E /* BlurayFile.cpp in Sources */, E499127E174E5D9900741B6D /* DirectoryNodeAlbumCompilations.cpp in Sources */, E499127F174E5D9900741B6D /* DirectoryNodeAlbumCompilationsSongs.cpp in Sources */, E4991280174E5D9900741B6D /* DirectoryNodeAlbumRecentlyAdded.cpp in Sources */, @@ -13610,6 +13654,7 @@ E49913C1174E5F3C00741B6D /* Socket.cpp in Sources */, E49913C2174E5F3C00741B6D /* TCPServer.cpp in Sources */, E49913C3174E5F3C00741B6D /* UdpClient.cpp in Sources */, + DFEB902919E9337200728978 /* AEResampleFactory.cpp in Sources */, E49913C4174E5F3C00741B6D /* WakeOnAccess.cpp in Sources */, E49913C5174E5F3C00741B6D /* WebServer.cpp in Sources */, E49913C6174E5F3C00741B6D /* Zeroconf.cpp in Sources */, @@ -13635,6 +13680,7 @@ E49913DA174E5F8D00741B6D /* Picture.cpp in Sources */, E49913DB174E5F8D00741B6D /* PictureInfoLoader.cpp in Sources */, E49913DC174E5F8D00741B6D /* PictureInfoTag.cpp in Sources */, + DFA0E8C719FD7BD100269A92 /* VideoSyncCocoa.cpp in Sources */, E49913DD174E5F8D00741B6D /* PictureThumbLoader.cpp in Sources */, E49913DE174E5F8D00741B6D /* SlideShowPicture.cpp in Sources */, E49913DF174E5F8D00741B6D /* PlayList.cpp in Sources */, @@ -13955,7 +14001,6 @@ F5CC228E1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */, F5CC22DF1814FF3B006B5E91 /* ActiveAE.cpp in Sources */, F5CC22E01814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */, - F5CC22E11814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */, F5CC22E21814FF3B006B5E91 /* ActiveAESink.cpp in Sources */, F5CC22E31814FF3B006B5E91 /* ActiveAESound.cpp in Sources */, F5CC22E41814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */, @@ -13986,6 +14031,7 @@ 7CCDA136192753E30074CF51 /* PltHttpClientTask.cpp in Sources */, 7CCDA13F192753E30074CF51 /* PltHttpServer.cpp in Sources */, 7CCDA148192753E30074CF51 /* PltHttpServerTask.cpp in Sources */, + DF32466319E931A8005E8CFB /* ActiveAEResampleFFMPEG.cpp in Sources */, 7CCDA151192753E30074CF51 /* PltIconsData.cpp in Sources */, 7CCDA15A192753E30074CF51 /* PltMimeType.cpp in Sources */, 7CCDA163192753E30074CF51 /* PltProtocolInfo.cpp in Sources */, @@ -14228,7 +14274,7 @@ /* Begin PBXTargetDependency section */ 6E2FACC40E26E08100DF79EA /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 8DD76F740486A8DE00D96B5E /* XBMC */; + target = 8DD76F740486A8DE00D96B5E /* Kodi */; targetProxy = 6E2FACC30E26E08100DF79EA /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -14310,7 +14356,7 @@ "$(OTHER_CFLAGS)", "-Wreorder", ); - PRODUCT_NAME = XBMC; + PRODUCT_NAME = Kodi; USE_HEADERMAP = NO; WARNING_CFLAGS = ""; XBMC_DEPENDS = "$(XBMC_DEPENDS_ROOT)/$(SDK_NAME)_$(CURRENT_ARCH)-target"; @@ -14376,7 +14422,7 @@ "$(OTHER_CFLAGS)", "-Wreorder", ); - PRODUCT_NAME = XBMC; + PRODUCT_NAME = Kodi; USE_HEADERMAP = NO; WARNING_CFLAGS = ""; XBMC_DEPENDS = "$(XBMC_DEPENDS_ROOT)/$(SDK_NAME)_$(CURRENT_ARCH)-target"; @@ -14415,7 +14461,7 @@ COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = XBMC.app; + PRODUCT_NAME = Kodi.app; SDKROOT = macosx; XBMC_DEPENDS = "$(XBMC_DEPENDS_ROOT)/$(SDK_NAME)_$(CURRENT_ARCH)-target"; }; @@ -14429,7 +14475,7 @@ x86_64, ); COPY_PHASE_STRIP = YES; - PRODUCT_NAME = XBMC.app; + PRODUCT_NAME = Kodi.app; SDKROOT = macosx; XBMC_DEPENDS = "$(XBMC_DEPENDS_ROOT)/$(SDK_NAME)_$(CURRENT_ARCH)-target"; ZERO_LINK = NO; @@ -14485,7 +14531,7 @@ ); PLIST_FILE_OUTPUT_FORMAT = xml; PREBINDING = NO; - PRODUCT_NAME = XBMC; + PRODUCT_NAME = Kodi; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "2,3"; USER_HEADER_SEARCH_PATHS = "$XBMC_DEPENDS/include $XBMC_DEPENDS/include/mysql $XBMC_DEPENDS/include/freetype2 $XBMC_DEPENDS/include/python2.6"; @@ -14546,7 +14592,7 @@ ); PLIST_FILE_OUTPUT_FORMAT = xml; PREBINDING = NO; - PRODUCT_NAME = XBMC; + PRODUCT_NAME = Kodi; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "2,3"; USER_HEADER_SEARCH_PATHS = "$XBMC_DEPENDS/include $XBMC_DEPENDS/include/mysql $XBMC_DEPENDS/include/freetype2 $XBMC_DEPENDS/include/python2.6"; @@ -14640,7 +14686,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 1DEB924708733DCA0010E9CD /* Build configuration list for PBXNativeTarget "XBMC" */ = { + 1DEB924708733DCA0010E9CD /* Build configuration list for PBXNativeTarget "Kodi" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB924808733DCA0010E9CD /* Debug */, @@ -14649,7 +14695,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 1DEB924B08733DCA0010E9CD /* Build configuration list for PBXProject "XBMC" */ = { + 1DEB924B08733DCA0010E9CD /* Build configuration list for PBXProject "Kodi" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB924C08733DCA0010E9CD /* Debug */, @@ -14658,7 +14704,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6E2FACC10E26DFA300DF79EA /* Build configuration list for PBXAggregateTarget "XBMC.app" */ = { + 6E2FACC10E26DFA300DF79EA /* Build configuration list for PBXAggregateTarget "Kodi.app" */ = { isa = XCConfigurationList; buildConfigurations = ( 6E2FACBB0E26DF7A00DF79EA /* Debug */, @@ -14667,7 +14713,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DFFC52CE17527B4F00C937AB /* Build configuration list for PBXNativeTarget "XBMC-ATV2" */ = { + DFFC52CE17527B4F00C937AB /* Build configuration list for PBXNativeTarget "Kodi-ATV2" */ = { isa = XCConfigurationList; buildConfigurations = ( DFFC52CC17527B3100C937AB /* Debug */, @@ -14676,7 +14722,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - E49910A5174D0D2600741B6D /* Build configuration list for PBXNativeTarget "XBMC-iOS" */ = { + E49910A5174D0D2600741B6D /* Build configuration list for PBXNativeTarget "Kodi-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( E49910A3174D0D2600741B6D /* Debug */, diff --git a/Makefile.in b/Makefile.in index bda532b726..1ce9039ac6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -96,6 +96,7 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \ xbmc/storage/storage.a \ xbmc/utils/utils.a \ xbmc/video/dialogs/videodialogs.a \ + xbmc/video/videosync/videosync.a \ xbmc/video/video.a \ xbmc/video/windows/videowindows.a \ xbmc/view/view.a \ @@ -269,19 +270,19 @@ CXXFLAGS=@CXXFLAGS@ LDFLAGS=@LDFLAGS@ INCLUDES=$(sort @INCLUDES@) -CLEAN_FILES=xbmc.bin xbmc-xrandr libxbmc.so +CLEAN_FILES=@APP_NAME_LC@.bin @APP_NAME_LC@-xrandr lib@APP_NAME_LC@.so -DISTCLEAN_FILES=config.h config.log config.status tools/Linux/xbmc.sh \ - tools/Linux/xbmc-standalone.sh autom4te.cache config.h.in~ \ +DISTCLEAN_FILES=config.h config.log config.status tools/Linux/@APP_NAME_LC@.sh \ + tools/Linux/@APP_NAME_LC@-standalone.sh autom4te.cache config.h.in~ \ system/libcpluff-@ARCH@.so ifeq (@USE_LIBXBMC@,1) -FINAL_TARGETS+=libxbmc.so +FINAL_TARGETS+=lib@APP_NAME_LC@.so ifeq (@USE_ANDROID@,1) FINAL_TARGETS+=skins endif else -FINAL_TARGETS=xbmc.bin skins xbmc-xrandr +FINAL_TARGETS=@APP_NAME_LC@.bin skins @APP_NAME_LC@-xrandr endif FINAL_TARGETS+=Makefile externals @@ -326,13 +327,13 @@ sse4 : force $(MAKE) -C xbmc/linux/sse4 endif -CHECK_PROGRAMS = xbmc-test +CHECK_PROGRAMS = @APP_NAME_LC@-test CLEAN_FILES += $(CHECK_PROGRAMS) $(CHECK_EXTENSIONS) all : $(FINAL_TARGETS) @echo '-----------------------' - @echo 'XBMC built successfully' + @echo '@APP_NAME@ built successfully' @echo '-----------------------' include Makefile.include @@ -406,7 +407,7 @@ dvdpcodecs: dllloader $(MAKE) -C lib/libdvd ifeq (@USE_LIBSTAGEFRIGHT@,1) -dvdpextcodecs: libxbmc.so +dvdpextcodecs: lib@APP_NAME_LC@.so $(MAKE) -C xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS else dvdpextcodecs: @@ -518,59 +519,60 @@ $(NWAOBJSXBMC) $(DIRECTORY_ARCHIVES) $(MAINOBJS): force # Binary Addon bindings include xbmc/addons/addon-bindings.mk -libxbmc.so: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS) +lib@APP_NAME_LC@.so: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS) ifeq ($(findstring osx,@ARCH@), osx) $(SILENT_LD) $(CXX) $(LDFLAGS) -bundle -o $@ $(MAINOBJS) -Wl,-all_load,-ObjC $(MAINOBJS) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -read_only_relocs suppress else $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ -Wl,--whole-archive $(MAINOBJS) -Wl,--no-whole-archive,--start-group $(MAINOBJS) $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group -Wl,--no-undefined $(NWAOBJSXBMC) $(LIBS) endif -xbmc.bin: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS) +@APP_NAME_LC@.bin: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS) ifeq ($(findstring osx,@ARCH@), osx) - $(SILENT_LD) $(CXX) $(LDFLAGS) -o xbmc.bin $(MAINOBJS) -Wl,-all_load,-ObjC $(MAINOBJS) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -rdynamic + $(SILENT_LD) $(CXX) $(LDFLAGS) -o @APP_NAME_LC@.bin $(MAINOBJS) -Wl,-all_load,-ObjC $(MAINOBJS) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -rdynamic else - $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o xbmc.bin $(MAINOBJS) -Wl,--start-group $(MAINOBJS) $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group $(NWAOBJSXBMC) $(LIBS) -rdynamic + $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o @APP_NAME_LC@.bin $(MAINOBJS) -Wl,--start-group $(MAINOBJS) $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group $(NWAOBJSXBMC) $(LIBS) -rdynamic endif -xbmc-xrandr: xbmc-xrandr.c +@APP_NAME_LC@-xrandr: xbmc-xrandr.c ifneq (1,@USE_XRANDR@) # xbmc-xrandr.c gets picked up by the default make rules - @echo "excluding xbmc-xrandr" + @echo "excluding @APP_NAME_LC@-xrandr" else - $(SILENT_LD) $(CC) $(CFLAGS) $(LDFLAGS) -o xbmc-xrandr xbmc-xrandr.c -lXrandr -lX11 -lm + $(SILENT_LD) $(CC) $(CFLAGS) $(LDFLAGS) -o @APP_NAME_LC@-xrandr xbmc-xrandr.c -lXrandr -lX11 -lm endif tools/TexturePacker/TexturePacker: xbmc/guilib/XBTF.h $(MAKE) -C tools/TexturePacker/ -install-bin: xbmc.bin # developement convenience target +install-bin: @APP_NAME_LC@.bin # developement convenience target sudo install -d $(DESTDIR)$(libdir) - sudo install xbmc.bin $(DESTDIR)$(libdir)/xbmc + sudo install @APP_NAME_LC@.bin $(DESTDIR)$(libdir)/@APP_NAME_LC@ ifeq ($(findstring osx,@ARCH@), osx) # TODO: add osx install else install: install-binaries install-arch install-datas -apk: apk-clean install - make -C tools/android/packaging +apk obb apk-unsigned apk-obb apk-obb-unsigned apk-noobb: install + make -C tools/android/packaging $@ -apk-clean: - make -C tools/android/packaging clean +apk-clean apk-sign: + make -C tools/android/packaging $@ install-binaries: install-scripts - @echo "Copying XBMC binary to $(DESTDIR)$(libdir)/xbmc/" - @install -d $(DESTDIR)$(libdir)/xbmc + @echo "Copying @APP_NAME_LC@ binary to $(DESTDIR)$(libdir)/@APP_NAME_LC@/" + @install -d $(DESTDIR)$(libdir)/@APP_NAME_LC@ + @cd $(DESTDIR)$(libdir); [ -L xbmc ] || [ -d xbmc ] || ln -s @APP_NAME_LC@ xbmc ifeq (1,@USE_XRANDR@) - @install xbmc-xrandr $(DESTDIR)$(libdir)/xbmc/xbmc-xrandr + @install @APP_NAME_LC@-xrandr $(DESTDIR)$(libdir)/@APP_NAME_LC@/@APP_NAME_LC@-xrandr endif ifeq (@USE_LIBXBMC@,1) - @install libxbmc.so $(DESTDIR)$(libdir)/xbmc/libxbmc.so + @install lib@APP_NAME_LC@.so $(DESTDIR)$(libdir)/@APP_NAME_LC@/lib@APP_NAME_LC@.so else - @install xbmc.bin $(DESTDIR)$(libdir)/xbmc/xbmc.bin - @echo "You can run XBMC with the command 'xbmc'" + @install @APP_NAME_LC@.bin $(DESTDIR)$(libdir)/@APP_NAME_LC@/@APP_NAME_LC@.bin + @echo "You can run @APP_NAME_LC@ with the command '@APP_NAME_LC@'" endif endif @@ -582,31 +584,35 @@ endif ifeq ($(findstring freebsd,@ARCH@), freebsd) @find -E system addons -type f -not -iregex ".*\.git.*" \ -iregex ".*@ARCH@.*|.*\.vis|.*\.xbs" \ - -exec sh -c "install -d \"$(DESTDIR)$(libdir)/xbmc/\`dirname '{}'\`\"" \; \ + -exec sh -c "install -d \"$(DESTDIR)$(libdir)/@APP_NAME_LC@/\`dirname '{}'\`\"" \; \ -and \ - -exec install "{}" $(DESTDIR)$(libdir)/xbmc/"{}" \; \ + -exec install "{}" $(DESTDIR)$(libdir)/@APP_NAME_LC@/"{}" \; \ -exec printf " -- %-75.75s\r" "{}" \; else ifeq ($(findstring Darwin,$(shell uname -s)),Darwin) @find -E system addons -type f -not -iregex ".*\.git.*" \ -iregex ".*@ARCH@.*|.*\.vis|.*\.xbs" \ - -exec sh -c "install -d \"$(DESTDIR)$(libdir)/xbmc/\`dirname '{}'\`\"" \; \ + -exec sh -c "install -d \"$(DESTDIR)$(libdir)/@APP_NAME_LC@/\`dirname '{}'\`\"" \; \ -and \ -exec install "{}" $(DESTDIR)$(libdir)/xbmc/"{}" \; \ -exec printf " -- %-75.75s\r" "{}" \; else - @find system addons -regextype posix-extended -type f -not -iregex ".*\.git.*" -iregex ".*\.so|.*\.vis|.*\.xbs|.*\.pvr" -exec install -D "{}" $(DESTDIR)$(libdir)/xbmc/"{}" \; -printf " -- %-75.75f\r" + @find system addons -regextype posix-extended -type f -not -iregex ".*\.git.*" -iregex ".*\.so|.*\.vis|.*\.xbs|.*\.pvr" -exec install -D "{}" $(DESTDIR)$(libdir)/@APP_NAME_LC@/"{}" \; -printf " -- %-75.75f\r" endif endif install-scripts: @install -d $(DESTDIR)$(bindir) - @install tools/Linux/xbmc.sh $(DESTDIR)$(bindir)/xbmc - @install tools/Linux/xbmc-standalone.sh $(DESTDIR)$(bindir)/xbmc-standalone - @install -d $(DESTDIR)$(datarootdir)/xbmc - @install -m 0644 tools/Linux/FEH.py $(DESTDIR)$(datarootdir)/xbmc/FEH.py + @install tools/Linux/@APP_NAME_LC@.sh $(DESTDIR)$(bindir)/@APP_NAME_LC@ + @cd $(DESTDIR)$(bindir); [ -L xbmc ] || [ -f xbmc ] || ln -s @APP_NAME_LC@ xbmc + @install tools/Linux/@APP_NAME_LC@-standalone.sh $(DESTDIR)$(bindir)/@APP_NAME_LC@-standalone + @cd $(DESTDIR)$(bindir); [ -L xbmc-standalone ] || [ -f xbmc-standalone ] || ln -s @APP_NAME_LC@-standalone xbmc-standalone + @install -d $(DESTDIR)$(datarootdir)/@APP_NAME_LC@ + @cd $(DESTDIR)$(datarootdir); [ -L xbmc ] || [ -d xbmc ] || ln -s @APP_NAME_LC@ xbmc + @install -m 0644 tools/Linux/FEH.py $(DESTDIR)$(datarootdir)/@APP_NAME_LC@/FEH.py @install -d $(DESTDIR)$(datarootdir)/xsessions - @install -m 0644 tools/Linux/xbmc-xsession.desktop $(DESTDIR)$(datarootdir)/xsessions/XBMC.desktop + @install -m 0644 tools/Linux/@APP_NAME_LC@-xsession.desktop $(DESTDIR)$(datarootdir)/xsessions/@APP_NAME_LC@.desktop + @cd $(DESTDIR)$(datarootdir)/xsessions; [ -L xbmc.desktop ] || [ -f xbmc.desktop ] || ln -s @APP_NAME_LC@.desktop xbmc.desktop install-datas: install-scripts @echo "Copying support and legal files..." @@ -615,15 +621,15 @@ install-datas: install-scripts install -m 0644 "$$FILE" "$(DESTDIR)$(docdir)/$$FILE"; done @install -m 0644 "docs/README.linux" "$(DESTDIR)$(docdir)/README.linux" @echo "Done!" - @echo "Copying system files to $(DESTDIR)$(datarootdir)/xbmc" - @install -d $(DESTDIR)$(datarootdir)/xbmc + @echo "Copying system files to $(DESTDIR)$(datarootdir)/@APP_NAME_LC@" + @install -d $(DESTDIR)$(datarootdir)/@APP_NAME_LC@ @# Arch independent files ifeq ($(findstring bsd,@ARCH@), bsd) @find -E addons language media sounds userdata system -type f \ -not -iregex ".*@ARCH@.*|.*\.vis|.*\.xbs|.*\.git.*|.*\.so|.*\.dll|$(subst ${space},|,$(INSTALL_FILTER))" \ - -exec sh -c "install -d \"$(DESTDIR)$(datarootdir)/xbmc/\`dirname '{}'\`\"" \; \ + -exec sh -c "install -d \"$(DESTDIR)$(datarootdir)/@APP_NAME_LC@/\`dirname '{}'\`\"" \; \ -and \ - -exec install -m 0644 "{}" $(DESTDIR)$(datarootdir)/xbmc/"{}" \; \ + -exec install -m 0644 "{}" $(DESTDIR)$(datarootdir)/@APP_NAME_LC@/"{}" \; \ -exec printf " -- %-75.75s\r" "{}" \; else ifeq ($(findstring Darwin,$(shell uname -s)),Darwin) @@ -634,42 +640,43 @@ ifeq ($(findstring Darwin,$(shell uname -s)),Darwin) -exec install -m 0644 "{}" $(DESTDIR)$(datarootdir)/xbmc/"{}" \; \ -exec printf " -- %-75.75s\r" "{}" \; else - @find addons language media sounds userdata system -regextype posix-extended -type f -not -iregex ".*@ARCH@.*|.*\.vis|.*\.xbs|.*\.git.*|.*\.so|.*\.dll|.*\.pvr|$(subst ${space},|,$(INSTALL_FILTER))" -exec install -D -m 0644 "{}" $(DESTDIR)$(datarootdir)/xbmc/"{}" \; -printf " -- %-75.75f\r" + @find addons language media sounds userdata system -regextype posix-extended -type f -not -iregex ".*@ARCH@.*|.*\.vis|.*\.xbs|.*\.git.*|.*\.so|.*\.dll|.*\.pvr|$(subst ${space},|,$(INSTALL_FILTER))" -exec install -D -m 0644 "{}" $(DESTDIR)$(datarootdir)/@APP_NAME_LC@/"{}" \; -printf " -- %-75.75f\r" endif endif @# Icons and links @install -d $(DESTDIR)$(datarootdir)/applications - @install -m 0644 tools/Linux/xbmc.desktop $(DESTDIR)$(datarootdir)/applications/xbmc.desktop + @install -m 0644 tools/Linux/@APP_NAME_LC@.desktop $(DESTDIR)$(datarootdir)/applications/@APP_NAME_LC@.desktop @install -d $(DESTDIR)$(datadir)/icons/hicolor/48x48/apps - @install -m 0644 media/icon48x48.png $(DESTDIR)$(datadir)/icons/hicolor/48x48/apps/xbmc.png + @install -m 0644 media/icon48x48.png $(DESTDIR)$(datadir)/icons/hicolor/48x48/apps/@APP_NAME_LC@.png @install -d $(DESTDIR)$(datadir)/icons/hicolor/256x256/apps - @install -m 0644 media/icon256x256.png $(DESTDIR)$(datadir)/icons/hicolor/256x256/apps/xbmc.png + @install -m 0644 media/icon256x256.png $(DESTDIR)$(datadir)/icons/hicolor/256x256/apps/@APP_NAME_LC@.png @test -z "$(DESTDIR)" && gtk-update-icon-cache -f -q -t $(datadir)/icons/hicolor || : - @echo "Copying bindings to $(DESTDIR)$(includedir)/xbmc" - @install -d $(DESTDIR)$(includedir)/xbmc + @echo "Copying bindings to $(DESTDIR)$(includedir)/@APP_NAME_LC@" + @install -d $(DESTDIR)$(includedir)/@APP_NAME_LC@ @for f in $(BINDINGS); do \ - install -m 0644 $$f $(DESTDIR)$(includedir)/xbmc ; \ + install -m 0644 $$f $(DESTDIR)$(includedir)/@APP_NAME_LC@ ; \ done @for f in project/cmake/*.cmake; do \ - install -m 0644 $$f $(DESTDIR)$(libdir)/xbmc; \ + install -m 0644 $$f $(DESTDIR)$(libdir)/@APP_NAME_LC@; \ done @for f in project/cmake/scripts/common/*.cmake; do \ - install -m 0644 $$f $(DESTDIR)$(libdir)/xbmc; \ + install -m 0644 $$f $(DESTDIR)$(libdir)/@APP_NAME_LC@; \ done + @cd $(DESTDIR)$(includedir); [ -L xbmc ] || [ -d xbmc ] || ln -s @APP_NAME_LC@ xbmc uninstall: - @echo "Removing XBMC..." - @rm -rf $(DESTDIR)$(libdir)/xbmc - @rm -rf $(DESTDIR)$(datarootdir)/xbmc $(DESTDIR)$(bindir)/xbmc - @rm -rf $(DESTDIR)$(bindir)/xbmc-standalone - @rm -rf $(DESTDIR)$(datarootdir)/xsessions/XBMC.desktop - @rm -rf $(libdir)/libXBMC_* - @rm -rf $(prefix)/include/xbmc + @echo "Removing @APP_NAME@..." + @rm -rf $(DESTDIR)$(libdir)/@APP_NAME_LC@ + @rm -rf $(DESTDIR)$(datarootdir)/@APP_NAME_LC@ $(DESTDIR)$(bindir)/@APP_NAME_LC@ + @rm -rf $(DESTDIR)$(bindir)/@APP_NAME_LC@-standalone + @rm -rf $(DESTDIR)$(datarootdir)/xsessions/@APP_NAME_LC@.desktop + @rm -rf $(libdir)/lib@APP_NAME_LC@_* + @rm -rf $(prefix)/include/@APP_NAME_LC@ @echo "Done!" -clean-xbmc.bin: - rm -f xbmc.bin +clean-@APP_NAME_LC@.bin: + rm -f @APP_NAME_LC@.bin for d in $(BIN_DIRS); do if test -f $$d/Makefile; then $(MAKE) -C $$d clean; fi; done clean-eventclients: for d in $(EC_DIRS); do if test -f $$d/Makefile; then $(MAKE) -C $$d clean; fi; done @@ -713,7 +720,7 @@ $(GTEST_DIR)/Makefile: force $(CHECK_LIBS): force @$(MAKE) $(if $(V),,-s) -C $(@D) -xbmc-test: $(CHECK_LIBS) $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(GTEST_LIBS) +@APP_NAME_LC@-test: $(CHECK_LIBS) $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(GTEST_LIBS) ifeq ($(findstring osx,@ARCH@), osx) $(SILENT_LD) $(CXX) $(LDFLAGS) $(GTEST_INCLUDES) -o $@ -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(GTEST_LIBS) $(CHECK_LIBS) $(LIBS) $(CHECK_LIBADD) -rdynamic else diff --git a/Makefile.include.in b/Makefile.include.in index 6ee228abfe..481da57c66 100644 --- a/Makefile.include.in +++ b/Makefile.include.in @@ -50,8 +50,8 @@ DEFINES+= \ @ARCH_DEFINES@ \ -D_FILE_DEFINED \ -D__STDC_CONSTANT_MACROS \ - -DBIN_INSTALL_PATH="\"$(libdir)/xbmc\"" \ - -DINSTALL_PATH="\"$(datarootdir)/xbmc\"" \ + -DBIN_INSTALL_PATH="\"$(libdir)/@APP_NAME_LC@\"" \ + -DINSTALL_PATH="\"$(datarootdir)/@APP_NAME_LC@\"" \ @SDL_DEFINES@ \ @UPNP_DEFINES@ \ @DEFS@ \ diff --git a/addons/library.xbmc.addon/libXBMC_addon.h b/addons/library.xbmc.addon/libXBMC_addon.h index 0b2d17c93b..3e822f478f 100644 --- a/addons/library.xbmc.addon/libXBMC_addon.h +++ b/addons/library.xbmc.addon/libXBMC_addon.h @@ -28,6 +28,10 @@ #include <stdarg.h> #ifdef _WIN32 // windows +#ifndef _SSIZE_T_DEFINED +typedef intptr_t ssize_t; +#define _SSIZE_T_DEFINED +#endif // !_SSIZE_T_DEFINED #include "dlfcn-win32.h" #define ADDON_DLL "\\library.xbmc.addon\\libXBMC_addon" ADDON_HELPER_EXT #define ADDON_HELPER_EXT ".dll" @@ -186,7 +190,7 @@ namespace ADDON dlsym(m_libXBMC_addon, "XBMC_open_file_for_write"); if (XBMC_open_file_for_write == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } - XBMC_read_file = (unsigned int (*)(void* HANDLE, void* CB, void* file, void* lpBuf, int64_t uiBufSize)) + XBMC_read_file = (ssize_t (*)(void* HANDLE, void* CB, void* file, void* lpBuf, size_t uiBufSize)) dlsym(m_libXBMC_addon, "XBMC_read_file"); if (XBMC_read_file == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } @@ -194,7 +198,7 @@ namespace ADDON dlsym(m_libXBMC_addon, "XBMC_read_file_string"); if (XBMC_read_file_string == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } - XBMC_write_file = (int (*)(void* HANDLE, void* CB, void* file, const void* lpBuf, int64_t uiBufSize)) + XBMC_write_file = (ssize_t (*)(void* HANDLE, void* CB, void* file, const void* lpBuf, size_t uiBufSize)) dlsym(m_libXBMC_addon, "XBMC_write_file"); if (XBMC_write_file == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } @@ -375,9 +379,11 @@ namespace ADDON * @param file The file handle to read from. * @param lpBuf The buffer to store the data in. * @param uiBufSize The size of the buffer. - * @return Number of bytes read. + * @return number of successfully read bytes if any bytes were read and stored in + * buffer, zero if no bytes are available to read (end of file was reached) + * or undetectable error occur, -1 in case of any explicit error */ - unsigned int ReadFile(void* file, void* lpBuf, int64_t uiBufSize) + ssize_t ReadFile(void* file, void* lpBuf, size_t uiBufSize) { return XBMC_read_file(m_Handle, m_Callbacks, file, lpBuf, uiBufSize); } @@ -399,9 +405,11 @@ namespace ADDON * @param file The file handle to write to. * @param lpBuf The data to write. * @param uiBufSize Size of the data to write. - * @return The number of bytes read. + * @return number of successfully written bytes if any bytes were written, + * zero if no bytes were written and no detectable error occur, + * -1 in case of any explicit error */ - int WriteFile(void* file, const void* lpBuf, int64_t uiBufSize) + ssize_t WriteFile(void* file, const void* lpBuf, size_t uiBufSize) { return XBMC_write_file(m_Handle, m_Callbacks, file, lpBuf, uiBufSize); } @@ -562,9 +570,9 @@ namespace ADDON void (*XBMC_free_string)(void *HANDLE, void* CB, char* str); void* (*XBMC_open_file)(void *HANDLE, void* CB, const char* strFileName, unsigned int flags); void* (*XBMC_open_file_for_write)(void *HANDLE, void* CB, const char* strFileName, bool bOverWrite); - unsigned int (*XBMC_read_file)(void *HANDLE, void* CB, void* file, void* lpBuf, int64_t uiBufSize); + ssize_t (*XBMC_read_file)(void *HANDLE, void* CB, void* file, void* lpBuf, size_t uiBufSize); bool (*XBMC_read_file_string)(void *HANDLE, void* CB, void* file, char *szLine, int iLineLength); - int (*XBMC_write_file)(void *HANDLE, void* CB, void* file, const void* lpBuf, int64_t uiBufSize); + ssize_t(*XBMC_write_file)(void *HANDLE, void* CB, void* file, const void* lpBuf, size_t uiBufSize); void (*XBMC_flush_file)(void *HANDLE, void* CB, void* file); int64_t (*XBMC_seek_file)(void *HANDLE, void* CB, void* file, int64_t iFilePosition, int iWhence); int (*XBMC_truncate_file)(void *HANDLE, void* CB, void* file, int64_t iSize); diff --git a/addons/skin.confluence/720p/MusicVisualisation.xml b/addons/skin.confluence/720p/MusicVisualisation.xml index 13ccf540f8..02dede396f 100644 --- a/addons/skin.confluence/720p/MusicVisualisation.xml +++ b/addons/skin.confluence/720p/MusicVisualisation.xml @@ -221,7 +221,7 @@ <control type="group" id="0"> <left>0</left> <top>50</top> - <visible>Player.ShowCodec + ![Window.IsVisible(script-XBMC_Lyrics-main.xml) | Window.IsVisible(VisualisationSettings) | Window.IsVisible(VisualisationPresetList)]</visible> + <visible>Player.ShowCodec + ![Window.IsVisible(script-cu-lrclyrics-main.xml) | Window.IsVisible(VisualisationSettings) | Window.IsVisible(VisualisationPresetList)]</visible> <animation effect="fade" time="200">VisibleChange</animation> <control type="image"> <description>media info background image</description> diff --git a/addons/skin.confluence/720p/MyWeather.xml b/addons/skin.confluence/720p/MyWeather.xml index 4b2ed1186e..62438553c8 100644 --- a/addons/skin.confluence/720p/MyWeather.xml +++ b/addons/skin.confluence/720p/MyWeather.xml @@ -203,138 +203,190 @@ <height>4</height> <texture>separator.png</texture> </control> - <control type="label"> - <description>current feels like label</description> + <control type="grouplist"> <left>0</left> <top>400</top> <width>170</width> - <height>35</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <label>$LOCALIZE[402] :</label> - <textcolor>grey2</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current dew label</description> - <left>0</left> - <top>430</top> - <width>170</width> - <height>35</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <label>$LOCALIZE[405] :</label> - <textcolor>grey2</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current humidity label</description> - <left>0</left> - <top>460</top> - <width>170</width> - <height>35</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <label>$LOCALIZE[406] :</label> - <textcolor>grey2</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current UV Index label</description> - <left>0</left> - <top>490</top> - <width>170</width> - <height>35</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <label>$LOCALIZE[403] :</label> - <textcolor>grey2</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current Wind label</description> - <left>0</left> - <top>520</top> - <width>170</width> - <height>35</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <label>$LOCALIZE[404] :</label> - <textcolor>grey2</textcolor> - <shadowcolor>black</shadowcolor> + <height>180</height> + <itemgap>0</itemgap> + <control type="label"> + <description>current feels like label</description> + <left>0</left> + <top>0</top> + <width>170</width> + <height>28</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <label>$LOCALIZE[402] :</label> + <textcolor>grey2</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.FeelsLike))</visible> + </control> + <control type="label"> + <description>current dew label</description> + <left>0</left> + <top>0</top> + <width>170</width> + <height>28</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <label>$LOCALIZE[405] :</label> + <textcolor>grey2</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.DewPoint))</visible> + </control> + <control type="label"> + <description>current humidity label</description> + <left>0</left> + <top>0</top> + <width>170</width> + <height>28</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <label>$LOCALIZE[406] :</label> + <textcolor>grey2</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.Humidity))</visible> + </control> + <control type="label"> + <description>current UV Index label</description> + <left>0</left> + <top>0</top> + <width>170</width> + <height>28</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <label>$LOCALIZE[403] :</label> + <textcolor>grey2</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.UVIndex))</visible> + </control> + <control type="label"> + <description>current Precipitation label</description> + <left>0</left> + <top>0</top> + <width>170</width> + <height>28</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <label>$LOCALIZE[33021] :</label> + <textcolor>grey2</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.Precipitation))</visible> + </control> + <control type="label"> + <description>current Wind label</description> + <left>0</left> + <top>0</top> + <width>170</width> + <height>28</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <label>$LOCALIZE[404] :</label> + <textcolor>grey2</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.Wind))</visible> + </control> </control> - <control type="label"> - <description>current feels like Value</description> + <control type="grouplist"> <left>185</left> <top>400</top> <width>300</width> - <height>35</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(Current.FeelsLike)]$INFO[System.TemperatureUnits]</label> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current dew Value</description> - <left>185</left> - <top>430</top> - <width>300</width> - <height>35</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(Current.DewPoint)]$INFO[System.TemperatureUnits]</label> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current humidity Value</description> - <left>185</left> - <top>460</top> - <width>300</width> - <height>35</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <info>Window.Property(Current.Humidity)</info> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current UV Index Value</description> - <left>185</left> - <top>490</top> - <width>300</width> - <height>35</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <info>Window.Property(Current.UVIndex)</info> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <description>current Wind Value</description> - <left>185</left> - <top>520</top> - <width>300</width> - <height>35</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <info>Window.Property(Current.Wind)</info> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> + <height>180</height> + <itemgap>0</itemgap> + <control type="label"> + <description>current feels like Value</description> + <left>0</left> + <top>0</top> + <width>300</width> + <height>28</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(Current.FeelsLike)]$INFO[System.TemperatureUnits]</label> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.FeelsLike))</visible> + </control> + <control type="label"> + <description>current dew Value</description> + <left>0</left> + <top>0</top> + <width>300</width> + <height>28</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(Current.DewPoint)]$INFO[System.TemperatureUnits]</label> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.DewPoint))</visible> + </control> + <control type="label"> + <description>current humidity Value</description> + <left>0</left> + <top>0</top> + <width>300</width> + <height>28</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <info>Window.Property(Current.Humidity)</info> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.Humidity))</visible> + </control> + <control type="label"> + <description>current UV Index Value</description> + <left>0</left> + <top>0</top> + <width>300</width> + <height>28</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <info>Window.Property(Current.UVIndex)</info> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.UVIndex))</visible> + </control> + <control type="label"> + <description>current Precipitation Value</description> + <left>0</left> + <top>0</top> + <width>300</width> + <height>28</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <info>Window.Property(Current.Precipitation)</info> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.Precipitation))</visible> + </control> + <control type="label"> + <description>current Wind Value</description> + <left>0</left> + <top>0</top> + <width>300</width> + <height>28</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <info>Window.Property(Current.Wind)</info> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Current.Wind))</visible> + </control> </control> <control type="group"> - <visible>!IsEmpty(Window.Property(36Hour.IsFetched))</visible> + <visible>!IsEmpty(Window.Property(Today.IsFetched))</visible> <control type="label"> <description>Sunrise Label</description> <left>30</left> @@ -347,6 +399,7 @@ <label>$LOCALIZE[33027] : [COLOR=white]$INFO[Window.Property(Today.Sunrise)][/COLOR]</label> <textcolor>grey2</textcolor> <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Today.Sunrise))</visible> </control> <control type="label"> <description>Sunset label</description> @@ -360,339 +413,11 @@ <label>$LOCALIZE[33028] : [COLOR=white]$INFO[Window.Property(Today.Sunset)][/COLOR]</label> <textcolor>grey2</textcolor> <shadowcolor>black</shadowcolor> + <visible>!IsEmpty(Window.Property(Today.Sunset))</visible> </control> </control> </control> <control type="group"> - <visible>IsEmpty(Window.Property(Today.IsFetched))</visible> - <left>580</left> - <top>40</top> - <control type="image"> - <left>0</left> - <top>0</top> - <width>650</width> - <height>620</height> - <texture border="20">ContentPanel.png</texture> - </control> - <control type="image"> - <left>0</left> - <top>612</top> - <width>650</width> - <height>64</height> - <texture border="10">ContentPanelMirror.png</texture> - </control> - <control type="image"> - <left>8</left> - <top>5</top> - <width>634</width> - <height>45</height> - <texture>dialogheader.png</texture> - </control> - <control type="label"> - <description>header label</description> - <left>20</left> - <top>15</top> - <width>610</width> - <height>30</height> - <font>font13_title</font> - <label>10508</label> - <align>center</align> - <aligny>center</aligny> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="list" id="50"> - <left>15</left> - <top>60</top> - <width>600</width> - <height>541</height> - <onleft>9000</onleft> - <onright>61</onright> - <onup>50</onup> - <ondown>50</ondown> - <viewtype label="535">list</viewtype> - <pagecontrol>61</pagecontrol> - <scrolltime>200</scrolltime> - <itemlayout height="135" width="600"> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,5,0,5">MenuItemNF.png</texture> - </control> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,5,0,5">MenuItemNF.png</texture> - </control> - <control type="label"> - <left>150</left> - <top>5</top> - <width>300</width> - <height>25</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <left>460</left> - <top>0</top> - <width>135</width> - <height>135</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[ListItem.ActualIcon]</texture> - </control> - <control type="label"> - <left>30</left> - <top>35</top> - <width>390</width> - <height>30</height> - <font>font13</font> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - <selectedcolor>selected</selectedcolor> - <align>left</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$LOCALIZE[419] : [/COLOR]$INFO[ListItem.Property(HighTemp)]$INFO[ListItem.Property(TempUnits)] [COLOR=grey2]$LOCALIZE[418] : [/COLOR]$INFO[ListItem.Property(LowTemp)]$INFO[ListItem.Property(TempUnits)]</label> - <visible>!IsEmpty(ListItem.Property(HighTemp))</visible> - </control> - <control type="textbox"> - <left>30</left> - <top>70</top> - <width>400</width> - <height>50</height> - <font>font13</font> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - <selectedcolor>selected</selectedcolor> - <align>left</align> - <label>$INFO[ListItem.Property(Outlook)]</label> - </control> - </itemlayout> - <focusedlayout height="135" width="600"> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,2,0,2">MenuItemNF.png</texture> - <visible>!Control.HasFocus(50)</visible> - <include>VisibleFadeEffect</include> - </control> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,2,0,2">MenuItemNF.png</texture> - <visible>!Control.HasFocus(50)</visible> - <include>VisibleFadeEffect</include> - </control> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="10">button-focus2.png</texture> - <visible>Control.HasFocus(50)</visible> - <include>VisibleFadeEffect</include> - </control> - <control type="label"> - <left>150</left> - <top>5</top> - <width>300</width> - <height>25</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <left>460</left> - <top>0</top> - <width>135</width> - <height>135</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[ListItem.ActualIcon]</texture> - </control> - <control type="label"> - <left>30</left> - <top>35</top> - <width>390</width> - <height>30</height> - <font>font13</font> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - <selectedcolor>selected</selectedcolor> - <align>left</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$LOCALIZE[419] : [/COLOR]$INFO[ListItem.Property(HighTemp)]$INFO[ListItem.Property(TempUnits)] [COLOR=grey2]$LOCALIZE[418] : [/COLOR]$INFO[ListItem.Property(LowTemp)]$INFO[ListItem.Property(TempUnits)]</label> - <visible>!IsEmpty(ListItem.Property(HighTemp))</visible> - </control> - <control type="textbox"> - <left>30</left> - <top>70</top> - <width>400</width> - <height>50</height> - <font>font13</font> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - <selectedcolor>selected</selectedcolor> - <align>left</align> - <label>$INFO[ListItem.Property(Outlook)]</label> - </control> - </focusedlayout> - <content> - <item> - <label>$LOCALIZE[31909]</label> - <icon>-</icon> - <onclick>noop</onclick> - <visible>!Weather.IsFetched</visible> - </item> - <item> - <label>$INFO[Window.Property(Day0.Title)]</label> - <icon>$INFO[Window.Property(Day0.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day0.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day0.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day0.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day0.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day1.Title)]</label> - <icon>$INFO[Window.Property(Day1.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day1.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day1.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day1.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day1.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day2.Title)]</label> - <icon>$INFO[Window.Property(Day2.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day2.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day2.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day2.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day2.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day3.Title)]</label> - <icon>$INFO[Window.Property(Day3.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day3.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day3.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day3.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day3.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day4.Title)]</label> - <icon>$INFO[Window.Property(Day4.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day4.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day4.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day4.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day4.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day5.Title)]</label> - <icon>$INFO[Window.Property(Day5.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day5.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day5.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day5.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day5.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day6.Title)]</label> - <icon>$INFO[Window.Property(Day6.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day6.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day6.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day6.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day6.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day7.Title)]</label> - <icon>$INFO[Window.Property(Day7.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day7.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day7.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day7.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day7.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day8.Title)]</label> - <icon>$INFO[Window.Property(Day8.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day8.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day8.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day8.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day8.Title))</visible> - </item> - <item> - <label>$INFO[Window.Property(Day9.Title)]</label> - <icon>$INFO[Window.Property(Day9.OutlookIcon)]</icon> - <property name="HighTemp">$INFO[Window.Property(Day9.HighTemp)]</property> - <property name="LowTemp">$INFO[Window.Property(Day9.LowTemp)]</property> - <property name="Outlook">$INFO[Window.Property(Day9.Outlook)]</property> - <property name="TempUnits">$INFO[System.TemperatureUnits]</property> - <onclick>noop</onclick> - <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day9.Title))</visible> - </item> - </content> - </control> - <control type="scrollbar" id="61"> - <left>615</left> - <top>60</top> - <width>25</width> - <height>540</height> - <texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground> - <texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar> - <texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus> - <textureslidernib>ScrollBarNib.png</textureslidernib> - <textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus> - <onleft>50</onleft> - <onright>9000</onright> - <showonepage>true</showonepage> - <orientation>vertical</orientation> - <visible>Control.IsVisible(50)</visible> - </control> - <control type="label"> - <animation effect="slide" start="0,0" end="-90,0" time="0" condition="system.getbool(input.enablemouse)">Conditional</animation> - <description>number of files/pages</description> - <left>90</left> - <top>627</top> - <width>570</width> - <font>font12</font> - <align>right</align> - <scroll>true</scroll> - <textcolor>grey</textcolor> - <shadowcolor>black</shadowcolor> - <label>([COLOR=blue]$INFO[Container(50).NumItems][/COLOR]) $LOCALIZE[12393] - $LOCALIZE[31024] ([COLOR=blue]$INFO[Container(50).CurrentPage]/$INFO[Container(50).NumPages][/COLOR])</label> - </control> - </control> - <control type="group"> - <visible>!IsEmpty(Window.Property(Today.IsFetched))</visible> <left>580</left> <top>40</top> <control type="image"> @@ -717,11 +442,12 @@ <texture>dialogheader.png</texture> </control> <control type="group" id="50"> - <include condition="!IsEmpty(Window.Property(Daily.IsFetched))">Weather10DayForcast</include> - <include condition="!IsEmpty(Window.Property(36Hour.IsFetched))">Weather36HourForcast</include> - <include condition="!IsEmpty(Window.Property(Weekend.IsFetched))">WeatherWeekendForcast</include> - <include condition="!IsEmpty(Window.Property(Hourly.IsFetched))">WeatherHourlyForcast</include> - <include condition="!IsEmpty(Window.Property(Alerts.IsFetched)) + !IsEmpty(Window.Property(Map.IsFetched))">WeatherMapAlerts</include> + <include>WeatherDaily</include> + <include>Weather36Hour</include> + <include>WeatherWeekend</include> + <include>WeatherHourly</include> + <include>WeatherMaps</include> + <include>WeatherAlerts</include> </control> </control> </control> @@ -778,7 +504,7 @@ </control> </control> <control type="button" id="302"> - <description>10 day forcast button</description> + <description>Daily forcast button</description> <textwidth>235</textwidth> <include>ButtonCommonValues</include> <label>31904</label> @@ -810,12 +536,20 @@ <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> </control> <control type="button" id="306"> - <description>Map and alerts button</description> + <description>Maps button</description> <textwidth>235</textwidth> <include>ButtonCommonValues</include> <label>31910</label> <onfocus>SetProperty(Weather.CurrentView,map)</onfocus> - <visible>!IsEmpty(Window.Property(Alerts.IsFetched)) + !IsEmpty(Window.Property(Map.IsFetched))">WeatherMapAlerts</visible> + <visible>!IsEmpty(Window.Property(Map.IsFetched))</visible> + </control> + <control type="button" id="307"> + <description>Alerts button</description> + <textwidth>235</textwidth> + <include>ButtonCommonValues</include> + <label>33050</label> + <onfocus>SetProperty(Weather.CurrentView,alerts)</onfocus> + <visible>!IsEmpty(Window.Property(Alerts.IsFetched))</visible> </control> <control type="label" id="201"> <width>250</width> diff --git a/addons/skin.confluence/720p/ProfileSettings.xml b/addons/skin.confluence/720p/ProfileSettings.xml index 17aba87c75..0bd1a8ae42 100644 --- a/addons/skin.confluence/720p/ProfileSettings.xml +++ b/addons/skin.confluence/720p/ProfileSettings.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <window> - <defaultcontrol>1</defaultcontrol> <coordinates> <system>1</system> <left>290</left> diff --git a/addons/skin.confluence/720p/ViewsWeather.xml b/addons/skin.confluence/720p/ViewsWeather.xml new file mode 100644 index 0000000000..0ef41a1cb8 --- /dev/null +++ b/addons/skin.confluence/720p/ViewsWeather.xml @@ -0,0 +1,1568 @@ +<?xml version="1.0" encoding="UTF-8"?> +<includes> + <include name="WeatherDaily"> + <control type="group"> + <control type="label"> + <description>header label</description> + <left>20</left> + <top>15</top> + <width>610</width> + <height>30</height> + <font>font13_title</font> + <label>31904</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <include>VisibleFadeEffect</include> + <visible>Control.IsVisible(51)</visible> + </control> + <control type="list" id="51"> + <left>15</left> + <top>60</top> + <width>600</width> + <height>541</height> + <onleft>9000</onleft> + <onright>61</onright> + <onup>51</onup> + <ondown>51</ondown> + <viewtype label="535">list</viewtype> + <pagecontrol>61</pagecontrol> + <scrolltime>200</scrolltime> + <include>VisibleFadeEffect</include> + <visible>IsEmpty(Window.Property(Weather.CurrentView))</visible> + <itemlayout height="135" width="600" condition="IsEmpty(Window.Property(Daily.IsFetched))"> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,5,0,5">MenuItemNF.png</texture> + </control> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,5,0,5">MenuItemNF.png</texture> + </control> + <control type="label"> + <left>150</left> + <top>5</top> + <width>300</width> + <height>25</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <left>460</left> + <top>0</top> + <width>135</width> + <height>135</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[ListItem.ActualIcon]</texture> + </control> + <control type="label"> + <left>30</left> + <top>35</top> + <width>390</width> + <height>30</height> + <font>font13</font> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <selectedcolor>selected</selectedcolor> + <align>left</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$LOCALIZE[419] : [/COLOR]$INFO[ListItem.Property(HighTemp)]$INFO[ListItem.Property(TempUnits)] [COLOR=grey2]$LOCALIZE[418] : [/COLOR]$INFO[ListItem.Property(LowTemp)]$INFO[ListItem.Property(TempUnits)]</label> + <visible>!IsEmpty(ListItem.Property(HighTemp))</visible> + </control> + <control type="textbox"> + <left>30</left> + <top>70</top> + <width>400</width> + <height>50</height> + <font>font13</font> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <selectedcolor>selected</selectedcolor> + <align>left</align> + <label>$INFO[ListItem.Property(Outlook)]</label> + </control> + </itemlayout> + <focusedlayout height="135" width="600" condition="IsEmpty(Window.Property(Daily.IsFetched))"> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,2,0,2">MenuItemNF.png</texture> + <visible>!Control.HasFocus(51)</visible> + <include>VisibleFadeEffect</include> + </control> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,2,0,2">MenuItemNF.png</texture> + <visible>!Control.HasFocus(51)</visible> + <include>VisibleFadeEffect</include> + </control> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="10">button-focus2.png</texture> + <visible>Control.HasFocus(51)</visible> + <include>VisibleFadeEffect</include> + </control> + <control type="label"> + <left>150</left> + <top>5</top> + <width>300</width> + <height>25</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <left>460</left> + <top>0</top> + <width>135</width> + <height>135</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[ListItem.ActualIcon]</texture> + </control> + <control type="label"> + <left>30</left> + <top>35</top> + <width>390</width> + <height>30</height> + <font>font13</font> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <selectedcolor>selected</selectedcolor> + <align>left</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$LOCALIZE[419] : [/COLOR]$INFO[ListItem.Property(HighTemp)]$INFO[ListItem.Property(TempUnits)] [COLOR=grey2]$LOCALIZE[418] : [/COLOR]$INFO[ListItem.Property(LowTemp)]$INFO[ListItem.Property(TempUnits)]</label> + <visible>!IsEmpty(ListItem.Property(HighTemp))</visible> + </control> + <control type="textbox"> + <left>30</left> + <top>70</top> + <width>400</width> + <height>50</height> + <font>font13</font> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <selectedcolor>selected</selectedcolor> + <align>left</align> + <label>$INFO[ListItem.Property(Outlook)]</label> + </control> + </focusedlayout> + <itemlayout height="135" width="600" condition="!IsEmpty(Window.Property(Daily.IsFetched))"> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,5,0,5">MenuItemNF.png</texture> + </control> + <control type="label"> + <left>0</left> + <top>0</top> + <width>100</width> + <height>120</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <left>110</left> + <top>5</top> + <width>80</width> + <height>80</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[ListItem.Thumb]</texture> + </control> + <control type="label"> + <left>200</left> + <top>0</top> + <width>390</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>right</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="textbox"> + <left>5</left> + <top>80</top> + <width>590</width> + <height>50</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[ListItem.ActualIcon]</label> + </control> + </itemlayout> + <focusedlayout height="135" width="600" condition="!IsEmpty(Window.Property(Daily.IsFetched))"> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,2,0,2">MenuItemNF.png</texture> + <visible>!Control.HasFocus(51)</visible> + <include>VisibleFadeEffect</include> + </control> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="10">button-focus2.png</texture> + <visible>Control.HasFocus(51)</visible> + <include>VisibleFadeEffect</include> + </control> + <control type="label"> + <left>0</left> + <top>0</top> + <width>100</width> + <height>120</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <left>110</left> + <top>5</top> + <width>80</width> + <height>80</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[ListItem.Thumb]</texture> + </control> + <control type="label"> + <left>200</left> + <top>0</top> + <width>390</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>right</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="textbox"> + <left>5</left> + <top>80</top> + <width>590</width> + <height>50</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[ListItem.ActualIcon]</label> + </control> + </focusedlayout> + <content> + <item> + <label>-</label> + <icon>-</icon> + <onclick>noop</onclick> + <visible>!Weather.IsFetched</visible> + </item> + <item> + <label>$INFO[Window.Property(Day0.Title)]</label> + <icon>$INFO[Window.Property(Day0.OutlookIcon)]</icon> + <property name="HighTemp">$INFO[Window.Property(Day0.HighTemp)]</property> + <property name="LowTemp">$INFO[Window.Property(Day0.LowTemp)]</property> + <property name="Outlook">$INFO[Window.Property(Day0.Outlook)]</property> + <property name="TempUnits">$INFO[System.TemperatureUnits]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day0.Outlook)) + IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Day1.Title)]</label> + <icon>$INFO[Window.Property(Day1.OutlookIcon)]</icon> + <property name="HighTemp">$INFO[Window.Property(Day1.HighTemp)]</property> + <property name="LowTemp">$INFO[Window.Property(Day1.LowTemp)]</property> + <property name="Outlook">$INFO[Window.Property(Day1.Outlook)]</property> + <property name="TempUnits">$INFO[System.TemperatureUnits]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day1.Outlook)) + IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Day2.Title)]</label> + <icon>$INFO[Window.Property(Day2.OutlookIcon)]</icon> + <property name="HighTemp">$INFO[Window.Property(Day2.HighTemp)]</property> + <property name="LowTemp">$INFO[Window.Property(Day2.LowTemp)]</property> + <property name="Outlook">$INFO[Window.Property(Day2.Outlook)]</property> + <property name="TempUnits">$INFO[System.TemperatureUnits]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day2.Outlook)) + IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Day3.Title)]</label> + <icon>$INFO[Window.Property(Day3.OutlookIcon)]</icon> + <property name="HighTemp">$INFO[Window.Property(Day3.HighTemp)]</property> + <property name="LowTemp">$INFO[Window.Property(Day3.LowTemp)]</property> + <property name="Outlook">$INFO[Window.Property(Day3.Outlook)]</property> + <property name="TempUnits">$INFO[System.TemperatureUnits]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day3.Outlook)) + IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Day4.Title)]</label> + <icon>$INFO[Window.Property(Day4.OutlookIcon)]</icon> + <property name="HighTemp">$INFO[Window.Property(Day4.HighTemp)]</property> + <property name="LowTemp">$INFO[Window.Property(Day4.LowTemp)]</property> + <property name="Outlook">$INFO[Window.Property(Day4.Outlook)]</property> + <property name="TempUnits">$INFO[System.TemperatureUnits]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day4.Outlook)) + IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Day5.Title)]</label> + <icon>$INFO[Window.Property(Day5.OutlookIcon)]</icon> + <property name="HighTemp">$INFO[Window.Property(Day5.HighTemp)]</property> + <property name="LowTemp">$INFO[Window.Property(Day5.LowTemp)]</property> + <property name="Outlook">$INFO[Window.Property(Day5.Outlook)]</property> + <property name="TempUnits">$INFO[System.TemperatureUnits]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day5.Outlook)) + IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Day6.Title)]</label> + <icon>$INFO[Window.Property(Day6.OutlookIcon)]</icon> + <property name="HighTemp">$INFO[Window.Property(Day6.HighTemp)]</property> + <property name="LowTemp">$INFO[Window.Property(Day6.LowTemp)]</property> + <property name="Outlook">$INFO[Window.Property(Day6.Outlook)]</property> + <property name="TempUnits">$INFO[System.TemperatureUnits]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Day6.Outlook)) + IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.1.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.1.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.1.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.1.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.1.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.1.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.1.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.1.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.1.WindSpeed)] $INFO[Window.Property(Daily.1.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.1.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.2.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.2.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.2.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.2.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.2.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.2.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.2.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.2.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.2.WindSpeed)] $INFO[Window.Property(Daily.2.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.2.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.3.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.3.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.3.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.3.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.3.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.3.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.3.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.3.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.3.WindSpeed)] $INFO[Window.Property(Daily.3.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.3.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.4.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.4.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.4.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.4.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.4.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.4.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.4.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.4.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.4.WindSpeed)] $INFO[Window.Property(Daily.4.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.4.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.5.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.5.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.5.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.5.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.5.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.5.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.5.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.5.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.5.WindSpeed)] $INFO[Window.Property(Daily.5.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.5.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.6.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.6.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.6.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.6.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.6.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.6.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.6.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.6.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.6.WindSpeed)] $INFO[Window.Property(Daily.6.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.6.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.7.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.7.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.7.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.7.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.7.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.7.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.7.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.7.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.7.WindSpeed)] $INFO[Window.Property(Daily.7.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.7.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.8.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.8.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.8.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.8.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.8.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.8.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.8.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.8.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.8.WindSpeed)] $INFO[Window.Property(Daily.8.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.8.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.9.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.9.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.9.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.9.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.9.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.9.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.9.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.9.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.9.WindSpeed)] $INFO[Window.Property(Daily.9.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.9.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.10.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.10.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.10.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.10.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.10.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.10.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.10.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.10.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.10.WindSpeed)] $INFO[Window.Property(Daily.10.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.10.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.11.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.11.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.11.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.11.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.11.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.11.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.11.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.11.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.11.WindSpeed)] $INFO[Window.Property(Daily.11.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.11.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.12.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.12.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.12.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.12.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.12.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.12.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.12.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.12.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.12.WindSpeed)] $INFO[Window.Property(Daily.12.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.12.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.13.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.13.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.13.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.13.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.13.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.13.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.13.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.13.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.13.WindSpeed)] $INFO[Window.Property(Daily.13.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.13.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Daily.4.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.4.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Daily.4.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.4.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.4.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.14.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Daily.4.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Daily.4.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.4.WindSpeed)] $INFO[Window.Property(Daily.4.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Daily.14.Outlook)) + !IsEmpty(Window.Property(Daily.IsFetched))</visible> + </item> + </content> + </control> + <control type="scrollbar" id="61"> + <left>615</left> + <top>60</top> + <width>25</width> + <height>540</height> + <texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground> + <texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar> + <texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus> + <textureslidernib>ScrollBarNib.png</textureslidernib> + <textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus> + <onleft>51</onleft> + <onright>9000</onright> + <showonepage>true</showonepage> + <orientation>vertical</orientation> + <visible>Control.IsVisible(51)</visible> + </control> + <control type="label"> + <animation effect="slide" start="0,0" end="-90,0" time="0" condition="system.getbool(input.enablemouse)">Conditional</animation> + <description>number of files/pages</description> + <left>90</left> + <top>627</top> + <width>570</width> + <font>font12</font> + <align>right</align> + <scroll>true</scroll> + <textcolor>grey</textcolor> + <shadowcolor>black</shadowcolor> + <label>([COLOR=blue]$INFO[Container(51).NumItems][/COLOR]) $LOCALIZE[12393] - $LOCALIZE[31024] ([COLOR=blue]$INFO[Container(51).CurrentPage]/$INFO[Container(51).NumPages][/COLOR])</label> + <visible>Control.IsVisible(51)</visible> + </control> + </control> + </include> + <include name="Weather36Hour"> + <control type="group"> + <visible>StringCompare(Window.Property(Weather.CurrentView),36hour) + !IsEmpty(Window.Property(36Hour.IsFetched))</visible> + <include>VisibleFadeEffect</include> + <control type="button" id="997"> + <description>Hidden Button for focus</description> + <left>-600</left> + <top>-20</top> + <width>1</width> + <height>1</height> + <texturenofocus>-</texturenofocus> + <texturefocus>-</texturefocus> + <onleft>9000</onleft> + <onright>9000</onright> + </control> + <control type="label"> + <description>header label</description> + <left>20</left> + <top>15</top> + <width>610</width> + <height>30</height> + <font>font13_title</font> + <label>31901</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="group"> + <left>20</left> + <top>50</top> + <control type="group"> + <left>0</left> + <top>0</top> + <control type="label"> + <left>0</left> + <top>5</top> + <width>600</width> + <height>30</height> + <font>font13_title</font> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(36Hour.1.Heading)]</label> + </control> + <control type="image"> + <left>0</left> + <top>10</top> + <width>120</width> + <height>110</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[Window.Property(36Hour.1.OutlookIcon)]</texture> + </control> + <control type="label"> + <left>120</left> + <top>40</top> + <width>100</width> + <height>40</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$INFO[Window.Property(36Hour.1.TemperatureHeading)][CR][/COLOR]$INFO[Window.Property(36Hour.1.Temperature),[B] ,[/B]]</label> + </control> + <control type="label"> + <right>90</right> + <top>20</top> + <width>390</width> + <height>130</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>right</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(36Hour.1.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(36Hour.1.Precipitation),[COLOR=grey2]$LOCALIZE[33021] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(36Hour.1.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label> + </control> + <control type="textbox"> + <left>0</left> + <top>145</top> + <width>590</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[Window.Property(36hour.1.Outlook),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]]</label> + </control> + <control type="image"> + <left>0</left> + <top>180</top> + <width>650</width> + <height>4</height> + <texture>separator.png</texture> + </control> + </control> + <control type="group"> + <left>0</left> + <top>185</top> + <control type="label"> + <left>0</left> + <top>5</top> + <width>600</width> + <height>30</height> + <font>font13_title</font> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(36Hour.2.Heading)]</label> + </control> + <control type="image"> + <left>0</left> + <top>10</top> + <width>120</width> + <height>110</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[Window.Property(36Hour.2.OutlookIcon)]</texture> + </control> + <control type="label"> + <left>120</left> + <top>40</top> + <width>100</width> + <height>40</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$INFO[Window.Property(36Hour.2.TemperatureHeading)][CR][/COLOR]$INFO[Window.Property(36Hour.2.Temperature),[B] ,[/B]]</label> + </control> + <control type="label"> + <right>90</right> + <top>20</top> + <width>390</width> + <height>130</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>right</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(36Hour.2.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(36Hour.2.Precipitation),[COLOR=grey2]$LOCALIZE[33021] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(36Hour.2.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label> + </control> + <control type="textbox"> + <left>0</left> + <top>145</top> + <width>590</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[Window.Property(36hour.2.Outlook),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]]</label> + </control> + <control type="image"> + <left>0</left> + <top>180</top> + <width>650</width> + <height>4</height> + <texture>separator.png</texture> + </control> + </control> + <control type="group"> + <left>0</left> + <top>370</top> + <control type="label"> + <left>0</left> + <top>5</top> + <width>600</width> + <height>30</height> + <font>font13_title</font> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(36Hour.3.Heading)]</label> + </control> + <control type="image"> + <left>0</left> + <top>10</top> + <width>120</width> + <height>110</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[Window.Property(36Hour.3.OutlookIcon)]</texture> + </control> + <control type="label"> + <left>120</left> + <top>40</top> + <width>100</width> + <height>40</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$INFO[Window.Property(36Hour.3.TemperatureHeading)][CR][/COLOR]$INFO[Window.Property(36Hour.3.Temperature),[B] ,[/B]]</label> + </control> + <control type="label"> + <right>90</right> + <top>20</top> + <width>390</width> + <height>130</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>right</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(36Hour.3.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(36Hour.3.Precipitation),[COLOR=grey2]$LOCALIZE[33021] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(36Hour.3.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]]</label> + </control> + <control type="textbox"> + <left>0</left> + <top>145</top> + <width>590</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[Window.Property(36hour.3.Outlook),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]]</label> + </control> + </control> + </control> + </control> + </include> + <include name="WeatherWeekend"> + <control type="group"> + <visible>StringCompare(Window.Property(Weather.CurrentView),weekend) + !IsEmpty(Window.Property(Weekend.IsFetched))</visible> + <include>VisibleFadeEffect</include> + <control type="button" id="998"> + <description>Hidden Button for focus</description> + <left>-600</left> + <top>-20</top> + <width>1</width> + <height>1</height> + <texturenofocus>-</texturenofocus> + <texturefocus>-</texturefocus> + <onleft>9000</onleft> + <onright>9000</onright> + </control> + <control type="label"> + <description>header label</description> + <left>20</left> + <top>15</top> + <width>610</width> + <height>30</height> + <font>font13_title</font> + <label>31903</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="group"> + <left>20</left> + <top>50</top> + <control type="group"> + <left>0</left> + <top>0</top> + <control type="label"> + <left>0</left> + <top>5</top> + <width>600</width> + <height>30</height> + <font>font13_title</font> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(Weekend.1.LongDay)] - $INFO[Window.Property(Weekend.1.ShortDate)]</label> + </control> + <control type="image"> + <left>10</left> + <top>20</top> + <width>130</width> + <height>160</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[Window.Property(Weekend.1.OutlookIcon)]</texture> + </control> + <control type="label"> + <left>140</left> + <top>40</top> + <width>100</width> + <height>50</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$LOCALIZE[393][CR][/COLOR]$INFO[Window.Property(Weekend.1.HighTemperature),[B] ,[/B]]</label> + </control> + <control type="label"> + <left>140</left> + <top>100</top> + <width>100</width> + <height>50</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$LOCALIZE[391][CR][/COLOR]$INFO[Window.Property(Weekend.1.LowTemperature),[B] ,[/B]]</label> + </control> + <control type="textbox"> + <left>240</left> + <top>40</top> + <width>350</width> + <height>130</height> + <font>font12</font> + <textcolor>white</textcolor> + <align>right</align> + <label>$INFO[Window.Property(Weekend.1.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.1.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.1.Precipitation),[COLOR=grey2]$LOCALIZE[33021] :[/COLOR][B] ,[/B]]</label> + </control> + <control type="label"> + <left>0</left> + <top>180</top> + <width>590</width> + <height>20</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(Weekend.1.WindSpeed),[COLOR=grey2]$LOCALIZE[404]: [/COLOR]]$INFO[Window.Property(Weekend.1.WindDirection), - ]</label> + </control> + <control type="textbox"> + <left>0</left> + <top>215</top> + <width>590</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[Window.Property(Weekend.1.Outlook),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]][CR]</label> + </control> + <control type="image"> + <left>0</left> + <top>270</top> + <width>650</width> + <height>4</height> + <texture>separator.png</texture> + </control> + </control> + <control type="group"> + <left>0</left> + <top>280</top> + <control type="label"> + <left>0</left> + <top>5</top> + <width>600</width> + <height>30</height> + <font>font13_title</font> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(Weekend.2.LongDay)] - $INFO[Window.Property(Weekend.2.ShortDate)]</label> + </control> + <control type="image"> + <left>10</left> + <top>20</top> + <width>130</width> + <height>160</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[Window.Property(Weekend.2.OutlookIcon)]</texture> + </control> + <control type="label"> + <left>140</left> + <top>40</top> + <width>100</width> + <height>50</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$LOCALIZE[393][CR][/COLOR]$INFO[Window.Property(Weekend.2.HighTemperature),[B] ,[/B]]</label> + </control> + <control type="label"> + <left>140</left> + <top>100</top> + <width>100</width> + <height>50</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>[COLOR=grey2]$LOCALIZE[391][CR][/COLOR]$INFO[Window.Property(Weekend.2.LowTemperature),[B] ,[/B]]</label> + </control> + <control type="textbox"> + <left>240</left> + <top>40</top> + <width>350</width> + <height>130</height> + <font>font12</font> + <textcolor>white</textcolor> + <align>right</align> + <label>$INFO[Window.Property(Weekend.2.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.2.Cloudiness),[COLOR=grey2]$LOCALIZE[387] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.2.Precipitation),[COLOR=grey2]$LOCALIZE[33021] :[/COLOR][B] ,[/B]]</label> + </control> + <control type="label"> + <left>0</left> + <top>180</top> + <width>590</width> + <height>20</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(Weekend.2.WindSpeed),[COLOR=grey2]$LOCALIZE[404]: [/COLOR]]$INFO[Window.Property(Weekend.2.WindDirection), - ]</label> + </control> + <control type="textbox"> + <left>0</left> + <top>215</top> + <width>590</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[Window.Property(Weekend.2.Outlook),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]][CR]</label> + </control> + </control> + </control> + </control> + </include> + <include name="WeatherHourly"> + <control type="group"> + <control type="label"> + <description>header label</description> + <left>20</left> + <top>15</top> + <width>610</width> + <height>30</height> + <font>font13_title</font> + <label>31902</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + <include>VisibleFadeEffect</include> + <visible>Control.IsVisible(52)</visible> + </control> + <control type="list" id="52"> + <left>15</left> + <top>60</top> + <width>600</width> + <height>541</height> + <onleft>9000</onleft> + <onright>62</onright> + <onup>52</onup> + <ondown>52</ondown> + <viewtype label="535">list</viewtype> + <pagecontrol>62</pagecontrol> + <scrolltime>200</scrolltime> + <include>VisibleFadeEffect</include> + <visible>StringCompare(Window.Property(Weather.CurrentView),hourly) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + <itemlayout height="135" width="600"> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,5,0,5">MenuItemNF.png</texture> + </control> + <control type="label"> + <left>0</left> + <top>0</top> + <width>100</width> + <height>120</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <left>110</left> + <top>5</top> + <width>80</width> + <height>80</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[ListItem.Thumb]</texture> + </control> + <control type="label"> + <left>200</left> + <top>5</top> + <width>390</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>right</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="textbox"> + <left>5</left> + <top>80</top> + <width>590</width> + <height>50</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[ListItem.ActualIcon]</label> + </control> + </itemlayout> + <focusedlayout height="135" width="600"> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="0,2,0,2">MenuItemNF.png</texture> + <visible>!Control.HasFocus(52)</visible> + <include>VisibleFadeEffect</include> + </control> + <control type="image"> + <left>0</left> + <top>0</top> + <width>600</width> + <height>136</height> + <texture border="10">button-focus2.png</texture> + <visible>Control.HasFocus(52)</visible> + <include>VisibleFadeEffect</include> + </control> + <control type="label"> + <left>0</left> + <top>0</top> + <width>100</width> + <height>120</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <left>110</left> + <top>5</top> + <width>80</width> + <height>80</height> + <aspectratio>keep</aspectratio> + <texture>$INFO[ListItem.Thumb]</texture> + </control> + <control type="label"> + <left>200</left> + <top>5</top> + <width>390</width> + <height>70</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>right</align> + <aligny>center</aligny> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="textbox"> + <left>5</left> + <top>80</top> + <width>590</width> + <height>50</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[ListItem.ActualIcon]</label> + </control> + </focusedlayout> + <content> + <item> + <icon>$LOCALIZE[31909]</icon> + <onclick>noop</onclick> + <visible>IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.1.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.1.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.1.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.1.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.1.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.1.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.1.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.1.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.1.WindSpeed)] $INFO[Window.Property(Hourly.1.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.1.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.2.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.2.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.2.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.2.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.2.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.2.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.2.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.2.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.2.WindSpeed)] $INFO[Window.Property(Hourly.2.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.2.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.3.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.3.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.3.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.3.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.3.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.3.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.3.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.3.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.3.WindSpeed)] $INFO[Window.Property(Hourly.3.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.3.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.4.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.4.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.4.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.4.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.4.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.4.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.4.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.4.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.4.WindSpeed)] $INFO[Window.Property(Hourly.4.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.4.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.5.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.5.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.5.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.5.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.5.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.5.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.5.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.5.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.5.WindSpeed)] $INFO[Window.Property(Hourly.5.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.5.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.6.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.6.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.6.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.6.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.6.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.6.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.6.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.6.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.6.WindSpeed)] $INFO[Window.Property(Hourly.6.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.6.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.7.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.7.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.7.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.7.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.7.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.7.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.7.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.7.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.7.WindSpeed)] $INFO[Window.Property(Hourly.7.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.7.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.8.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.8.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.8.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.8.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.8.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.8.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.8.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.8.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.8.WindSpeed)] $INFO[Window.Property(Hourly.8.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.8.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.9.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.9.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.9.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.9.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.9.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.9.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.9.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.9.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.9.WindSpeed)] $INFO[Window.Property(Hourly.9.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.9.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.10.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.10.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.10.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.10.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.10.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.10.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.10.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.10.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.10.WindSpeed)] $INFO[Window.Property(Hourly.10.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.10.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.11.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.11.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.11.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.11.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.11.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.11.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.11.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.11.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.11.WindSpeed)] $INFO[Window.Property(Hourly.11.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.11.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.12.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.12.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.12.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.12.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.12.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.12.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.12.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.12.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.12.WindSpeed)] $INFO[Window.Property(Hourly.12.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.12.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.13.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.13.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.13.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.13.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.13.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.13.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.13.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.13.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.13.WindSpeed)] $INFO[Window.Property(Hourly.13.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.13.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.14.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.14.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.14.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.14.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.14.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.14.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.14.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.14.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.14.WindSpeed)] $INFO[Window.Property(Hourly.14.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.14.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.15.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.15.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.15.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.15.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.15.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.15.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.15.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.15.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.15.WindSpeed)] $INFO[Window.Property(Hourly.15.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.15.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.16.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.16.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.16.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.16.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.16.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.16.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.16.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.16.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.16.WindSpeed)] $INFO[Window.Property(Hourly.16.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.16.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.17.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.17.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.17.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.17.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.17.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.17.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.17.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.17.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.17.WindSpeed)] $INFO[Window.Property(Hourly.17.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.17.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.18.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.18.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.18.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.18.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.18.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.18.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.18.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.18.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.18.WindSpeed)] $INFO[Window.Property(Hourly.18.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.18.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.19.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.19.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.19.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.19.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.19.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.19.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.19.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.19.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.19.WindSpeed)] $INFO[Window.Property(Hourly.19.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.19.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.20.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.20.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.20.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.20.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.20.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.20.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.20.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.20.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.20.WindSpeed)] $INFO[Window.Property(Hourly.20.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.20.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.21.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.21.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.21.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.21.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.21.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.21.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.21.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.21.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.21.WindSpeed)] $INFO[Window.Property(Hourly.21.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.21.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.22.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.22.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.22.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.22.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.22.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.22.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.22.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.22.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.22.WindSpeed)] $INFO[Window.Property(Hourly.22.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.22.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.23.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.23.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.23.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.23.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.23.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.23.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.23.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.23.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.23.WindSpeed)] $INFO[Window.Property(Hourly.23.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.23.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + <item> + <label>[B]$INFO[Window.Property(Hourly.24.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.24.ShortDate)][/COLOR]</label> + <label2>$INFO[Window.Property(Hourly.24.Temperature),[COLOR=grey2]$LOCALIZE[401] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.24.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.24.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.24.Precipitation),[COLOR=grey2]$LOCALIZE[1448] :[/COLOR][B] ,[/B]]</label2> + <thumb>$INFO[Window.Property(Hourly.24.OutlookIcon)]</thumb> + <icon>$INFO[Window.Property(Hourly.24.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.24.WindSpeed)] $INFO[Window.Property(Hourly.24.WindDirection)]</icon> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Hourly.24.Outlook)) + !IsEmpty(Window.Property(Hourly.IsFetched))</visible> + </item> + </content> + </control> + <control type="scrollbar" id="62"> + <left>615</left> + <top>60</top> + <width>25</width> + <height>540</height> + <texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground> + <texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar> + <texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus> + <textureslidernib>ScrollBarNib.png</textureslidernib> + <textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus> + <onleft>52</onleft> + <onright>9000</onright> + <showonepage>true</showonepage> + <orientation>vertical</orientation> + <include>VisibleFadeEffect</include> + <visible>Control.IsVisible(52)</visible> + </control> + <control type="label"> + <animation effect="slide" start="0,0" end="-90,0" time="0" condition="system.getbool(input.enablemouse)">Conditional</animation> + <description>number of files/pages</description> + <right>40</right> + <top>627</top> + <width>570</width> + <font>font12</font> + <align>right</align> + <scroll>true</scroll> + <textcolor>grey</textcolor> + <shadowcolor>black</shadowcolor> + <label>([COLOR=blue]$INFO[Container(52).NumItems][/COLOR]) $LOCALIZE[31025] - $LOCALIZE[31024] ([COLOR=blue]$INFO[Container(52).CurrentPage]/$INFO[Container(52).NumPages][/COLOR])</label> + <include>VisibleFadeEffect</include> + <visible>Control.IsVisible(52)</visible> + </control> + </control> + </include> + <include name="WeatherMaps"> + <control type="group"> + <visible>StringCompare(Window.Property(Weather.CurrentView),map) + !IsEmpty(Window.Property(Map.IsFetched))</visible> + <include>VisibleFadeEffect</include> + <control type="label"> + <description>header label</description> + <left>20</left> + <top>15</top> + <width>610</width> + <height>30</height> + <font>font13_title</font> + <label>31910</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="image"> + <description>Background image</description> + <left>25</left> + <top>65</top> + <width>600</width> + <height>480</height> + <texture border="5">button-nofocus.png</texture> + </control> + <control type="button" id="992"> + <left>580</left> + <top>565</top> + <width>25</width> + <height>25</height> + <label>-</label> + <texturefocus>scroll-right-focus.png</texturefocus> + <texturenofocus>scroll-right.png</texturenofocus> + <onleft>991</onleft> + <onright>9000</onright> + <onclick>Control.Move(53,1)</onclick> + </control> + <control type="button" id="991"> + <left>45</left> + <top>565</top> + <width>25</width> + <height>25</height> + <label>-</label> + <texturefocus>scroll-left-focus.png</texturefocus> + <texturenofocus>scroll-left.png</texturenofocus> + <onleft>9000</onleft> + <onright>992</onright> + <onclick>Control.Move(53,-1)</onclick> + </control> + <control type="label"> + <description>heading label</description> + <left>75</left> + <top>565</top> + <width>500</width> + <height>30</height> + <font>font13_title</font> + <label>$INFO[Container(53).ListItem.Label]</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="list" id="53"> + <left>30</left> + <top>70</top> + <width>590</width> + <height>470</height> + <onleft>9000</onleft> + <onright>9000</onright> + <onup>9000</onup> + <ondown>9000</ondown> + <viewtype label="535">list</viewtype> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <include>VisibleFadeEffect</include> + <visible>StringCompare(Window.Property(Weather.CurrentView),map) + !IsEmpty(Window.Property(Map.IsFetched))</visible> + <itemlayout height="470" width="590"> + <control type="image"> + <description>area image</description> + <left>0</left> + <top>0</top> + <width>590</width> + <height>470</height> + <texture>$INFO[ListItem.Icon]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <description>layer image</description> + <left>0</left> + <top>0</top> + <width>590</width> + <height>470</height> + <texture>$INFO[ListItem.Property(Layer)]</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>70FFFFFF</colordiffuse> + </control> + <control type="image"> + <description>legend image</description> + <left>360</left> + <top>430</top> + <width>224</width> + <height>35</height> + <texture>$INFO[ListItem.Label2]</texture> + </control> + </itemlayout> + <focusedlayout height="490" width="590"> + <control type="image"> + <description>layer image</description> + <left>0</left> + <top>0</top> + <width>590</width> + <height>470</height> + <texture>$INFO[ListItem.Icon]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <description>area image</description> + <left>0</left> + <top>0</top> + <width>590</width> + <height>470</height> + <texture>$INFO[ListItem.Property(Layer)]</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>70FFFFFF</colordiffuse> + </control> + <control type="image"> + <description>legend image</description> + <left>360</left> + <top>430</top> + <width>224</width> + <height>35</height> + <texture>$INFO[ListItem.Label2]</texture> + </control> + </focusedlayout> + <content> + <item> + <label>$INFO[Window.Property(Map.1.Heading)]</label> + <label2>$INFO[Window.Property(Map.1.Legend)]</label2> + <icon>$INFO[Window.Property(Map.1.Area)]</icon> + <property name="Layer">$INFO[Window.Property(Map.1.Layer)]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Map.1.Area)) + !IsEmpty(Window.Property(Map.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Map.2.Heading)]</label> + <label2>$INFO[Window.Property(Map.2.Legend)]</label2> + <icon>$INFO[Window.Property(Map.2.Area)]</icon> + <property name="Layer">$INFO[Window.Property(Map.2.Layer)]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Map.2.Area)) + !IsEmpty(Window.Property(Map.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Map.3.Heading)]</label> + <label2>$INFO[Window.Property(Map.3.Legend)]</label2> + <icon>$INFO[Window.Property(Map.3.Area)]</icon> + <property name="Layer">$INFO[Window.Property(Map.3.Layer)]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Map.3.Area)) + !IsEmpty(Window.Property(Map.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Map.4.Heading)]</label> + <label2>$INFO[Window.Property(Map.4.Legend)]</label2> + <icon>$INFO[Window.Property(Map.4.Area)]</icon> + <property name="Layer">$INFO[Window.Property(Map.4.Layer)]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Map.4.Area)) + !IsEmpty(Window.Property(Map.IsFetched))</visible> + </item> + <item> + <label>$INFO[Window.Property(Map.5.Heading)]</label> + <label2>$INFO[Window.Property(Map.5.Legend)]</label2> + <icon>$INFO[Window.Property(Map.5.Area)]</icon> + <property name="Layer">$INFO[Window.Property(Map.5.Layer)]</property> + <onclick>noop</onclick> + <visible>Weather.IsFetched + !IsEmpty(Window.Property(Map.5.Area)) + !IsEmpty(Window.Property(Map.IsFetched))</visible> + </item> + </content> + </control> + <control type="image"> + <left>0</left> + <top>550</top> + <width>650</width> + <height>4</height> + <texture>separator.png</texture> + </control> + </control> + </include> + <include name="WeatherAlerts"> + <control type="group"> + <visible>StringCompare(Window.Property(Weather.CurrentView),alerts) + !IsEmpty(Window.Property(Alerts.IsFetched))</visible> + <include>VisibleFadeEffect</include> + <control type="button" id="996"> + <description>Hidden Button for focus</description> + <left>-600</left> + <top>-20</top> + <width>1</width> + <height>1</height> + <texturenofocus>-</texturenofocus> + <texturefocus>-</texturefocus> + <onleft>9000</onleft> + <onright>9000</onright> + </control> + <control type="label"> + <description>header label</description> + <left>20</left> + <top>15</top> + <width>610</width> + <height>30</height> + <font>font13_title</font> + <label>33050</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <left>40</left> + <top>75</top> + <width>570</width> + <height>30</height> + <font>font13_title</font> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>$LOCALIZE[33050]</label> + </control> + <control type="group"> + <visible>!StringCompare(Window.Property(Alerts.Count),0)</visible> + <control type="textbox"> + <left>40</left> + <top>115</top> + <width>570</width> + <height>400</height> + <font>font12</font> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <align>center</align> + <label>$INFO[Window.Property(Alerts)]</label> + <autoscroll time="2000" delay="3000" repeat="5000">Skin.HasSetting(AutoScroll)</autoscroll> + </control> + </control> + <control type="label"> + <left>40</left> + <top>200</top> + <width>570</width> + <height>30</height> + <font>font13_title</font> + <textcolor>white</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>$LOCALIZE[19055]</label> + <visible>StringCompare(Window.Property(Alerts.Count),0)</visible> + </control> + </control> + </include> +</includes> diff --git a/addons/skin.confluence/720p/includes.xml b/addons/skin.confluence/720p/includes.xml index 4948a3c503..6aa3350785 100644 --- a/addons/skin.confluence/720p/includes.xml +++ b/addons/skin.confluence/720p/includes.xml @@ -8,35 +8,31 @@ <include file="ViewsAddonBrowser.xml"/> <include file="ViewsLiveTV.xml"/> <include file="ViewsPVRGuide.xml"/> + <include file="ViewsWeather.xml"/> <include file="IncludesCodecFlagging.xml"/> <include file="IncludesHomeRecentlyAdded.xml"/> <include file="IncludesHomeMenuItems.xml"/> <include file="IncludesPVR.xml"/> <include file="IncludesBackgroundBuilding.xml"/> - <include file="weather\10DayForecast.xml"/> - <include file="weather\36HourForecast.xml"/> - <include file="weather\WeekendForecast.xml"/> - <include file="weather\HourlyForecast.xml"/> - <include file="weather\MapAlerts.xml"/> <constant name="FanartCrossfadeTime">500</constant> <constant name="IconCrossfadeTime">400</constant> <variable name="BannerThumb"> <value condition="!IsEmpty(ListItem.Art(banner))">$INFO[ListItem.Art(banner)]</value> - <value condition="IsEmpty(ListItem.Art(banner))">$INFO[ListItem.Icon]</value> + <value>$INFO[ListItem.Icon]</value> </variable> <variable name="PosterThumb"> <value condition="!IsEmpty(ListItem.Art(poster))">$INFO[ListItem.Art(poster)]</value> - <value condition="IsEmpty(ListItem.Art(poster))">$INFO[ListItem.Icon]</value> + <value>$INFO[ListItem.Icon]</value> </variable> <variable name="PlayList"> <value condition="Window.IsActive(videolibrary) + !StringCompare(Playlist.Length(video),0)">ActivateWindow(videoplaylist)</value> - <value condition="[Window.IsActive(musiclibrary) | Window.IsActive(musicfiles)] + !StringCompare(Playlist.Length(music),0)">ActivateWindow(musicplaylist)</value> + <value>ActivateWindow(musicplaylist)</value> </variable> <variable name="SelectBack"> <value condition="![Window.IsVisible(FullscreenVideo) | Window.IsVisible(Visualisation)]">DialogBack.png</value> - <value condition="Window.IsVisible(FullscreenVideo) | Window.IsVisible(Visualisation)">DialogBack2.png</value> + <value>DialogBack2.png</value> </variable> <include name="BehindDialogFadeOut"> @@ -48,7 +44,7 @@ <texture>black-back.png</texture> <animation effect="fade" time="400">Visible</animation> <animation effect="fade" time="200">Hidden</animation> - <visible>Window.IsActive(MovieInformation) | Window.IsActive(MusicInformation) | Window.IsActive(SongInformation) | Window.IsActive(FileBrowser) | Window.IsActive(TextViewer) | Window.IsActive(AddonSettings) | Window.IsActive(ContentSettings) | Window.IsActive(SelectDialog) | Window.IsActive(FileStackingDialog) | Window.IsActive(MediaSource) | Window.IsActive(PictureInfo) | Window.IsActive(PlayerControls) | Window.IsActive(VirtualKeyboard) | Window.IsActive(NumericInput) | Window.IsActive(ProfileSettings) | Window.IsActive(LockSettings) | Window.IsActive(SmartPlaylistEditor) | Window.IsActive(SmartPlaylistRule) | Window.IsActive(script-RSS_Editor-rssEditor.xml) | Window.IsActive(script-RSS_Editor-setEditor.xml) | Window.IsActive(AddonInformation) | Window.IsActive(Peripherals) | Window.IsActive(PeripheralSettings) | Window.IsActive(script-XBMC_Lyrics-main.xml) | Window.IsActive(PVRChannelManager) | Window.IsActive(MediaFilter)</visible> + <visible>Window.IsActive(MovieInformation) | Window.IsActive(MusicInformation) | Window.IsActive(SongInformation) | Window.IsActive(FileBrowser) | Window.IsActive(TextViewer) | Window.IsActive(AddonSettings) | Window.IsActive(ContentSettings) | Window.IsActive(SelectDialog) | Window.IsActive(FileStackingDialog) | Window.IsActive(MediaSource) | Window.IsActive(PictureInfo) | Window.IsActive(PlayerControls) | Window.IsActive(VirtualKeyboard) | Window.IsActive(NumericInput) | Window.IsActive(ProfileSettings) | Window.IsActive(LockSettings) | Window.IsActive(SmartPlaylistEditor) | Window.IsActive(SmartPlaylistRule) | Window.IsActive(script-RSS_Editor-rssEditor.xml) | Window.IsActive(script-RSS_Editor-setEditor.xml) | Window.IsActive(AddonInformation) | Window.IsActive(Peripherals) | Window.IsActive(PeripheralSettings) | Window.IsActive(script-cu-lrclyrics-main.xml) | Window.IsActive(PVRChannelManager) | Window.IsActive(MediaFilter)</visible> </control> </include> <include name="WindowTitleCommons"> @@ -902,7 +898,6 @@ <label>13350</label> <onclick>$VAR[PlayList]</onclick> <visible>[Window.IsActive(videolibrary) + !StringCompare(Playlist.Length(video),0)] | [[Window.IsActive(musiclibrary) | Window.IsActive(musicfiles)] + !StringCompare(Playlist.Length(music),0)]</visible> - <visible>!Window.IsVisible(MusicPlaylist) + !Window.IsVisible(VideoPlaylist)</visible> </control> </include> <include name="ScrollOffsetLabel"> diff --git a/addons/skin.confluence/720p/weather/10DayForecast.xml b/addons/skin.confluence/720p/weather/10DayForecast.xml deleted file mode 100644 index e0edfb2119..0000000000 --- a/addons/skin.confluence/720p/weather/10DayForecast.xml +++ /dev/null @@ -1,266 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<includes> - <include name="Weather10DayForcast"> - <control type="group"> - <visible>IsEmpty(Window.Property(Weather.CurrentView))</visible> - <include>VisibleFadeEffect</include> - <control type="label"> - <description>header label</description> - <left>20</left> - <top>15</top> - <width>610</width> - <height>30</height> - <font>font13_title</font> - <label>31904</label> - <align>center</align> - <aligny>center</aligny> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="list" id="51"> - <left>15</left> - <top>60</top> - <width>600</width> - <height>541</height> - <onleft>9000</onleft> - <onright>61</onright> - <onup>51</onup> - <ondown>51</ondown> - <viewtype label="535">list</viewtype> - <pagecontrol>61</pagecontrol> - <scrolltime>200</scrolltime> - <itemlayout height="135" width="600"> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,5,0,5">MenuItemNF.png</texture> - </control> - <control type="label"> - <left>0</left> - <top>0</top> - <width>100</width> - <height>120</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <left>110</left> - <top>5</top> - <width>80</width> - <height>80</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[ListItem.Thumb]</texture> - </control> - <control type="label"> - <left>200</left> - <top>0</top> - <width>390</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>right</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="textbox"> - <left>5</left> - <top>80</top> - <width>590</width> - <height>50</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[ListItem.ActualIcon]</label> - </control> - </itemlayout> - <focusedlayout height="135" width="600"> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,2,0,2">MenuItemNF.png</texture> - <visible>!Control.HasFocus(51)</visible> - <include>VisibleFadeEffect</include> - </control> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="10">button-focus2.png</texture> - <visible>Control.HasFocus(51)</visible> - <include>VisibleFadeEffect</include> - </control> - <control type="label"> - <left>0</left> - <top>0</top> - <width>100</width> - <height>120</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <left>110</left> - <top>5</top> - <width>80</width> - <height>80</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[ListItem.Thumb]</texture> - </control> - <control type="label"> - <left>200</left> - <top>0</top> - <width>390</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>right</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="textbox"> - <left>5</left> - <top>80</top> - <width>590</width> - <height>50</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[ListItem.ActualIcon]</label> - </control> - </focusedlayout> - <content> - <item> - <icon>$LOCALIZE[31909]</icon> - <onclick>noop</onclick> - <visible>IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.1.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.1.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.1.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.1.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.1.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.1.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.1.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.1.WindSpeed)] $INFO[Window.Property(Daily.1.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.2.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.2.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.2.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.2.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.2.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.2.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.2.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.2.WindSpeed)] $INFO[Window.Property(Daily.2.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.3.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.3.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.3.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.3.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.3.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.3.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.3.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.3.WindSpeed)] $INFO[Window.Property(Daily.3.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.4.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.4.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.4.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.4.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.4.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.4.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.4.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.4.WindSpeed)] $INFO[Window.Property(Daily.4.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.5.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.5.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.5.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.5.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.5.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.5.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.5.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.5.WindSpeed)] $INFO[Window.Property(Daily.5.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.6.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.6.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.6.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.6.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.6.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.6.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.6.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.6.WindSpeed)] $INFO[Window.Property(Daily.6.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.7.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.7.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.7.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.7.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.7.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.7.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.7.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.7.WindSpeed)] $INFO[Window.Property(Daily.7.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.8.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.8.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.8.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.8.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.8.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.8.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.8.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.8.WindSpeed)] $INFO[Window.Property(Daily.8.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.9.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.9.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.9.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.9.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.9.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.9.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.9.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.9.WindSpeed)] $INFO[Window.Property(Daily.9.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Daily.10.ShortDay)][/B][CR][COLOR=grey2]$INFO[Window.Property(Daily.10.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Daily.10.HighTemperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Daily.10.LowTemperature),[COLOR=grey2]$LOCALIZE[418] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Daily.10.Precipitation),[COLOR=grey2]$LOCALIZE[33022] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Daily.10.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Daily.10.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Daily.10.WindSpeed)] $INFO[Window.Property(Daily.10.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Daily.IsFetched))</visible> - </item> - </content> - </control> - <control type="scrollbar" id="61"> - <left>615</left> - <top>60</top> - <width>25</width> - <height>540</height> - <texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground> - <texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar> - <texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus> - <textureslidernib>ScrollBarNib.png</textureslidernib> - <textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus> - <onleft>51</onleft> - <onright>9000</onright> - <showonepage>true</showonepage> - <orientation>vertical</orientation> - <visible>Control.IsVisible(50)</visible> - </control> - <control type="label"> - <animation effect="slide" start="0,0" end="-90,0" time="0" condition="system.getbool(input.enablemouse)">Conditional</animation> - <description>number of files/pages</description> - <right>40</right> - <top>627</top> - <width>570</width> - <font>font12</font> - <align>right</align> - <scroll>true</scroll> - <textcolor>grey</textcolor> - <shadowcolor>black</shadowcolor> - <label>([COLOR=blue]$INFO[Container(51).NumItems][/COLOR]) $LOCALIZE[31025] - $LOCALIZE[31024] ([COLOR=blue]$INFO[Container(51).CurrentPage]/$INFO[Container(51).NumPages][/COLOR])</label> - </control> - </control> - </include> -</includes> diff --git a/addons/skin.confluence/720p/weather/36HourForecast.xml b/addons/skin.confluence/720p/weather/36HourForecast.xml deleted file mode 100644 index ff5a5e14b1..0000000000 --- a/addons/skin.confluence/720p/weather/36HourForecast.xml +++ /dev/null @@ -1,239 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<includes> - <include name="Weather36HourForcast"> - <control type="group"> - <visible>StringCompare(Window.Property(Weather.CurrentView),36hour)</visible> - <include>VisibleFadeEffect</include> - <control type="button" id="997"> - <description>Hidden Button for focus</description> - <left>-600</left> - <top>-20</top> - <width>1</width> - <height>1</height> - <texturenofocus>-</texturenofocus> - <texturefocus>-</texturefocus> - <onleft>9000</onleft> - <onright>9000</onright> - </control> - <control type="label"> - <description>header label</description> - <left>20</left> - <top>15</top> - <width>610</width> - <height>30</height> - <font>font13_title</font> - <label>31901</label> - <align>center</align> - <aligny>center</aligny> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <left>0</left> - <top>200</top> - <width>600</width> - <height>30</height> - <font>font13</font> - <textcolor>white</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$LOCALIZE[31909]</label> - <visible>IsEmpty(Window.Property(36Hour.IsFetched))</visible> - </control> - <control type="group"> - <left>20</left> - <top>50</top> - <visible>!IsEmpty(Window.Property(36Hour.IsFetched))</visible> - <include>VisibleFadeEffect</include> - <control type="group"> - <left>0</left> - <top>0</top> - <control type="label"> - <left>0</left> - <top>5</top> - <width>600</width> - <height>30</height> - <font>font13_title</font> - <textcolor>blue</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(36Hour.1.Heading)]</label> - </control> - <control type="image"> - <left>0</left> - <top>10</top> - <width>120</width> - <height>110</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[Window.Property(36Hour.1.OutlookIcon)]</texture> - </control> - <control type="label"> - <left>120</left> - <top>40</top> - <width>100</width> - <height>40</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$INFO[Window.Property(36Hour.1.TemperatureHeading)][CR][/COLOR]$INFO[Window.Property(36Hour.1.Temperature),[B] ,[/B]]</label> - </control> - <control type="label"> - <right>90</right> - <top>60</top> - <width>390</width> - <height>20</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>right</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(36Hour.1.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label> - </control> - <control type="textbox"> - <left>0</left> - <top>110</top> - <width>590</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[Window.Property(36hour.1.Forecast),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]]</label> - </control> - <control type="image"> - <left>0</left> - <top>180</top> - <width>650</width> - <height>4</height> - <texture>separator.png</texture> - </control> - </control> - <control type="group"> - <left>0</left> - <top>185</top> - <control type="label"> - <left>0</left> - <top>5</top> - <width>600</width> - <height>30</height> - <font>font13_title</font> - <textcolor>blue</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(36Hour.2.Heading)]</label> - </control> - <control type="image"> - <left>0</left> - <top>10</top> - <width>120</width> - <height>110</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[Window.Property(36Hour.2.OutlookIcon)]</texture> - </control> - <control type="label"> - <left>120</left> - <top>40</top> - <width>100</width> - <height>40</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$INFO[Window.Property(36Hour.2.TemperatureHeading)][CR][/COLOR]$INFO[Window.Property(36Hour.2.Temperature),[B] ,[/B]]</label> - </control> - <control type="label"> - <right>90</right> - <top>60</top> - <width>390</width> - <height>20</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>right</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(36Hour.2.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label> - </control> - <control type="textbox"> - <left>0</left> - <top>110</top> - <width>590</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[Window.Property(36hour.2.Forecast),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]]</label> - </control> - <control type="image"> - <left>0</left> - <top>180</top> - <width>650</width> - <height>4</height> - <texture>separator.png</texture> - </control> - </control> - <control type="group"> - <left>0</left> - <top>370</top> - <control type="label"> - <left>0</left> - <top>5</top> - <width>600</width> - <height>30</height> - <font>font13_title</font> - <textcolor>blue</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(36Hour.3.Heading)]</label> - </control> - <control type="image"> - <left>0</left> - <top>10</top> - <width>120</width> - <height>110</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[Window.Property(36Hour.3.OutlookIcon)]</texture> - </control> - <control type="label"> - <left>120</left> - <top>40</top> - <width>100</width> - <height>40</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$INFO[Window.Property(36Hour.3.TemperatureHeading)][CR][/COLOR]$INFO[Window.Property(36Hour.3.Temperature),[B] ,[/B]]</label> - </control> - <control type="label"> - <right>90</right> - <top>60</top> - <width>390</width> - <height>20</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>right</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(36Hour.3.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label> - </control> - <control type="textbox"> - <left>0</left> - <top>110</top> - <width>590</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[Window.Property(36hour.3.Forecast),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]]</label> - </control> - </control> - </control> - </control> - </include> -</includes> diff --git a/addons/skin.confluence/720p/weather/HourlyForecast.xml b/addons/skin.confluence/720p/weather/HourlyForecast.xml deleted file mode 100644 index 526648ed70..0000000000 --- a/addons/skin.confluence/720p/weather/HourlyForecast.xml +++ /dev/null @@ -1,282 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<includes> - <include name="WeatherHourlyForcast"> - <control type="group"> - <visible>StringCompare(Window.Property(Weather.CurrentView),hourly)</visible> - <include>VisibleFadeEffect</include> - <control type="label"> - <description>header label</description> - <left>20</left> - <top>15</top> - <width>610</width> - <height>30</height> - <font>font13_title</font> - <label>31902</label> - <align>center</align> - <aligny>center</aligny> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="list" id="52"> - <left>15</left> - <top>60</top> - <width>600</width> - <height>541</height> - <onleft>9000</onleft> - <onright>62</onright> - <onup>52</onup> - <ondown>52</ondown> - <viewtype label="535">list</viewtype> - <pagecontrol>62</pagecontrol> - <scrolltime>200</scrolltime> - <itemlayout height="135" width="600"> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,5,0,5">MenuItemNF.png</texture> - </control> - <control type="label"> - <left>0</left> - <top>0</top> - <width>100</width> - <height>120</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <left>110</left> - <top>5</top> - <width>80</width> - <height>80</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[ListItem.Thumb]</texture> - </control> - <control type="label"> - <left>200</left> - <top>5</top> - <width>390</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>right</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="textbox"> - <left>5</left> - <top>80</top> - <width>590</width> - <height>50</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[ListItem.ActualIcon]</label> - </control> - </itemlayout> - <focusedlayout height="135" width="600"> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="0,2,0,2">MenuItemNF.png</texture> - <visible>!Control.HasFocus(52)</visible> - <include>VisibleFadeEffect</include> - </control> - <control type="image"> - <left>0</left> - <top>0</top> - <width>600</width> - <height>136</height> - <texture border="10">button-focus2.png</texture> - <visible>Control.HasFocus(52)</visible> - <include>VisibleFadeEffect</include> - </control> - <control type="label"> - <left>0</left> - <top>0</top> - <width>100</width> - <height>120</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <left>110</left> - <top>5</top> - <width>80</width> - <height>80</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[ListItem.Thumb]</texture> - </control> - <control type="label"> - <left>200</left> - <top>5</top> - <width>390</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>right</align> - <aligny>center</aligny> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="textbox"> - <left>5</left> - <top>80</top> - <width>590</width> - <height>50</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[ListItem.ActualIcon]</label> - </control> - </focusedlayout> - <content> - <item> - <icon>$LOCALIZE[31909]</icon> - <onclick>noop</onclick> - <visible>IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.1.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.1.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.1.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.1.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.1.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.1.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.1.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.1.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.1.WindSpeed)] $INFO[Window.Property(Hourly.1.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.2.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.2.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.2.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.2.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.2.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.2.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.2.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.2.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.2.WindSpeed)] $INFO[Window.Property(Hourly.2.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.3.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.3.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.3.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.3.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.3.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.3.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.3.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.3.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.3.WindSpeed)] $INFO[Window.Property(Hourly.3.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.4.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.4.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.4.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.4.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.4.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.4.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.4.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.4.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.4.WindSpeed)] $INFO[Window.Property(Hourly.4.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.5.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.5.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.5.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.5.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.5.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.5.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.5.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.5.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.5.WindSpeed)] $INFO[Window.Property(Hourly.5.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.6.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.6.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.6.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.6.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.6.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.6.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.6.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.6.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.6.WindSpeed)] $INFO[Window.Property(Hourly.6.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.7.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.7.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.7.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.7.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.7.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.7.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.7.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.7.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.7.WindSpeed)] $INFO[Window.Property(Hourly.7.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.8.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.8.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.8.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.8.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.8.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.8.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.8.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.8.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.8.WindSpeed)] $INFO[Window.Property(Hourly.8.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.9.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.9.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.9.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.9.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.9.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.9.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.9.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.9.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.9.WindSpeed)] $INFO[Window.Property(Hourly.9.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.10.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.10.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.10.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.10.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.10.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.10.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.10.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.10.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.10.WindSpeed)] $INFO[Window.Property(Hourly.10.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.11.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.11.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.11.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.11.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.11.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.11.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.11.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.11.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.11.WindSpeed)] $INFO[Window.Property(Hourly.11.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - <item> - <label>[B]$INFO[Window.Property(Hourly.12.Time)][/B][CR][COLOR=grey2]$INFO[Window.Property(Hourly.12.ShortDate)][/COLOR]</label> - <label2>$INFO[Window.Property(Hourly.12.Temperature),[COLOR=grey2]$LOCALIZE[419] :[/COLOR][B] ,[/B]] $INFO[Window.Property(Hourly.12.FeelsLike),[COLOR=grey2]$LOCALIZE[402] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.12.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR]$INFO[Window.Property(Hourly.12.ChancePrecipitation),[COLOR=grey2]$LOCALIZE[31908] :[/COLOR][B] ,[/B]]</label2> - <thumb>$INFO[Window.Property(Hourly.12.OutlookIcon)]</thumb> - <icon>$INFO[Window.Property(Hourly.12.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]][CR][COLOR=grey2]$LOCALIZE[383]: [/COLOR]$INFO[Window.Property(Hourly.12.WindSpeed)] $INFO[Window.Property(Hourly.12.WindDirection)]</icon> - <onclick>noop</onclick> - <visible>!IsEmpty(Window.Property(Hourly.IsFetched))</visible> - </item> - </content> - </control> - <control type="scrollbar" id="62"> - <left>615</left> - <top>60</top> - <width>25</width> - <height>540</height> - <texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground> - <texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar> - <texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus> - <textureslidernib>ScrollBarNib.png</textureslidernib> - <textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus> - <onleft>52</onleft> - <onright>9000</onright> - <showonepage>true</showonepage> - <orientation>vertical</orientation> - <visible>Control.IsVisible(50)</visible> - </control> - <control type="label"> - <animation effect="slide" start="0,0" end="-90,0" time="0" condition="system.getbool(input.enablemouse)">Conditional</animation> - <description>number of files/pages</description> - <right>40</right> - <top>627</top> - <width>570</width> - <font>font12</font> - <align>right</align> - <scroll>true</scroll> - <textcolor>grey</textcolor> - <shadowcolor>black</shadowcolor> - <label>([COLOR=blue]$INFO[Container(52).NumItems][/COLOR]) $LOCALIZE[31025] - $LOCALIZE[31024] ([COLOR=blue]$INFO[Container(52).CurrentPage]/$INFO[Container(52).NumPages][/COLOR])</label> - </control> - </control> - </include> -</includes> diff --git a/addons/skin.confluence/720p/weather/MapAlerts.xml b/addons/skin.confluence/720p/weather/MapAlerts.xml deleted file mode 100644 index f49e74142d..0000000000 --- a/addons/skin.confluence/720p/weather/MapAlerts.xml +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<includes> - <include name="WeatherMapAlerts"> - <control type="group"> - <visible>StringCompare(Window.Property(Weather.CurrentView),map)</visible> - <include>VisibleFadeEffect</include> - <control type="button" id="999"> - <description>Hidden Button for focus</description> - <left>-600</left> - <top>-20</top> - <width>1</width> - <height>1</height> - <texturenofocus>-</texturenofocus> - <texturefocus>-</texturefocus> - <onleft>9000</onleft> - <onright>9000</onright> - </control> - <control type="label"> - <description>header label</description> - <left>20</left> - <top>15</top> - <width>610</width> - <height>30</height> - <font>font13_title</font> - <label>31910</label> - <align>center</align> - <aligny>center</aligny> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="image"> - <description>Background image</description> - <left>40</left> - <top>75</top> - <width>570</width> - <height>325</height> - <texture border="5">button-nofocus.png</texture> - </control> - <control type="multiimage"> - <description>map multiimage</description> - <left>45</left> - <top>80</top> - <width>560</width> - <height>315</height> - <imagepath>$INFO[Window.Property(MapPath)]</imagepath> - <timeperimage>500</timeperimage> - <pauseatend>1000</pauseatend> - <fadetime>0</fadetime> - <randomize>false</randomize> - <loop>yes</loop> - <aspectratio>keep</aspectratio> - <aligny>center</aligny> - </control> - <control type="image"> - <left>0</left> - <top>410</top> - <width>650</width> - <height>4</height> - <texture>separator.png</texture> - </control> - <control type="label"> - <left>40</left> - <top>430</top> - <width>570</width> - <height>30</height> - <font>font13_title</font> - <textcolor>blue</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$LOCALIZE[33050]</label> - </control> - <control type="group"> - <visible>!StringCompare(Window.Property(Alerts.Count),0)</visible> - <control type="textbox"> - <left>40</left> - <top>470</top> - <width>570</width> - <height>100</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[Window.Property(Alerts)]</label> - <autoscroll time="2000" delay="3000" repeat="5000">Skin.HasSetting(AutoScroll)</autoscroll> - </control> - </control> - <control type="label"> - <left>40</left> - <top>500</top> - <width>570</width> - <height>30</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$LOCALIZE[19055]</label> - <visible>StringCompare(Window.Property(Alerts.Count),0)</visible> - </control> - </control> - </include> -</includes> diff --git a/addons/skin.confluence/720p/weather/WeekendForecast.xml b/addons/skin.confluence/720p/weather/WeekendForecast.xml deleted file mode 100644 index 750a39e386..0000000000 --- a/addons/skin.confluence/720p/weather/WeekendForecast.xml +++ /dev/null @@ -1,218 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<includes> - <include name="WeatherWeekendForcast"> - <control type="group"> - <visible>StringCompare(Window.Property(Weather.CurrentView),weekend)</visible> - <include>VisibleFadeEffect</include> - <control type="button" id="998"> - <description>Hidden Button for focus</description> - <left>-600</left> - <top>-20</top> - <width>1</width> - <height>1</height> - <texturenofocus>-</texturenofocus> - <texturefocus>-</texturefocus> - <onleft>9000</onleft> - <onright>9000</onright> - </control> - <control type="label"> - <description>header label</description> - <left>20</left> - <top>15</top> - <width>610</width> - <height>30</height> - <font>font13_title</font> - <label>31903</label> - <align>center</align> - <aligny>center</aligny> - <textcolor>white</textcolor> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <left>0</left> - <top>200</top> - <width>600</width> - <height>30</height> - <font>font13</font> - <textcolor>white</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$LOCALIZE[31909]</label> - <visible>IsEmpty(Window.Property(Weekend.IsFetched))</visible> - </control> - <control type="group"> - <left>20</left> - <top>50</top> - <visible>!IsEmpty(Window.Property(Weekend.IsFetched))</visible> - <include>VisibleFadeEffect</include> - <control type="group"> - <left>0</left> - <top>0</top> - <control type="label"> - <left>0</left> - <top>5</top> - <width>600</width> - <height>30</height> - <font>font13_title</font> - <textcolor>blue</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(Weekend.1.LongDay)] - $INFO[Window.Property(Weekend.1.ShortDate)]</label> - </control> - <control type="image"> - <left>10</left> - <top>20</top> - <width>130</width> - <height>160</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[Window.Property(Weekend.1.OutlookIcon)]</texture> - </control> - <control type="label"> - <left>140</left> - <top>40</top> - <width>100</width> - <height>50</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$LOCALIZE[393][CR][/COLOR]$INFO[Window.Property(Weekend.1.HighTemperature),[B] ,[/B]]</label> - </control> - <control type="label"> - <left>140</left> - <top>100</top> - <width>100</width> - <height>50</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$LOCALIZE[391][CR][/COLOR]$INFO[Window.Property(Weekend.1.LowTemperature),[B] ,[/B]]</label> - </control> - <control type="textbox"> - <left>240</left> - <top>40</top> - <width>350</width> - <height>130</height> - <font>font12</font> - <textcolor>white</textcolor> - <align>right</align> - <label>$INFO[Window.Property(Weekend.1.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.1.ShortWindDirection),[COLOR=grey2]$LOCALIZE[404] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.1.Precipitation),[COLOR=grey2]$LOCALIZE[33021] :[/COLOR][B] ,[/B]]</label> - </control> - <control type="label"> - <left>0</left> - <top>170</top> - <width>590</width> - <height>20</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(Weekend.1.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]]</label> - </control> - <control type="textbox"> - <left>0</left> - <top>210</top> - <width>590</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[Window.Property(Weekend.1.LongOutlookDay),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]][CR]</label> - </control> - <control type="image"> - <left>0</left> - <top>270</top> - <width>650</width> - <height>4</height> - <texture>separator.png</texture> - </control> - </control> - <control type="group"> - <left>0</left> - <top>280</top> - <control type="label"> - <left>0</left> - <top>5</top> - <width>600</width> - <height>30</height> - <font>font13_title</font> - <textcolor>blue</textcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(Weekend.2.LongDay)] - $INFO[Window.Property(Weekend.2.ShortDate)]</label> - </control> - <control type="image"> - <left>10</left> - <top>20</top> - <width>130</width> - <height>160</height> - <aspectratio>keep</aspectratio> - <texture>$INFO[Window.Property(Weekend.2.OutlookIcon)]</texture> - </control> - <control type="label"> - <left>140</left> - <top>40</top> - <width>100</width> - <height>50</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$LOCALIZE[393][CR][/COLOR]$INFO[Window.Property(Weekend.2.HighTemperature),[B] ,[/B]]</label> - </control> - <control type="label"> - <left>140</left> - <top>100</top> - <width>100</width> - <height>50</height> - <font>font13_title</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>[COLOR=grey2]$LOCALIZE[391][CR][/COLOR]$INFO[Window.Property(Weekend.2.LowTemperature),[B] ,[/B]]</label> - </control> - <control type="textbox"> - <left>240</left> - <top>40</top> - <width>350</width> - <height>130</height> - <font>font12</font> - <textcolor>white</textcolor> - <align>right</align> - <label>$INFO[Window.Property(Weekend.2.Humidity),[COLOR=grey2]$LOCALIZE[406] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.2.ShortWindDirection),[COLOR=grey2]$LOCALIZE[404] :[/COLOR][B] ,[/B]][CR][CR]$INFO[Window.Property(Weekend.2.Precipitation),[COLOR=grey2]$LOCALIZE[33021] :[/COLOR][B] ,[/B]]</label> - </control> - <control type="label"> - <left>0</left> - <top>170</top> - <width>590</width> - <height>20</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(Weekend.2.Outlook),[COLOR=grey2]$LOCALIZE[33030]: [/COLOR]]</label> - </control> - <control type="textbox"> - <left>0</left> - <top>210</top> - <width>590</width> - <height>70</height> - <font>font12</font> - <textcolor>white</textcolor> - <selectedcolor>selected</selectedcolor> - <align>center</align> - <label>$INFO[Window.Property(Weekend.2.LongOutlookDay),[COLOR=grey2]$LOCALIZE[31905]: [/COLOR]][CR]</label> - </control> - </control> - </control> - </control> - </include> -</includes> diff --git a/addons/skin.confluence/language/English/strings.po b/addons/skin.confluence/language/English/strings.po index 9435a34e7b..8bfbd35096 100644 --- a/addons/skin.confluence/language/English/strings.po +++ b/addons/skin.confluence/language/English/strings.po @@ -534,7 +534,7 @@ msgstr "" #empty string with id 31407 msgctxt "#31408" -msgid "[B]CONFIGURE ADD-ONS[/B][CR][CR]Manage your installed Add-ons · Browse for and install Add-ons from xbmc.org[CR]Modify Add-on settings" +msgid "[B]CONFIGURE ADD-ONS[/B][CR][CR]Manage your installed Add-ons · Browse for and install Add-ons from kodi.tv[CR]Modify Add-on settings" msgstr "" msgctxt "#31409" @@ -631,7 +631,7 @@ msgid "Weekend Forecast" msgstr "" msgctxt "#31904" -msgid "10 Day Forecast" +msgid "Daily Forecast" msgstr "" msgctxt "#31905" @@ -649,7 +649,7 @@ msgid "Fetching forecast info..." msgstr "" msgctxt "#31910" -msgid "Map & Alerts" +msgid "Maps" msgstr "" #empty strings from id 31911 to 31949 diff --git a/addons/skin.re-touched b/addons/skin.re-touched -Subproject 1c4d55a3a701a37e5ebce44033e930bffd1b84b +Subproject 28b0836f5a1145ef68c6e4525056a1293a91d03 diff --git a/configure.in b/configure.in index 9b423ce33d..cc0b3951d2 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([xbmc], [13.9.705], [http://issues.xbmc.org]) +AC_INIT([kodi], [13.9.705], [http://issues.kodi.tv]) AC_CONFIG_HEADERS([xbmc/config.h]) AH_TOP([#pragma once]) m4_include([m4/ax_prog_cc_for_build.m4]) @@ -117,6 +117,7 @@ AC_DEFUN([XB_PUSH_FLAGS], [ # version can be overridden by setting the following as ENV vars when running configure APP_NAME=${APP_NAME-$(${AWK} '/APP_NAME/ {print $2}' version.txt)} +APP_NAME_LC=$(echo $APP_NAME | ${AWK} '{print tolower($0)}') APP_VERSION_MAJOR=${APP_VERSION_MAJOR-$(${AWK} '/VERSION_MAJOR/ {print $2}' version.txt)} APP_VERSION_MINOR=${APP_VERSION_MINOR-$(${AWK} '/VERSION_MINOR/ {print $2}' version.txt)} APP_VERSION_TAG=${APP_VERSION_TAG-$(${AWK} '/VERSION_TAG/ {print $2}' version.txt)} @@ -127,6 +128,7 @@ if test "$APP_NAME" != "" && test "$APP_VERSION_MAJOR" != "" && test "$APP_VERSI && test "$APP_VERSION_TAG" != "" && test "$APP_VERSION_CODE" != "" && test "$APP_ADDON_API" != ""; then final_message="$final_message\n ${APP_NAME} Version:\t${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}-${APP_VERSION_TAG}" AC_SUBST(APP_NAME) + AC_SUBST(APP_NAME_LC) AC_SUBST(APP_VERSION_MAJOR) AC_SUBST(APP_VERSION_MINOR) AC_SUBST(APP_VERSION_TAG) @@ -230,7 +232,7 @@ AC_ARG_WITH([ffmpeg], AC_ARG_ENABLE([shared-lib], [AS_HELP_STRING([--enable-shared-lib], - [build libxbmc. helpful for tests (default is no)])], + [build lib${APP_NAME_LC}. helpful for tests (default is no)])], [build_shared_lib=$enableval], [build_shared_lib=no]) @@ -1034,7 +1036,7 @@ else fi else AC_MSG_RESULT(== WARNING: OpenGL support is disabled. ${APP_NAME} will run VERY slow. ==) - AC_CHECK_LIB([SDL_gfx],[main]) + AC_CHECK_LIB([SDL2_gfx],[main]) fi fi @@ -1060,7 +1062,6 @@ AC_CHECK_HEADER([jpeglib.h],, AC_MSG_ERROR($missing_library)) AC_CHECK_HEADER([ogg/ogg.h],, AC_MSG_ERROR($missing_library)) AC_CHECK_HEADER([vorbis/vorbisfile.h],, AC_MSG_ERROR($missing_library)) AC_CHECK_HEADER([libmodplug/modplug.h],, AC_MSG_ERROR($missing_library)) -AC_CHECK_HEADER([FLAC/stream_decoder.h],, AC_MSG_ERROR($missing_library)) AC_CHECK_HEADER([curl/curl.h],, AC_MSG_ERROR($missing_library)) XB_FIND_SONAME([CURL], [curl]) @@ -1200,6 +1201,7 @@ if test "$host_vendor" = "apple" ; then if test "$use_arch" != "arm"; then AC_CHECK_LIB([SDL], [main],, AC_MSG_ERROR($missing_library)) AC_DEFINE([HAVE_SDL],[1],["Define to 1 if using sdl"]) + AC_DEFINE([SDL_VERSION],[1],["SDL major version"]) fi else if test "$target_platform" != "target_android" ; then @@ -1219,16 +1221,21 @@ else AC_MSG_NOTICE($dbus_disabled) fi if test "x$use_sdl" != "xno"; then - PKG_CHECK_MODULES([SDL], [sdl], - [INCLUDES="$INCLUDES $SDL_CFLAGS"; LIBS="$LIBS $SDL_LIBS"], - AC_MSG_ERROR($missing_library)) + PKG_CHECK_MODULES([SDL2], [sdl2], + [AC_DEFINE([SDL_VERSION],[2],["SDL major version"]) + INCLUDES="$INCLUDES $SDL2_CFLAGS"; LIBS="$LIBS $SDL2_LIBS";], + [PKG_CHECK_MODULES([SDL], [sdl], + [AC_DEFINE([SDL_VERSION],[1],["SDL major version"]) + INCLUDES="$INCLUDES $SDL_CFLAGS"; LIBS="$LIBS $SDL_LIBS"; use_joystick=no], + [AC_MSG_ERROR($missing_library)]) + ] + ) AC_CHECK_LIB([SDL_image], [main],, AC_MSG_ERROR($missing_library)) AC_DEFINE([HAVE_SDL],[1],["Define to 1 if using sdl"]) fi fi XB_FIND_SONAME([OGG], [ogg]) -XB_FIND_SONAME([FLAC], [FLAC]) XB_FIND_SONAME([VORBIS], [vorbis]) XB_FIND_SONAME([VORBISFILE], [vorbisfile]) XB_FIND_SONAME([MODPLUG], [modplug]) @@ -1333,6 +1340,9 @@ if test "$use_x11" = "yes" && test "$host_vendor" != "apple"; then PKG_CHECK_MODULES([XEXT], [xext], [INCLUDES="$INCLUDES $XEXT_CFLAGS"; LIBS="$LIBS $XEXT_LIBS"], AC_MSG_ERROR($missing_library)) + PKG_CHECK_MODULES([DRM], [libdrm], + [INCLUDES="$INCLUDES $DRM_CFLAGS"; LIBS="$LIBS $DRM_LIBS"], + AC_MSG_ERROR($missing_library)) AC_DEFINE([HAVE_X11], [1], [Define to 1 if you have X11 libs installed.]) else AC_MSG_RESULT($x11_disabled) @@ -2083,7 +2093,7 @@ fi if test "$use_joystick" = "yes"; then final_message="$final_message\n Joystick:\tYes" - SDL_DEFINES="$SDL_DEFINES -DHAS_SDL_JOYSTICK" + AC_DEFINE([HAS_SDL_JOYSTICK],[1],["Define to 1 if using SDL joystick"]) else final_message="$final_message\n Joystick:\tNo" fi @@ -2203,7 +2213,7 @@ else fi if test "x$use_pulse" != "xno"; then - XBMC_STANDALONE_SH_PULSE=tools/Linux/xbmc-standalone.sh.pulse + XBMC_STANDALONE_SH_PULSE=tools/Linux/${APP_NAME_LC}-standalone.sh.pulse final_message="$final_message\n PulseAudio:\tYes" else XBMC_STANDALONE_SH_PULSE=/dev/null @@ -2474,11 +2484,13 @@ OUTPUT_FILES="Makefile \ lib/addons/library.xbmc.gui/Makefile \ lib/addons/library.xbmc.pvr/Makefile \ xbmc/visualizations/EGLHelpers/Makefile \ - tools/Linux/xbmc.sh \ - tools/Linux/xbmc-standalone.sh \ + tools/Linux/${APP_NAME_LC}.sh \ + tools/Linux/${APP_NAME_LC}-standalone.sh \ + tools/Linux/${APP_NAME_LC}-xsession.desktop \ tools/Linux/FEH.py \ tools/Linux/FEH-ARM.py \ tools/TexturePacker/Makefile \ + tools/EventClients/Makefile \ tools/EventClients/Clients/OSXRemote/Makefile \ xbmc/peripherals/bus/Makefile \ xbmc/peripherals/devices/Makefile \ @@ -2489,12 +2501,23 @@ OUTPUT_FILES="Makefile \ xbmc/main/Makefile \ tools/darwin/Configurations/App.xcconfig \ tools/darwin/Configurations/Common.xcconfig \ - tools/darwin/packaging/xbmc-ios/mkdeb-xbmc-ios.sh \ - tools/darwin/packaging/xbmc-atv2/mkdeb-xbmc-atv2.sh \ - tools/darwin/packaging/xbmc-osx/mkdmg-xbmc-osx.sh \ + tools/darwin/packaging/ios/mkdeb-ios.sh \ + tools/darwin/packaging/atv2/mkdeb-atv2.sh \ + tools/darwin/packaging/osx/mkdmg-osx.sh \ + tools/darwin/packaging/migrate_to_kodi_ios.sh \ + tools/darwin/packaging/seatbeltunlock/mkdeb-seatbeltunlock.sh \ xbmc/osx/Info.plist \ + xbmc/osx/ios/XBMCIOS-Info.plist \ + xbmc/osx/atv2/XBMCATV2-Info.plist \ + project/cmake/kodi-config.cmake \ project/cmake/xbmc-config.cmake \ tools/android/packaging/xbmc/AndroidManifest.xml \ + tools/android/packaging/Makefile \ + tools/android/packaging/xbmc/src/org/xbmc/kodi/Splash.java \ + tools/android/packaging/xbmc/src/org/xbmc/kodi/Main.java \ + tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCBroadcastReceiver.java \ + tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCOnFrameAvailableListener.java \ + tools/android/packaging/xbmc/strings.xml \ addons/xbmc.addon/addon.xml" if test "$use_wayland" = "yes"; then @@ -2552,7 +2575,6 @@ AC_SUBST(OUTPUT_FILES) AC_SUBST(HAVE_XBMC_NONFREE) AC_SUBST(USE_ASAP_CODEC) AC_SUBST(LIBCURL_BASENAME) -AC_SUBST(LIBFLAC_BASENAME) AC_SUBST(LIBVORBISFILE_BASENAME) AC_SUBST(LIBMODPLUG_BASENAME) AC_SUBST(LIBOGG_BASENAME) diff --git a/docs/README.android b/docs/README.android index 48701d7396..dcb9382b29 100644 --- a/docs/README.android +++ b/docs/README.android @@ -4,8 +4,8 @@ TOC 3. Getting the source code 4. Installing the required Ubuntu packages 5. How to compile -6. Installing XBMC in an Android system -7. Running and debugging XBMC in an Android system +6. Installing Kodi in an Android system +7. Running and debugging Kodi in an Android system 8. Architecture 9. Useful Commands @@ -25,7 +25,7 @@ character itself should NOT be typed as part of the command. ----------------------------------------------------------------------------- 2. Installing the required Ubuntu packages ----------------------------------------------------------------------------- -These are the minimum packages necessary for building XBMC. Non-Ubuntu +These are the minimum packages necessary for building Kodi. Non-Ubuntu users will need to get the equivalents. # sudo apt-get install build-essential default-jdk git curl autoconf \ @@ -34,7 +34,7 @@ users will need to get the equivalents. If you run a 64bit operating system you will also need to get ia32-libs ubuntu >= 14.04: - # sudo apt-get install lib32stdc++6 lib32z1 lib32z1-de + # sudo apt-get install lib32stdc++6 lib32z1 lib32z1-dev older versions: # sudo apt-get install ia32-libs @@ -50,7 +50,7 @@ JRE: openjre-6-jre (java version "1.6.0_27") 3. Installing and setting up the Android environment ----------------------------------------------------------------------------- -To develop XBMC for Android the Android SDK and NDK are required. +To develop Kodi for Android the Android SDK and NDK are required. -------------------------------------------------------------------- 3.1. Getting the Android SDK and NDK @@ -60,7 +60,7 @@ To get the Android SDK, go to http://developer.android.com/sdk and download the latest version for your operating system. The NDK can be downloaded from http://developer.android.com/tools/sdk/ndk/ -[NOTICE] Compiling XBMC for Android requires Android NDK +[NOTICE] Compiling Kodi for Android requires Android NDK Revision r9. For the SDK just use the latest available. It will work. @@ -97,7 +97,7 @@ install some android packages using the Android SDK Manager: 3.3. Setup the Android toolchain -------------------------------------------------------------------- -To be able to compile XBMC and the libraries it depends on for the +To be able to compile Kodi and the libraries it depends on for the Android platform you first need to setup an Android toolchain using the Android NDK which you earlier extracted to <android-ndk>. The following commands will create a toolchain suitable for the most @@ -105,7 +105,7 @@ common scenario. The --install-dir option (and therefore the <android-toolchain-arm>/<android-toolchain-x86> value) specifies where the resulting toolchain should be installed (your choice). -[NOTICE] XBMC uses the android API Version 14 and gcc version 4.8! +[NOTICE] Kodi uses the android API Version 14 and gcc version 4.8! Building for arm architecture: @@ -144,15 +144,15 @@ Make sure to pick a toolchain for your desired architecture. ----------------------------------------------------------------------------- # cd $HOME - # git clone git://github.com/xbmc/xbmc.git xbmc-android - # cd xbmc-android + # git clone git://github.com/xbmc/xbmc.git kodi-android + # cd kodi-android # git submodule update --init addons/skin.re-touched ----------------------------------------------------------------------------- 5. How to compile ----------------------------------------------------------------------------- -Compiling XBMC for Android consists of compiling the libraries XBMC depends +Compiling Kodi for Android consists of compiling the libraries Kodi depends on with the Android toolchain and creating an Android Application Package (APK) which can be installed in an Android system. @@ -160,7 +160,7 @@ on with the Android toolchain and creating an Android Application Package 5.1. Building dependencies -------------------------------------------------------------------- - # cd $HOME/xbmc-android/tools/depends + # cd $HOME/kodi-android/tools/depends # ./bootstrap # ./configure --help @@ -182,10 +182,10 @@ on with the Android toolchain and creating an Android Application Package "Dependencies built successfully." appears. -------------------------------------------------------------------- -5.2. Building XBMC +5.2. Building Kodi -------------------------------------------------------------------- - # cd $HOME/xbmc-android + # cd $HOME/kodi-android # make -C tools/depends/target/xbmc # make # make apk @@ -194,15 +194,15 @@ on with the Android toolchain and creating an Android Application Package subsequent builds can be run with a simple 'make' and 'make apk'. ----------------------------------------------------------------------------- -6. Installing XBMC in an Android system +6. Installing Kodi in an Android system ----------------------------------------------------------------------------- -To install XBMC through the previously built APK in an Android system you can +To install Kodi through the previously built APK in an Android system you can either install it on a real device (smartphone/tablet/...) running Android >= 2.3.x. -------------------------------------------------------------------- -6.1. Installing XBMC on the Android device +6.1. Installing Kodi on the Android device -------------------------------------------------------------------- Make sure your Android device is connected to your computer through @@ -212,7 +212,7 @@ device's Android settings: - Applications [X] Unknown sources - # cd $HOME/xbmc-android/tools/android/packaging + # cd $HOME/kodi-android/tools/android/packaging # adb devices # adb -s <device-id> install -r images/xbmcapp-debug.apk @@ -221,17 +221,17 @@ The <device-id> can be retrieved from the list returned by the your device. ----------------------------------------------------------------------------- -7. Running and debugging XBMC in an Android system +7. Running and debugging Kodi in an Android system ----------------------------------------------------------------------------- -After installing XBMC's APK in an Android system you can start it using its +After installing Kodi's APK in an Android system you can start it using its Launcher icon in Android's Application Launcher. -------------------------------------------------------------------- -7.1. Debugging XBMC +7.1. Debugging Kodi -------------------------------------------------------------------- -To be able to see what is happening while running XBMC you first need +To be able to see what is happening while running Kodi you first need to enable USB debugging in your Android settings (this is already done when using the emulator): @@ -257,18 +257,18 @@ to cd to tools/android/packaging/xbmc and execute it from there. # ndk-gdb --start --delay=0 -This will open the installed version of XBMC and break. The warnings can be +This will open the installed version of Kodi and break. The warnings can be ignored as we have setup the appropriate paths already. -------------------------------------------------------------------- 8. Architecture -------------------------------------------------------------------- -During the early days of the android port, xbmc was launched via a stub lib -that then dlopen'd libxbmc. This was done to get around bionic's poor handling -of shared libs. We now compile everything into libxbmc itself so that it has +During the early days of the android port, Kodi was launched via a stub lib +that then dlopen'd libkodi. This was done to get around bionic's poor handling +of shared libs. We now compile everything into libkodi itself so that it has no runtime dependencies beyond system libs. Done this way, we're able to launch -into libxbmc directly. +into libkodi directly. But we still hit Bionic's loader's deficiencies when we dlopen a lib. There are two main issues to overcome for loading: @@ -317,10 +317,10 @@ is 'tools/android/packaging' and that the proper sdk/ndk paths are set. -Install a new build over the existing one # adb -e install -r images/xbmcapp-debug.apk --Launch XBMC on the emulator without the GUI +-Launch Kodi on the emulator without the GUI # adb shell am start -a android.intent.action.MAIN -n org.xbmc.xbmc/android.app.NativeActivity --Kill a misbehaving XBMC +-Kill a misbehaving Kodi # adb shell ps | grep org.xbmc | awk '{print $2}' | xargs adb shell kill -Filter logcat messages by a specific tag (e.g. "XBMC") diff --git a/docs/README.armel b/docs/README.armel index 066cc0887d..1ad32fe908 100644 --- a/docs/README.armel +++ b/docs/README.armel @@ -14,7 +14,7 @@ TOC 7. How to run 7.1 Obtaining the Packages 7.2 Installing the Files - 7.3 Running XBMC + 7.3 Running Kodi 8. Troubleshooting @@ -22,12 +22,12 @@ TOC 1. Introduction ----------------------------------------------------------------------------- -This is a port of XBMC for use on ARM Architecture. -As this is not an official version of XBMC, in-depth testing on various setups has not been done. USE WITH CAUTION! +This is a port of Kodi for use on ARM Architecture. +As this is not an official version of Kodi, in-depth testing on various setups has not been done. USE WITH CAUTION! For the purpose of this port, the following Hardware and Software was used. Software: Scratchbox (cross-compiler) on a Linux (Ubuntu) machine. Hardware: BeagleBoard (ARM Cortex-A8 with IMG POWERVR SGX). -The source code is based on XBMC for Linux - version 9.11 (Camelot). +The source code is based on Kodi for Linux - version 9.11 (Camelot). All lines that are prefixed with the '$' character are commands that need to be typed into a standard linux terminal All lines that are prefixed with the '>' character are commands that need to be typed into scratchbox @@ -162,7 +162,7 @@ In order to continue, you will need the SGX SDK from TI's website. Once you have installed said SDK on a standard Linux machine, copy the neccessary .h and .so files to the appropriate directories in scratchbox: e.g /scratchbox/users/<username>/targets/<target_name>/usr/include/EGL/egl.h These files will also need to be transferred over to the board eventually. -NOTE: XBMC has only been tested with the following versions of the OMAP35x Graphics SDK: +NOTE: Kodi has only been tested with the following versions of the OMAP35x Graphics SDK: 3.00.00.05, 3.00.00.06, 3.00.00.08, 3.00.00.09 @@ -170,7 +170,7 @@ NOTE: XBMC has only been tested with the following versions of the OMAP35x Graph 6. How to compile ----------------------------------------------------------------------------- -To create the XBMC executable manually perform these following steps: +To create the Kodi executable manually perform these following steps: ----------------------------------------------------------------------------- 6.1 Configure & Make: @@ -179,7 +179,7 @@ To create the XBMC executable manually perform these following steps: $ ./bootstrap > ./configure --enable-gles - This will configure XBMC inside scratchbox ready for compilation on ARM. + This will configure Kodi inside scratchbox ready for compilation on ARM. Because the default is to build for OpenGL, we require the --enable-gles flag to be set for OpenGL ES 2.0. (Note: No OpenGL ES 1.x available) Now, build with the following: @@ -191,12 +191,12 @@ To create the XBMC executable manually perform these following steps: ----------------------------------------------------------------------------- There is no need to do 'make install' as we dont want it installed into scratchbox. - There is also the slight problem of the fact that scratchbox's 'find' command is outdated and wont execute xbmc's 'make install' correctly. + There is also the slight problem of the fact that scratchbox's 'find' command is outdated and wont execute Kodi's 'make install' correctly. Instead, use the provided shell script: > cd /tools/arm/arm-scripts/ > ./create-xbmcfile.sh - This will create a tar file tools/arm/arm-scripts/xbmc.tar.bz2 containing the xbmc files, ready for you to transfer to the board. + This will create a tar file tools/arm/arm-scripts/xbmc.tar.bz2 containing the Kodi files, ready for you to transfer to the board. ----------------------------------------------------------------------------- @@ -238,14 +238,14 @@ It is also assumed that you have it setup with either Angstrom or Ubuntu. # tar xjf armel-pkgs.tar.bz2 -C / # tar xjf xbmc.tar.bz2 -C /usr/ - After this initial setup, during development, you should only need to replace /usr/share/xbmc/xbmc.bin with the newly created binary. + After this initial setup, during development, you should only need to replace /usr/share/kodi/kodi.bin with the newly created binary. ----------------------------------------------------------------------------- - 7.3 Running XBMC: + 7.3 Running Kodi: ----------------------------------------------------------------------------- - Now, run XBMC by executing the binary: - # /usr/share/xbmc/xbmc.bin + Now, run Kodi by executing the binary: + # /usr/share/kodi/kodi.bin Run the binary and not the script as the script will fail. @@ -256,7 +256,7 @@ It is also assumed that you have it setup with either Angstrom or Ubuntu. If it fails to run correctly, there are a few things to try out. First, is there any helpful output on the terminal? -Check the log file, usually located ~/.xbmc/temp/xbmc.log +Check the log file, usually located ~/.kodi/temp/kodi.log It may have failed because of a missing package. If so, you will need to download the appropriate armel package from packages.debian.org, Extract the files with the command: dpkg-deb -x packagename.deb /path/to/extract/to @@ -264,10 +264,10 @@ Then tarball the extracted files: tar cjf pkg.tar.bz2 /path/to/extracted/files Then transfer them to the board, and extract: tar xjf pkg.tar.bz2 This is because the .deb files cannot be extracted in Angstrom. -If this is not the case, try various different parameters for xbmc.bin such as: -xbmc.bin --standalone -xbmc.bin -p -xbmc.bin -fs -Or build with debug for a more in-depth xbmc.log file by ommitting the line --disable-debug on configure. +If this is not the case, try various different parameters for kodi.bin such as: +kodi.bin --standalone +kodi.bin -p +kodi.bin -fs +Or build with debug for a more in-depth kodi.log file by ommitting the line --disable-debug on configure. Feel free to contact me on mcgeagh@xbmc.org diff --git a/docs/README.ios b/docs/README.ios index 59bcaa38ab..e1d0444612 100644 --- a/docs/README.ios +++ b/docs/README.ios @@ -16,9 +16,9 @@ TOC 1. Introduction ----------------------------------------------------------------------------- -This is a platform port of XBMC for the Apple iOS operating system. -The current build system supports Xcode 3.2.6 or Xcode 4.3.x with iOS SDK 4.2/4.3/5.1 -There are two ways to build XBMC for Mac. +This is a platform port of Kodi for the Apple iOS operating system. +The current build system supports Xcode 3.2.6, 4.3.x, 5.x.x, 6.0.1, 6.1.0 with iOS SDK 4.3/5.1/6/7/8/8.1 +There are two ways to build Kodi for Mac. 1) command-line or 2) Xcode. @@ -26,7 +26,7 @@ There are two ways to build XBMC for Mac. Generally, Xcode is the easiest as it presents the build system in a GUI environment. The command-line build is still under development. -XBMC for iOS is composed of a main binary with numerous dynamic libraries and +Kodi for iOS is composed of a main binary with numerous dynamic libraries and codecs that support a multitude of music and video formats. NOTE TO NEW OS X USERS: All lines that are prefixed with the '$' character are @@ -39,8 +39,8 @@ character itself should NOT be typed as part of the command. ----------------------------------------------------------------------------- $ cd $HOME - $ git clone git://github.com/xbmc/xbmc.git xbmc - $ cd xbmc + $ git clone git://github.com/xbmc/xbmc.git Kodi + $ cd Kodi $ git submodule update --init addons/skin.re-touched ----------------------------------------------------------------------------- @@ -48,7 +48,7 @@ character itself should NOT be typed as part of the command. ----------------------------------------------------------------------------- See point 3.0a below for an updated list of supported Xcode/osx constellations!!! -Install latest Xcode (5.1.1 as of the writing). You can download it from +Install latest Xcode (6.1.0 as of the writing). You can download it from 1. The MacOSX AppStore (Xcode). @@ -60,10 +60,11 @@ automatically once they are invoked from the cmdline. Xcode 3.2.6 only runs on 10.6.x (Snow Leopard). Xcode 4.3.x only runs on 10.7.x (Lion). Xcode 5.x.x only runs on 10.8.x and later. - +Xcode 6.0.1 only runs on 10.9.4 and later. +Xcode 6.1.0 only runs on 10.9.5 and later. The preferred iOS SDK Version is 4.3 (when using Xcode 3.2.6) or 5.1 (when using -Xcode 4.3.x) or 7.x (when using Xcode 5.x.x) +Xcode 4.3.x) or 7.x (when using Xcode 5.x.x) or 8.x (when using Xcode 6.x.x) ----------------------------------------------------------------------------- 3.0a Supported Xcode and OSX constellations @@ -77,6 +78,8 @@ constellations of Xcode and osx versions (to be updated once we know more): 3.a Building against iOS SDK 6.0 will only allow to run on targets with iOS 5.1 and below. There is no support for devices running iOS 6.0 for now! 4. Xcode 5.1.1 against iOS SDK 7.0 and 7.1 on 10.9.x (Mavericks) +5. Xcode 6.0.1 against iOS SDK 8.0 on 10.9.x (Mavericks) +6. Xcode 6.1.0 against iOS SDK 8.1 on 10.10.x (Yosemite) ----------------------------------------------------------------------------- 3.1 Install Cross libs and runtime environment @@ -85,7 +88,7 @@ constellations of Xcode and osx versions (to be updated once we know more): The following commands will build using the latest iOS SDK found on your system. - $ cd $HOME/XBMC + $ cd $HOME/Kodi $ cd tools/depends $ ./bootstrap $ ./configure --host=arm-apple-darwin @@ -110,7 +113,7 @@ constellations of Xcode and osx versions (to be updated once we know more): Both Xcode and Terminal compilation require that build environment be setup from the step 3.1. - $ cd $HOME/XBMC + $ cd $HOME/Kodi $ make -C tools/depends/target/xbmc $ make clean $ make xcode_depends @@ -118,11 +121,11 @@ from the step 3.1. ----------------------------------------------------------------------------- 4.1 Using Xcode ----------------------------------------------------------------------------- -Start XCode and open the XBMC project (XBMC.xcodeproj) -located in $HOME/XBMC. +Start XCode and open the Kodi project (Kodi.xcodeproj) +located in $HOME/Kodi. There are two relevant build configurations : Release and Debug. Compile always for device -end not simulator and select the wanted target (either XBMC-iOS or XBMC-ATV2) +end not simulator and select the wanted target (either Kodi-iOS or Kodi-ATV2) If you have selected a specific iOS SDK Version in step 3.1 then you might need to adapt the active target to use the same iOS SDK version. Else build will fail @@ -135,16 +138,16 @@ of the ATV2 project manually to "default/clang". 4.2 Using Terminal (command-line) ----------------------------------------------------------------------------- - $ cd $HOME/XBMC - $ xcodebuild -project XBMC.xcodeproj -target XBMC-iOS -configuration Release build \ - ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.2 \ - SDKROOT=iphoneos4.2 + $ cd $HOME/Kodi + $ xcodebuild -project Kodi.xcodeproj -target Kodi-iOS -configuration Release build \ + ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.3 \ + SDKROOT=iphoneos4.3 or - $ xcodebuild -project XBMC.xcodeproj -target XBMC-ATV2 -configuration Release build \ - ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.2 \ - SDKROOT=iphoneos4.2 + $ xcodebuild -project Kodi.xcodeproj -target Kodi-ATV2 -configuration Release build \ + ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.3 \ + SDKROOT=iphoneos4.3 Make sure to set SDKROOT to the iOS SDK you want to use. This should be the same you used on point 3.1! @@ -153,20 +156,20 @@ or 5. Packaging ----------------------------------------------------------------------------- -This section describes how to package XBMC in a deb image for +This section describes how to package Kodi in a deb image for distribution. - 1. build XBMC for iOS or ATV2 from XCode so that the application bundle is + 1. build Kodi for iOS or ATV2 from XCode so that the application bundle is correctly updated. 2. - $ cd tools/darwin/packaging/xbmc-atv2 + $ cd tools/darwin/packaging/atv2 or - $ cd tools/darwin/packaging/xbmc-ios + $ cd tools/darwin/packaging/ios - 3. $ chmod +x ./mkdeb-xbmc-atv2.sh && ./mkdeb-xbmc-atv2.sh release + 3. $ chmod +x ./mkdeb-atv2.sh && ./mkdeb-atv2.sh release or - $ chmod +x ./mkdeb-xbmc-ios.sh && ./mkdeb-xbmc-ios.sh release + $ chmod +x ./mkdeb-ios.sh && ./mkdeb-ios.sh release 4. Use release or debug - you have to be sure that you build the corresponding version before. @@ -200,12 +203,14 @@ distribution. 8. Usage/Development on un-jailbroken devices (only interesting for official apple developers!) ------------------------------------------------------------------------------ -If you are a developer with an official apple code signing identity you can deploy XBMC +If you are a developer with an official apple code signing identity you can deploy Kodi via xcode to work on it on non-jailbroken devices. For this to happen you just need to alter the -Xcode project by setting your codesign identity. After that the last buildstep in our support script +Xcode project by setting your codesign identity. Be sure to not just select the "iPhone Developer" shortcut +but instead select your full identity "iPhone Developer: your name (your id)" (this is important else our sign +script won't detect a real sign identity). After that the last buildstep in our support script will do a full sign of all binaries and the bundle with the given identity (all *.viz, *.pvr, *.so files -Xcode doesn't know anything about). This should allow you to deploy XBMC to all non-jailbroken devices -which you can deploy normal apps to. In that case (XBMC will be sandboxed like any other app) - all XBMC +Xcode doesn't know anything about). This should allow you to deploy Kodi to all non-jailbroken devices +which you can deploy normal apps to. In that case (Kodi will be sandboxed like any other app) - all Kodi files are then located in the sandboxed "Documents" folder and can be easily accessed via iTunes file sharing. -Keep in mind that no hardware acceleration will be possible without jailbreaking! +Keep in mind that no hardware acceleration will be possible without jailbreaking when using iOS < Version 8. diff --git a/docs/README.linux b/docs/README.linux index 60c76bb30a..5d4c47de28 100644 --- a/docs/README.linux +++ b/docs/README.linux @@ -47,7 +47,7 @@ Build-Depends: autoconf, automake, autopoint, autotools-dev, cmake, curl, libavfilter-dev, libavformat-dev, libavutil-dev, libbluetooth-dev, libbluray-dev, libboost-dev, libboost-thread-dev, libbz2-dev, libcap-dev, libcdio-dev, libcec-dev, libcurl4-gnutls-dev | libcurl4-openssl-dev | libcurl-dev, libcwiid-dev, libdbus-1-dev, - libenca-dev, libflac-dev, libfontconfig-dev, libfreetype6-dev, libfribidi-dev, + libenca-dev, libfontconfig-dev, libfreetype6-dev, libfribidi-dev, libgl1-mesa-dev | libgl-dev, libglew-dev, libglu1-mesa-dev | libglu-dev, libhal-dev, libhal-storage-dev, libiso9660-dev, libjasper-dev, libjpeg-dev, libltdl-dev, liblzo2-dev, libmad0-dev, libmicrohttpd-dev, libmodplug-dev, libmpcdec-dev, libmpeg2-4-dev, libmysqlclient-dev, diff --git a/docs/README.osx b/docs/README.osx index 049fdb2379..c659ef5023 100644 --- a/docs/README.osx +++ b/docs/README.osx @@ -3,7 +3,7 @@ TOC 2. Getting the source code 3. Install required libs 3.1. Install Xcode - 3.2. Install XBMC build depends + 3.2. Install Kodi build depends 4. How to compile and run 4.1 Using XCode 4.2 Using Command line @@ -13,29 +13,30 @@ TOC 1. Introduction ----------------------------------------------------------------------------- -This is a platform port of XBMC for the Apple OSX operating system. 10.6, 10.7 -10.8 and 10.9 Intel development platforms are supported. Xcode 3.2.6 and 4.3 and newer +This is a platform port of Kodi for the Apple OSX operating system. 10.6, 10.7 +10.8, 10.9 and 10.10 Intel development platforms are supported. Xcode 3.2.6 and 4.3 and newer are the recommended versions. -There are 3 ways to build XBMC for Mac, from command-line with make, from command-line +There are 3 ways to build Kodi for Mac, from command-line with make, from command-line using xcodebuild or from Xcode. Generally, Xcode is the easiest as it presents the build system in a GUI environment. The command-line build is still under development. -XBMC for Mac is composed of a main binary with numerous dynamic libraries and +Kodi for Mac is composed of a main binary with numerous dynamic libraries and codecs that support a multitude of music and video formats. On Snow Leopard (OSX 10.6.x) we recommend using Xcode 3.2.6. On Lion (OSX 10.7.x) we recommend using Xcode 4.3.x. On Mountain Lion (OSX 10.8.1) we recommend using Xcode 4.4. On Mavericks (OSX 10.9.3) we recommend using Xcode 5.1.1 or 6.0.1. +On Yosemite (OSX 10.10) we recommend using Xcode 6.1. NOTE TO NEW OS X USERS: All lines that are prefixed with the '$' character are commands that need to be typed into a Terminal window. Note that the '$' character itself should NOT be typed as part of the command. -ATTENTION: When using Mountain Lion (OSX 10.8.x) or Mavericks (10.9.x) you need to download and install -XQuartz from https://xquartz.macosforge.org/landing/ since its not part of OSX +ATTENTION: When using Mountain Lion (OSX 10.8.x), Mavericks (10.9.x) or Yosemite (10.10.x) you +need to download and install XQuartz from https://xquartz.macosforge.org/landing/ since its not part of OSX anymore. ----------------------------------------------------------------------------- @@ -43,14 +44,14 @@ anymore. ----------------------------------------------------------------------------- $ cd $HOME - $ git clone git://github.com/xbmc/xbmc.git xbmc + $ git clone git://github.com/xbmc/xbmc.git Kodi ----------------------------------------------------------------------------- 3.0 Install XCODE ----------------------------------------------------------------------------- See point 3.0a below for an updated list of supported/tested Xcode/osx constellations!!! -Install latest Xcode (6.0.1 or 3.2.6 as of the writing). You can download it from +Install latest Xcode (6.1.0 or 3.2.6 as of the writing). You can download it from 1. Apple's site after registration at http://developer.apple.com/tools/download (Xcode 3.2.6) 2. In the MacOSX AppStore (Xcode 4.3.x and later). @@ -65,6 +66,7 @@ Xcode 4.3.x only runs on 10.7.x (Lion). Xcode 4.4 only runs on 10.8.x (Mountain Lion). Xcode 5.1.1 runs on 10.8.x and 10.9.x (Mavericks). Xcode 6.0.1 runs on 10.9.4 and later (Mavericks). +Xcode 6.1 runs on 10.9.5 and later (Mavericks). ----------------------------------------------------------------------------- 3.0a Supported Xcode and OSX constellations @@ -77,22 +79,23 @@ constellations of Xcode and osx versions (to be updated once we know more): 3. XCode 4.6 against OSX SDK 10.6, 10.7 and 10.8 on 10.7.x (Lion) and 10.8.x (ML) 4. XCode 5.1.1 against OSX SDK 10.8 (ML) and 10.9 (M) 5. XCode 6.0.1 against OSX SDK 10.9 (M) +6. XCode 6.1.0 against OSX SDK 10.10 (Y) ----------------------------------------------------------------------------- -3.1 Install XBMC build depends +3.1 Install Kodi build depends ----------------------------------------------------------------------------- The following commands will build using the latest OSX SDK found on your system. 3.1.1 Compiling as 32 Bit binary - $ cd $HOME/XBMC + $ cd $HOME/Kodi $ cd tools/depends $ ./bootstrap $ ./configure --host=i386-apple-darwin $ make 3.1.2 Compiling as 64 Bit binary - $ cd $HOME/XBMC + $ cd $HOME/Kodi $ cd tools/depends $ ./bootstrap $ ./configure --host=x86_64-apple-darwin @@ -119,46 +122,46 @@ first. This is a simple step and involves the following: 4.a Compilation by using command-line building via xcodebuild or by compiling via Xcode GUI - $ cd $HOME/XBMC + $ cd $HOME/Kodi $ make -C tools/depends/target/xbmc $ make clean $ make xcode_depends 4.b Compilation by using command-line building via make (experimental) - $ cd $HOME/XBMC + $ cd $HOME/Kodi $ make -C tools/depends/target/xbmc $ make clean The configure operation will setup the build environment for codecs and -internal libraries that are used by XBMC. This step is required for both Xcode +internal libraries that are used by Kodi. This step is required for both Xcode and command-line building. The "make clean" ensures that there are no stale binaries from git that might cause problems. ----------------------------------------------------------------------------- 4.1 Using Xcode ----------------------------------------------------------------------------- -Start XCode and open the XBMC project (XBMC.xcodeproj) located in $HOME/XBMC. -For development, XBMC is run from the $HOME/XBMC directory and needs to have -the XBMC_HOME environment variable set to know where that directory is located. -To set XBMC_HOME environment variable: +Start XCode and open the Kodi project (Kodi.xcodeproj) located in $HOME/Kodi. +For development, Kodi is run from the $HOME/Kodi directory and needs to have +the APP_HOME environment variable set to know where that directory is located. +To set APP_HOME environment variable: Xcode 3.2.6 - Menu -> Project -> Edit Active Executable "XBMC", click "Arguments" tab and - add "XBMC_HOME" as an enviroment variable. Set the value to the path to the - XBMC root folder. For example, "/Users/bigdog/Documents/XBMC" + Menu -> Project -> Edit Active Executable "Kodi", click "Arguments" tab and + add "APP_HOME" as an enviroment variable. Set the value to the path to the + Kodi root folder. For example, "/Users/bigdog/Documents/Kodi" Xcode 4.3.x and later - Menu -> Product -> Edit Sheme -> "Run XBMC"/"Debug" -> Add XBMC_HOME into - the List of "Environment Variables".Set the value to the path to thev XBMC - root folder. For example, "/Users/bigdog/Documents/XBMC" + Menu -> Product -> Edit Sheme -> "Run Kodi"/"Debug" -> Add APP_HOME into + the List of "Environment Variables". Set the value to the path to the Kodi + root folder. For example, "/Users/bigdog/Documents/Kodi" -There are two build targets "XBMC" and "XBMC.app" (each in 32Bit and 64Bit flavour) -with debug and release settings. The "XBMC" target is used for rapid build and -debug cycles while the "XBMC.app" target is used to build a self contained +There are two build targets "Kodi" and "Kodi.app" (each in 32Bit and 64Bit flavour) +with debug and release settings. The "Kodi" target is used for rapid build and +debug cycles while the "Kodi.app" target is used to build a self contained OSX application. -Set the build target to "XBMC" or "XBMC.app" and be sure to select the same +Set the build target to "Kodi" or "Kodi.app" and be sure to select the same architecture as selected in step 3.1 (either i386 for 32Bit or x86_64 for 64Bit), then build. @@ -171,21 +174,21 @@ You can see the progress in "Build Results". There are a large number of static and dynamic libaries that will need to be built. Once these are built, subsequent builds will be faster. -After the build, you can ether run XBMC for Mac from Xcode or run it from +After the build, you can ether run Kodi for Mac from Xcode or run it from the command-line. If you run it from the command-line, make sure your set -the XBMC_HOME environment variable (export XBMC_HOME=$HOME/XBMC). Then, to +the APP_HOME environment variable (export APP_HOME=$HOME/Kodi). Then, to run the debug version: -$ ./build/Debug/XBMC +$ ./build/Debug/Kodi Or the release version: -$ ./build/Release/XBMC +$ ./build/Release/Kodi You can also build via Xcode from the command-line using the following: $ xcodebuild -configuration Release ONLY_ACTIVE_ARCH=YES ARCHS=i386 VALID_ARCHS=i386 \ - -target "XBMC.app" -project XBMC.xcodeproj + -target "Kodi.app" -project Kodi.xcodeproj You can specify "Release" instead of "Debug" as a configuration. Be sure to set *_ARCHS variables to the same architecture as selected in step 3.1 (either i386 for 32Bit or x86_64 @@ -202,29 +205,29 @@ you could try xcodebuild from the command-line (normally unneeded - for advanced developers). a) - $ cd $HOME/XBMC - $ export XBMC_HOME=`pwd` + $ cd $HOME/Kodi + $ export APP_HOME=`pwd` $ make xcode_depends - $ xcodebuild -sdk macosx10.7 -project XBMC.xcodeproj -target XBMC.app ONLY_ACTIVE_ARCH=YES \ + $ xcodebuild -sdk macosx10.7 -project Kodi.xcodeproj -target Kodi.app ONLY_ACTIVE_ARCH=YES \ ARCHS=x86_64 VALID_ARCHS=x86_64 -configuration Release build b) building via make - $ cd $HOME/XBMC - $ export XBMC_HOME=`pwd` + $ cd $HOME/Kodi + $ export APP_HOME=`pwd` $ make - $ ./xbmc.bin + $ ./Kodi.bin ----------------------------------------------------------------------------- 5. Packaging ----------------------------------------------------------------------------- -This section describes how to package XBMC in a disk image for +This section describes how to package Kodi in a disk image for distribution. - 1. build XBMC.app from XCode so that the application bundle is correctly updated. + 1. build Kodi.app from XCode so that the application bundle is correctly updated. - 2. $ cd tools/darwin/packaging/xbmc-osx + 2. $ cd tools/darwin/packaging/osx - 3. $ ./mkdmg-xbmc-osx.sh release + 3. $ ./mkdmg-osx.sh release 4. Use release or debug - you have to be sure that you build the corresponding version before. diff --git a/docs/README.raspberrypi b/docs/README.raspberrypi index aadcc418c7..5b9729825a 100644 --- a/docs/README.raspberrypi +++ b/docs/README.raspberrypi @@ -14,22 +14,22 @@ crosscompile environment. 2. Installing and setting up the buildroot environment ----------------------------------------------------------------------------- -Create a top level directory where you checkout xbmc and buildroot. +Create a top level directory where you checkout Kodi and buildroot. For example : -mkdir /opt/xbmc-raspberrypi -cd /opt/xbmc-raspberrypi +mkdir /opt/kodi-raspberrypi +cd /opt/kodi-raspberrypi Checkout xbmc : -git clone https://github.com/xbmc/xbmc.git +git clone https://github.com/xbmc/xbmc.git kodi Checkout buildroot : git clone https://github.com/huceke/buildroot-rbp.git -cd /opt/xbmc-raspberrypi/buildroot-rbp +cd /opt/kodi-raspberrypi/buildroot-rbp -Follow the instructions in README.rbp how to build the system and xbmc. +Follow the instructions in README.rbp how to build the system and Kodi. diff --git a/docs/README.ubuntu b/docs/README.ubuntu index c680b84f8d..f922ce3a7d 100644 --- a/docs/README.ubuntu +++ b/docs/README.ubuntu @@ -74,7 +74,7 @@ Tip: For those with multiple computers at home is to try out distcc For Ubuntu (all versions >= 7.04): - $ sudo apt-get install automake bison build-essential cmake curl cvs default-jre fp-compiler gawk gdc gettext git-core gperf libasound2-dev libass-dev libboost-dev libboost-thread-dev libbz2-dev libcap-dev libcdio-dev libcurl3 libcurl4-gnutls-dev libdbus-1-dev libenca-dev libflac-dev libfontconfig-dev libfreetype6-dev libfribidi-dev libglew-dev libiso9660-dev libjasper-dev libjpeg-dev liblzo2-dev libmad0-dev libmicrohttpd-dev libmodplug-dev libmpeg2-4-dev libmpeg3-dev libmysqlclient-dev libnfs-dev libogg-dev libpcre3-dev libplist-dev libpng-dev libpulse-dev libsdl-dev libsdl-gfx1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsmbclient-dev libsqlite3-dev libssh-dev libssl-dev libtiff-dev libtinyxml-dev libtool libudev-dev libusb-dev libvdpau-dev libvorbisenc2 libxml2-dev libxmu-dev libxrandr-dev libxrender-dev libxslt1-dev libxt-dev libyajl-dev mesa-utils nasm pmount python-dev python-imaging python-sqlite swig unzip yasm zip zlib1g-dev + $ sudo apt-get install automake bison build-essential cmake curl cvs default-jre fp-compiler gawk gdc gettext git-core gperf libasound2-dev libass-dev libboost-dev libboost-thread-dev libbz2-dev libcap-dev libcdio-dev libcurl3 libcurl4-gnutls-dev libdbus-1-dev libenca-dev libfontconfig-dev libfreetype6-dev libfribidi-dev libglew-dev libiso9660-dev libjasper-dev libjpeg-dev liblzo2-dev libmad0-dev libmicrohttpd-dev libmodplug-dev libmpeg2-4-dev libmpeg3-dev libmysqlclient-dev libnfs-dev libogg-dev libpcre3-dev libplist-dev libpng-dev libpulse-dev libsdl-dev libsdl-gfx1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsmbclient-dev libsqlite3-dev libssh-dev libssl-dev libtiff-dev libtinyxml-dev libtool libudev-dev libusb-dev libvdpau-dev libvorbisenc2 libxml2-dev libxmu-dev libxrandr-dev libxrender-dev libxslt1-dev libxt-dev libyajl-dev mesa-utils nasm pmount python-dev python-imaging python-sqlite swig unzip yasm zip zlib1g-dev For >= 10.10: $ sudo apt-get install autopoint libltdl-dev diff --git a/docs/manpages/diskmounter.1 b/docs/manpages/diskmounter.1 deleted file mode 100644 index 772ccddae9..0000000000 --- a/docs/manpages/diskmounter.1 +++ /dev/null @@ -1,7 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH DISKMOUNTER "1" "July 2009" "diskmounter " "User Commands" -.SH NAME -diskmounter \- mount various partitions -.SH DESCRIPTION -This utility searches for available HFS+, NTFS and FAT32 partitions, creates -mount points for them and mounts the partitions. diff --git a/docs/manpages/installXBMC.1 b/docs/manpages/installXBMC.1 deleted file mode 100644 index 424e4fbfc4..0000000000 --- a/docs/manpages/installXBMC.1 +++ /dev/null @@ -1,6 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH INSTALLXBMC "1" "July 2009" "installXBMC " "User Commands" -.SH NAME -installXBMC \- XBMC Live installer -.SH DESCRIPTION -This script installs XBMC Live. diff --git a/docs/manpages/xbmc-j2meremote.1 b/docs/manpages/kodi-j2meremote.1 index 5ce2a99884..2e11d1499a 100644 --- a/docs/manpages/xbmc-j2meremote.1 +++ b/docs/manpages/kodi-j2meremote.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH XBMC-J2MEREMOTE "1" "July 2009" "xbmc-j2meremote " "User Commands" +.TH KODI-J2MEREMOTE "1" "October 2014" "kodi-j2meremote " "User Commands" .SH NAME -xbmc-j2meremote \- Java Bluetooth Phone Remote Control Client for XBMC +kodi-j2meremote \- Java Bluetooth Phone Remote Control Client for Kodi .SH DESCRIPTION -This script is the XBMC remote control client that will allow XBMC to be +This script is the Kodi remote control client that will allow Kodi to be controlled by a Java Bluetooth Phone. .SH USAGE -Usage for xbmc-j2meremote +Usage for kodi-j2meremote .SS "Arguments:" .TP \fB\-\-address\fR ADDRESS diff --git a/docs/manpages/xbmc-ps3remote.1 b/docs/manpages/kodi-ps3remote.1 index 08e45b9dcd..3b6e6fccde 100644 --- a/docs/manpages/xbmc-ps3remote.1 +++ b/docs/manpages/kodi-ps3remote.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH XBMC-PS3REMOTE "1" "July 2009" "xbmc-ps3remote " "User Commands" +.TH KODI-PS3REMOTE "1" "October 2014" "kodi-ps3remote " "User Commands" .SH NAME -xbmc-ps3remote \- PS3 Blu\-Ray Remote Control Client for XBMC +kodi-ps3remote \- PS3 Blu\-Ray Remote Control Client for Kodi .SH DESCRIPTION -This script is the XBMC remote control client that will allow XBMC to be +This script is the Kodi remote control client that will allow Kodi to be controlled by a PS3 Blu-Ray Remote. .SH USAGE -Usage for xbmc-ps3remote +Usage for kodi-ps3remote .SS "Arguments:" .TP \fB\-\-address\fR ADDRESS diff --git a/docs/manpages/xbmc-send.1 b/docs/manpages/kodi-send.1 index 562c807f2c..03ca685177 100644 --- a/docs/manpages/xbmc-send.1 +++ b/docs/manpages/kodi-send.1 @@ -1,14 +1,14 @@ -.TH XBMC-SEND "1" "December 2009" "xbmc-send" +.TH KODI-SEND "1" "October 2014" "kodi-send" .SH NAME -xbmc\-send \- program to send some action to XBMC +xbmc\-send \- program to send some action to Kodi .SH SYNOPSIS xbmc\-send [OPTION] \fB\-\-action\fR=\fIACTION\fR .SH DESCRIPTION -This program is used for sending actions for XBMC. +This program is used for sending actions for Kodi. .PP Example .IP -xbmc\-send \fB\-\-host\fR=\fI192\fR.168.0.1 \fB\-\-port\fR=\fI9777\fR \fB\-\-action=\fR"XBMC.Quit" +kodi\-send \fB\-\-host\fR=\fI192\fR.168.0.1 \fB\-\-port\fR=\fI9777\fR \fB\-\-action=\fR"Quit" .PP Options .TP @@ -22,5 +22,5 @@ Choose what HOST to connect to (default=localhost) Choose what PORT to connect to (default=9777) .TP \fB\-\-action\fR=\fIACTION\fR -Sends an action to XBMC, this option can be added multiple times to create a macro. +Sends an action to Kodi, this option can be added multiple times to create a macro. diff --git a/docs/manpages/kodi-standalone.1 b/docs/manpages/kodi-standalone.1 new file mode 100644 index 0000000000..54e2fc0f30 --- /dev/null +++ b/docs/manpages/kodi-standalone.1 @@ -0,0 +1,6 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. +.TH KODI-STANDALONE "1" "October 2014" "kodi-standalone " "User Commands" +.SH NAME +kodi-standalone \- Kodi standalone mode +.SH DESCRIPTION +This script runs Kodi in standalone mode. diff --git a/docs/manpages/xbmc-wiiremote.1 b/docs/manpages/kodi-wiiremote.1 index 909a5803dd..7b0ced839a 100644 --- a/docs/manpages/xbmc-wiiremote.1 +++ b/docs/manpages/kodi-wiiremote.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH XBMC-WIIREMOTE "1" "July 2009" "xbmc-wiiremote " "User Commands" +.TH KODI-WIIREMOTE "1" "October 20014" "kodi-wiiremote " "User Commands" .SH NAME -xbmc-wiiremote \- Wiimote Remote Control Client for XBMC +kodi-wiiremote \- Wiimote Remote Control Client for Kodi .SH DESCRIPTION -This script is the XBMC remote control client that will allow XBMC to be +This script is the Kodi remote control client that will allow Kodi to be controlled by a Wiimote. .SS "Arguments:" .HP diff --git a/docs/manpages/kodi.1 b/docs/manpages/kodi.1 new file mode 100644 index 0000000000..5f55c7af5a --- /dev/null +++ b/docs/manpages/kodi.1 @@ -0,0 +1 @@ +.so man1/kodi.bin.1 diff --git a/docs/manpages/xbmc.bin.1 b/docs/manpages/kodi.bin.1 index 5113f15b72..80ef889212 100644 --- a/docs/manpages/xbmc.bin.1 +++ b/docs/manpages/kodi.bin.1 @@ -1,24 +1,24 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH XBMC.BIN "1" "July 2009" "xbmc.bin " "User Commands" +.TH KODI.BIN "1" "October 2014" "kodi.bin " "User Commands" .SH NAME -xbmc.bin \- XBMC main executable +kodi.bin \- Kodi main executable .SH SYNOPSIS -.B xbmc.bin +.B kodi.bin [\fIOPTION\fR]... [\fIFILE\fR]... .SH DESCRIPTION -This is the main executable that will run XBMC. +This is the main executable that will run Kodi. .SS "Arguments:" .TP \fB\-fs\fR -Runs XBMC in full screen +Runs Kodi in full screen .TP \fB\-\-standalone\fR -XBMC runs in a stand alone environment without a window +Kodi runs in a stand alone environment without a window manager and supporting applications. For example, that enables network settings. .TP \fB\-p\fR or \fB\-\-portable\fR -XBMC will look for configurations in install folder instead of ~/.xbmc +Kodi will look for configurations in install folder instead of ~/.kodi .TP \fB\-\-legacy\-res\fR Enables screen resolutions such as PAL, NTSC, etc. diff --git a/docs/manpages/runXBMC.1 b/docs/manpages/runXBMC.1 deleted file mode 100644 index 7c08b2fb2f..0000000000 --- a/docs/manpages/runXBMC.1 +++ /dev/null @@ -1,7 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH RUNXBMC "1" "July 2009" "runXBMC " "User Commands" -.SH NAME -runXBMC \- XBMC Live launcher -.SH DESCRIPTION -runXBMC is a script that runs XBMC in standalone mode, meant to be run for -XBMC Live. diff --git a/docs/manpages/setAlsaVolumes.1 b/docs/manpages/setAlsaVolumes.1 deleted file mode 100644 index daa79dc2fc..0000000000 --- a/docs/manpages/setAlsaVolumes.1 +++ /dev/null @@ -1,6 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH SETALSAVOLUMES "1" "July 2009" "setAlsaVolumes " "User Commands" -.SH NAME -setAlsaVolumes \- XBMC Live volume control script -.SH DESCRIPTION -Script that sets output volume for all amixer controls. diff --git a/docs/manpages/xbmc-standalone.1 b/docs/manpages/xbmc-standalone.1 deleted file mode 100644 index 84f34286ad..0000000000 --- a/docs/manpages/xbmc-standalone.1 +++ /dev/null @@ -1,6 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH XBMC-STANDALONE "1" "July 2009" "xbmc-standalone " "User Commands" -.SH NAME -xbmc-standalone \- XBMC standalone mode -.SH DESCRIPTION -This script runs XBMC in standalone mode. diff --git a/docs/manpages/xbmc.1 b/docs/manpages/xbmc.1 deleted file mode 100644 index 9bc7511fd1..0000000000 --- a/docs/manpages/xbmc.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/xbmc.bin.1 diff --git a/language/English/strings.po b/language/English/strings.po index 80706be8f2..a27daa0220 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -69,37 +69,38 @@ msgstr "" #empty string with id 10 -#: Used in Confluence +#strings from 11 to 17 are reserved for weather translation +#. Weather token msgctxt "#11" msgid "Monday" msgstr "" -#: Used in Confluence +#. Weather token msgctxt "#12" msgid "Tuesday" msgstr "" -#: Used in Confluence +#. Weather token msgctxt "#13" msgid "Wednesday" msgstr "" -#: Used in Confluence +#. Weather token msgctxt "#14" msgid "Thursday" msgstr "" -#: Used in Confluence +#. Weather token msgctxt "#15" msgid "Friday" msgstr "" -#: Used in Confluence +#. Weather token msgctxt "#16" msgid "Saturday" msgstr "" -#: Used in Confluence +#. Weather token msgctxt "#17" msgid "Sunday" msgstr "" @@ -3811,8 +3812,113 @@ msgctxt "#1301" msgid "Custom passthrough device" msgstr "" -#empty strings from id 1302 to 1395 -#strings from 1396 to 1449 are reserved for weather translation +#empty strings from id 1302 to 1374 +#strings from 1350 to 1449 are reserved for weather translation + +#. Weather token +msgctxt "#1375" +msgid "Temperature" +msgstr "" + +#. Weather token +msgctxt "#1376" +msgid "Pressure" +msgstr "" + +#. Weather token +msgctxt "#1377" +msgid "Proximity" +msgstr "" + +#. Weather token +msgctxt "#1378" +msgid "Intensity" +msgstr "" + +#. Weather token +msgctxt "#1379" +msgid "Ragged" +msgstr "" + +#. Weather token +msgctxt "#1380" +msgid "Very" +msgstr "" + +#. Weather token +msgctxt "#1381" +msgid "Extreme" +msgstr "" + +#. Weather token +msgctxt "#1382" +msgid "Whirls" +msgstr "" + +#. Weather token +msgctxt "#1383" +msgid "Sky Is Clear" +msgstr "" + +#. Weather token +msgctxt "#1384" +msgid "Broken" +msgstr "" + +#. Weather token +msgctxt "#1385" +msgid "Tornado" +msgstr "" + +#. Weather token +msgctxt "#1386" +msgid "Tropical" +msgstr "" + +#. Weather token +msgctxt "#1387" +msgid "Hurricane" +msgstr "" + +#. Weather token +msgctxt "#1388" +msgid "Cold" +msgstr "" + +#. Weather token +msgctxt "#1389" +msgid "Windy" +msgstr "" + +#. Weather token +msgctxt "#1390" +msgid "Settings" +msgstr "" + +#. Weather token +msgctxt "#1391" +msgid "Breeze" +msgstr "" + +#. Weather token +msgctxt "#1392" +msgid "Gentle" +msgstr "" + +#. Weather token +msgctxt "#1393" +msgid "High wind, near gale" +msgstr "" + +#. Weather token +msgctxt "#1394" +msgid "Severe" +msgstr "" + +#. Weather token +msgctxt "#1395" +msgid "Violent" +msgstr "" #. Weather token msgctxt "#1396" @@ -10068,7 +10174,12 @@ msgctxt "#20261" msgid "Apple Filing Protocol (AFP)" msgstr "" -#empty strings from id 20262 to 20299 +#: xbmc/storage/MediaManager.cpp +msgctxt "#20262" +msgid "Zeroconf Browser" +msgstr "" + +#empty strings from id 20263 to 20299 #: xbmc/network/GUIDialogNetworkSetup.cpp msgctxt "#20300" @@ -12537,7 +12648,19 @@ msgctxt "#24127" msgid "Automatically download first subtitle from the search result list" msgstr "" -#empty strings from id 24128 to 24999 +#. Info dialog after migrating userdata from xbmc to kodi +#: xbmc/Application.cpp +msgctxt "#24128" +msgid "Configuration has been moved" +msgstr "" + +#. Info dialog after migrating userdata from xbmc to kodi +#: xbmc/Application.cpp +msgctxt "#24129" +msgid "The configuration of XBMC has been moved to the new location for Kodi. Please refer to http://kodi.wiki/view/Migration_from_XBMC_to_Kodi - this message will not be shown again!" +msgstr "" + +#empty strings from id 24130 to 24999 msgctxt "#25000" msgid "Notifications" @@ -15953,3 +16076,8 @@ msgstr "" msgctxt "#37031" msgid "Specifies how Blu-rays should be opened/played back. Disc menus are not fully supported yet and may cause problems." msgstr "" + +#: system/settings/rbp.xml +msgctxt "#38010" +msgid "GPU accelerated" +msgstr "" diff --git a/lib/SlingboxLib/SlingboxLib.cpp b/lib/SlingboxLib/SlingboxLib.cpp index f2d7017de1..0632e6f8e8 100644 --- a/lib/SlingboxLib/SlingboxLib.cpp +++ b/lib/SlingboxLib/SlingboxLib.cpp @@ -41,24 +41,16 @@ typedef int socklen_t; // Default constructor. CSlingbox::CSlingbox() { - // Set all variables to default/invalid values - m_socCommunication = INVALID_SOCKET; - m_socStream = INVALID_SOCKET; - memset(m_szAddress, 0, sizeof(m_szAddress)); - m_uiPort = 0; - m_usCode = 0; - m_usSequence = 0; - m_iChannel = -1; - m_iInput = -1; - memset(&m_receivedMessages, 0, sizeof(m_receivedMessages)); + // initialize all members + init(); } // Alternative constructor used to set the address (IP or hostname) and port of the -// Slingbox we want to connect to. If no port is specified default port 5001 is used. +// Slingbox we want to connect to. If no port is specified default port 5001 is used. CSlingbox::CSlingbox(const char * szAddress, unsigned int uiPort /* = 5001 */) { - // Call default constructor - CSlingbox(); + // initialize all members + init(); // Set address and port variables to passed values SetAddress(szAddress, uiPort); @@ -74,6 +66,20 @@ CSlingbox::~CSlingbox() CloseSocket(m_socCommunication); } +// Function used to initialize class members +void CSlingbox::init() +{ + // Set all variables to default/invalid values + m_socCommunication = INVALID_SOCKET; + m_socStream = INVALID_SOCKET; + memset(m_szAddress, 0, sizeof(m_szAddress)); + m_uiPort = 0; + m_usCode = 0; + m_usSequence = 0; + m_iChannel = -1; + m_iInput = -1; + memset(&m_receivedMessages, 0, sizeof(m_receivedMessages)); +} // Function used to find a Slingbox. Address and port of found Slingbox can be // retrieved with the GetAddress function afterwards. bool CSlingbox::FindSlingbox(unsigned int uiTimeout /* = 10 */) diff --git a/lib/SlingboxLib/SlingboxLib.h b/lib/SlingboxLib/SlingboxLib.h index ad368f00f1..a8835bc02b 100644 --- a/lib/SlingboxLib/SlingboxLib.h +++ b/lib/SlingboxLib/SlingboxLib.h @@ -91,6 +91,7 @@ public: bool SendIRCommand(uint8_t ucCommand); protected: + void init(); // Function used to send and receive messages to and from the Slingbox struct MessageHeader; bool SendReceiveMessage(SOCKET socSocket, MessageHeader * pHeader, diff --git a/lib/SlingboxLib/patches/0001-Fix-alternative-CSlingbox-constructor.patch b/lib/SlingboxLib/patches/0001-Fix-alternative-CSlingbox-constructor.patch new file mode 100644 index 0000000000..3dffa98941 --- /dev/null +++ b/lib/SlingboxLib/patches/0001-Fix-alternative-CSlingbox-constructor.patch @@ -0,0 +1,85 @@ +From 25c5ffe9eb2213fc18ab498320fbf9af79e1250d Mon Sep 17 00:00:00 2001 +From: Maks Naumov <maksqwe1@ukr.net> +Date: Mon, 25 Aug 2014 21:45:02 +0300 +Subject: [PATCH] SlingboxLib: Fix alternative CSlingbox constructor + +CSlingbox::CSlingbox(const char * szAddress, unsigned int uiPort /* = 5001 */) { + // Call default constructor + CSlingbox(); + ... +} + +"CSlingbox();" - object is created and immediately removed. +Therefore with CSlingbox(const char * szAddress, unsigned int uiPort /* = 5001 */) class members will not be initialized. +--- + lib/SlingboxLib/SlingboxLib.cpp | 32 +++++++++++++++++++------------- + lib/SlingboxLib/SlingboxLib.h | 1 + + 2 files changed, 20 insertions(+), 13 deletions(-) + +diff --git a/lib/SlingboxLib/SlingboxLib.cpp b/lib/SlingboxLib/SlingboxLib.cpp +index f2d7017..0632e6f 100644 +--- a/lib/SlingboxLib/SlingboxLib.cpp ++++ b/lib/SlingboxLib/SlingboxLib.cpp +@@ -41,24 +41,16 @@ typedef int socklen_t; + // Default constructor. + CSlingbox::CSlingbox() + { +- // Set all variables to default/invalid values +- m_socCommunication = INVALID_SOCKET; +- m_socStream = INVALID_SOCKET; +- memset(m_szAddress, 0, sizeof(m_szAddress)); +- m_uiPort = 0; +- m_usCode = 0; +- m_usSequence = 0; +- m_iChannel = -1; +- m_iInput = -1; +- memset(&m_receivedMessages, 0, sizeof(m_receivedMessages)); ++ // initialize all members ++ init(); + } + + // Alternative constructor used to set the address (IP or hostname) and port of the +-// Slingbox we want to connect to. If no port is specified default port 5001 is used. ++// Slingbox we want to connect to. If no port is specified default port 5001 is used. + CSlingbox::CSlingbox(const char * szAddress, unsigned int uiPort /* = 5001 */) + { +- // Call default constructor +- CSlingbox(); ++ // initialize all members ++ init(); + + // Set address and port variables to passed values + SetAddress(szAddress, uiPort); +@@ -74,6 +66,20 @@ CSlingbox::~CSlingbox() + CloseSocket(m_socCommunication); + } + ++// Function used to initialize class members ++void CSlingbox::init() ++{ ++ // Set all variables to default/invalid values ++ m_socCommunication = INVALID_SOCKET; ++ m_socStream = INVALID_SOCKET; ++ memset(m_szAddress, 0, sizeof(m_szAddress)); ++ m_uiPort = 0; ++ m_usCode = 0; ++ m_usSequence = 0; ++ m_iChannel = -1; ++ m_iInput = -1; ++ memset(&m_receivedMessages, 0, sizeof(m_receivedMessages)); ++} + // Function used to find a Slingbox. Address and port of found Slingbox can be + // retrieved with the GetAddress function afterwards. + bool CSlingbox::FindSlingbox(unsigned int uiTimeout /* = 10 */) +diff --git a/lib/SlingboxLib/SlingboxLib.h b/lib/SlingboxLib/SlingboxLib.h +index ad368f0..a8835bc 100644 +--- a/lib/SlingboxLib/SlingboxLib.h ++++ b/lib/SlingboxLib/SlingboxLib.h +@@ -91,6 +91,7 @@ class CSlingbox + bool SendIRCommand(uint8_t ucCommand); + + protected: ++ void init(); + // Function used to send and receive messages to and from the Slingbox + struct MessageHeader; + bool SendReceiveMessage(SOCKET socSocket, MessageHeader * pHeader, diff --git a/lib/UnrarXLib/file.cpp b/lib/UnrarXLib/file.cpp index ddbe4f92a7..4b37d126d1 100644 --- a/lib/UnrarXLib/file.cpp +++ b/lib/UnrarXLib/file.cpp @@ -334,15 +334,12 @@ void File::Write(const void *Data,int Size) if (HandleType!=FILE_HANDLENORMAL) { const int MaxSize=0x4000; - for (int I=0;I<Size;I+=MaxSize) - //if (!(success=WriteFile(hFile,(byte *)Data+I,Min(Size-I,MaxSize),&Written,NULL) != FALSE)) - m_File.Write((byte*)Data+I,Min(Size-I,MaxSize)); - // break; + for (int I = 0; I < Size && success; I += MaxSize) + success = m_File.Write((byte*)Data + I, Min(Size - I, MaxSize)) == Min(Size - I, MaxSize); } else { - //success=WriteFile(hFile,Data,Size,&Written,NULL) != FALSE; - m_File.Write(Data,Size); + success = m_File.Write(Data, Size) == Size; } #else success=fwrite(Data,1,Size,hFile)==Size && !ferror(hFile); @@ -420,7 +417,7 @@ int File::DirectRead(void *Data,int Size) while (Size) { int nRead = m_File.Read(Data,Size); - if (nRead == 0) + if (nRead <= 0) break; Read += nRead; Data = (void*)(((char*)Data)+nRead); diff --git a/lib/addons/library.xbmc.addon/libXBMC_addon.cpp b/lib/addons/library.xbmc.addon/libXBMC_addon.cpp index 05ab740ac4..4dd4d5be9d 100644 --- a/lib/addons/library.xbmc.addon/libXBMC_addon.cpp +++ b/lib/addons/library.xbmc.addon/libXBMC_addon.cpp @@ -140,10 +140,10 @@ DLLEXPORT void* XBMC_open_file_for_write(void *hdl, void* cb, const char* strFil return ((CB_AddOnLib*)cb)->OpenFileForWrite(((AddonCB*)hdl)->addonData, strFileName, bOverWrite); } -DLLEXPORT unsigned int XBMC_read_file(void *hdl, void* cb, void* file, void* lpBuf, int64_t uiBufSize) +DLLEXPORT ssize_t XBMC_read_file(void *hdl, void* cb, void* file, void* lpBuf, size_t uiBufSize) { if (cb == NULL) - return 0; + return -1; return ((CB_AddOnLib*)cb)->ReadFile(((AddonCB*)hdl)->addonData, file, lpBuf, uiBufSize); } @@ -156,10 +156,10 @@ DLLEXPORT bool XBMC_read_file_string(void *hdl, void* cb, void* file, char *szLi return ((CB_AddOnLib*)cb)->ReadFileString(((AddonCB*)hdl)->addonData, file, szLine, iLineLength); } -DLLEXPORT int XBMC_write_file(void *hdl, void* cb, void* file, const void* lpBuf, int64_t uiBufSize) +DLLEXPORT ssize_t XBMC_write_file(void *hdl, void* cb, void* file, const void* lpBuf, size_t uiBufSize) { if (cb == NULL) - return false; + return -1; return ((CB_AddOnLib*)cb)->WriteFile(((AddonCB*)hdl)->addonData, file, lpBuf, uiBufSize); } diff --git a/lib/libRTV/GuideParser.cpp b/lib/libRTV/GuideParser.cpp index c92c40225a..b70c45e1e6 100644 --- a/lib/libRTV/GuideParser.cpp +++ b/lib/libRTV/GuideParser.cpp @@ -855,7 +855,7 @@ int CalculateMinutes( int seconds ) //------------------------------------------------------------------------- //------------------------------------------------------------------------- -#if _WIN32_WINNT < 0x0602 +#if _WIN32_WINNT < 0x0602 && !defined(ntohll) DWORD64 ntohll(DWORD64 llValue) { DWORD64 retval = 0; diff --git a/project/BuildDependencies/scripts/0_package.list b/project/BuildDependencies/scripts/0_package.list index 8127b156c6..e2a4a1ff6c 100644 --- a/project/BuildDependencies/scripts/0_package.list +++ b/project/BuildDependencies/scripts/0_package.list @@ -12,6 +12,7 @@ gnutls-3.2.3-win32.zip jsonschemabuilder-1.0.0-win32-3.7z libass-0.10.2-win32.7z libbluray-0.4.0-win32.zip +libcec-2.2.0-win32-1.7z libiconv-1.14-win32-vc120.7z libjpeg-turbo-1.2.0-win32.7z libnfs-1.6.2-win32.7z diff --git a/project/BuildDependencies/scripts/libcec_d.bat b/project/BuildDependencies/scripts/libcec_d.bat deleted file mode 100644 index b5104c3cf4..0000000000 --- a/project/BuildDependencies/scripts/libcec_d.bat +++ /dev/null @@ -1,15 +0,0 @@ -@ECHO OFF - -SET LOC_PATH=%CD% -SET FILES=%LOC_PATH%\libcec_d.txt - -CALL dlextract.bat libcec %FILES% - -cd %TMP_PATH% - -mkdir "%CUR_PATH%\include\libcec" -xcopy libcec\include\* "%CUR_PATH%\include\libcec\." /E /Q /I /Y - -copy libcec\libcec.dll "%APP_PATH%\system\." - -cd %LOC_PATH% diff --git a/project/BuildDependencies/scripts/libcec_d.txt b/project/BuildDependencies/scripts/libcec_d.txt index a126c74497..3d0265ee05 100644 --- a/project/BuildDependencies/scripts/libcec_d.txt +++ b/project/BuildDependencies/scripts/libcec_d.txt @@ -1,3 +1,3 @@ ; filename source of the file -libcec-2.1.4.zip http://mirrors.xbmc.org/build-deps/win32/ +libcec-2.2.0-win32.zip http://mirrors.xbmc.org/build-deps/win32/ diff --git a/project/VS2010Express/XBMC.defaults.props b/project/VS2010Express/XBMC.defaults.props index a1ebbcab1a..8d98c20bb7 100644 --- a/project/VS2010Express/XBMC.defaults.props +++ b/project/VS2010Express/XBMC.defaults.props @@ -7,7 +7,7 @@ <PropertyGroup> <IncludePath>$(SolutionDir)\..\BuildDependencies\include;$(SolutionDir)\..\BuildDependencies\include\python;$(IncludePath)</IncludePath> <ExecutablePath>$(SolutionDir)\..\..\tools\win32buildtools;$(ExecutablePath)</ExecutablePath> - <LocalDebuggerEnvironment>XBMC_HOME=$(SolutionDir)..\..
PATH=$(SolutionDir)..\Win32BuildSetup\dependencies;%PATH%</LocalDebuggerEnvironment> + <LocalDebuggerEnvironment>APP_HOME=$(SolutionDir)..\..
PATH=$(SolutionDir)..\Win32BuildSetup\dependencies;%PATH%</LocalDebuggerEnvironment> </PropertyGroup> <ItemDefinitionGroup> <ClCompile> diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 64f7d5cde0..c29fb2f17b 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -69,7 +69,7 @@ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug Testsuite|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath> <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(DXSDK_DIR)Include;$(IncludePath)</IncludePath> <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Testsuite|Win32'">xbmc-test</TargetName> + <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Testsuite|Win32'">$(ProjectName)-test</TargetName> <CustomBuildBeforeTargets Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> </CustomBuildBeforeTargets> </PropertyGroup> @@ -196,11 +196,12 @@ <ClCompile Include="..\..\xbmc\BackgroundInfoLoader.cpp" /> <ClCompile Include="..\..\xbmc\CompileInfo.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\AEFactory.cpp" /> + <ClCompile Include="..\..\xbmc\cores\AudioEngine\AEResampleFactory.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\AESinkFactory.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\Encoders\AEEncoderFFmpeg.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAE.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEBuffer.cpp" /> - <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResample.cpp" /> + <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResampleFFMPEG.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAESink.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAESound.cpp" /> <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEStream.cpp" /> @@ -278,6 +279,7 @@ <ClCompile Include="..\..\xbmc\filesystem\AFPFile.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\ASAPFileDirectory.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\BlurayDirectory.cpp" /> + <ClCompile Include="..\..\xbmc\filesystem\BlurayFile.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\CacheStrategy.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\CDDADirectory.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\CDDAFile.cpp" /> @@ -812,15 +814,17 @@ </CustomBuild> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEAudioFormat.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEFactory.h" /> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEResampleFactory.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AESinkFactory.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Encoders\AEEncoderFFmpeg.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAE.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEBuffer.h" /> - <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResample.h" /> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResampleFFMPEG.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAESink.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAESound.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEStream.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AE.h" /> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AEResample.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AEEncoder.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AESink.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AESound.h" /> @@ -848,6 +852,7 @@ <ClInclude Include="..\..\xbmc\DbUrl.h" /> <ClInclude Include="..\..\xbmc\dialogs\GUIDialogMediaFilter.h" /> <ClInclude Include="..\..\xbmc\FileItemListModification.h" /> + <ClInclude Include="..\..\xbmc\filesystem\BlurayFile.h" /> <ClInclude Include="..\..\xbmc\filesystem\HTTPFile.h" /> <ClInclude Include="..\..\xbmc\filesystem\DAVCommon.h" /> <ClInclude Include="..\..\xbmc\filesystem\DAVFile.h" /> @@ -1134,6 +1139,7 @@ <ClCompile Include="..\..\xbmc\utils\win32\Win32Log.cpp" /> <ClCompile Include="..\..\xbmc\utils\XSLTUtils.cpp" /> <ClCompile Include="..\..\xbmc\video\PlayerController.cpp" /> + <ClCompile Include="..\..\xbmc\video\videosync\VideoSyncD3D.cpp" /> <ClCompile Include="..\..\xbmc\video\VideoThumbLoader.cpp" /> <ClCompile Include="..\..\xbmc\music\MusicThumbLoader.cpp" /> <ClCompile Include="..\..\xbmc\ThumbnailCache.cpp" /> @@ -2020,6 +2026,8 @@ <ClInclude Include="..\..\xbmc\DatabaseManager.h" /> <ClInclude Include="..\..\xbmc\ThumbLoader.h" /> <ClInclude Include="..\..\xbmc\video\PlayerController.h" /> + <ClInclude Include="..\..\xbmc\video\videosync\VideoSync.h" /> + <ClInclude Include="..\..\xbmc\video\videosync\VideoSyncD3D.h" /> <ClInclude Include="..\..\xbmc\video\VideoThumbLoader.h" /> <ClInclude Include="..\..\xbmc\music\MusicThumbLoader.h" /> <ClInclude Include="..\..\xbmc\ThumbnailCache.h" /> @@ -2546,4 +2554,4 @@ </VisualStudio> </ProjectExtensions> <Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" /> -</Project> +</Project>
\ No newline at end of file diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index 2f3a22d3da..dbb9b9d41f 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -319,6 +319,9 @@ <Filter Include="utils\win32"> <UniqueIdentifier>{3adbba6a-6fbf-4192-b215-108d94bde1e0}</UniqueIdentifier> </Filter> + <Filter Include="video\videosync"> + <UniqueIdentifier>{9775d5c0-c640-4606-a625-e6cdcf9f959e}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\xbmc\win32\pch.cpp"> @@ -2262,6 +2265,9 @@ <ClCompile Include="..\..\xbmc\cores\AudioEngine\AEFactory.cpp"> <Filter>cores\AudioEngine</Filter> </ClCompile> + <ClCompile Include="..\..\xbmc\cores\AudioEngine\AEResampleFactory.cpp"> + <Filter>cores\AudioEngine</Filter> + </ClCompile> <ClCompile Include="..\..\xbmc\cores\AudioEngine\AESinkFactory.cpp"> <Filter>cores\AudioEngine</Filter> </ClCompile> @@ -2936,7 +2942,7 @@ <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEBuffer.cpp"> <Filter>cores\AudioEngine\Engines\ActiveAE</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResample.cpp"> + <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResampleFFMPEG.cpp"> <Filter>cores\AudioEngine\Engines\ActiveAE</Filter> </ClCompile> <ClCompile Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAESink.cpp"> @@ -3071,6 +3077,12 @@ <ClCompile Include="..\..\xbmc\utils\MarkWatchedJob.cpp"> <Filter>utils</Filter> </ClCompile> + <ClCompile Include="..\..\xbmc\filesystem\BlurayFile.cpp"> + <Filter>filesystem</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\video\videosync\VideoSyncD3D.cpp"> + <Filter>video\videosync</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\xbmc\win32\pch.h"> @@ -5276,12 +5288,18 @@ <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEFactory.h"> <Filter>cores\AudioEngine</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEResampleFactory.h"> + <Filter>cores\AudioEngine</Filter> + </ClInclude> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AESinkFactory.h"> <Filter>cores\AudioEngine</Filter> </ClInclude> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AE.h"> <Filter>cores\AudioEngine\Interfaces</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AEResample.h"> + <Filter>cores\AudioEngine\Interfaces</Filter> + </ClInclude> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Interfaces\AEEncoder.h"> <Filter>cores\AudioEngine\Interfaces</Filter> </ClInclude> @@ -5844,7 +5862,7 @@ <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEBuffer.h"> <Filter>cores\AudioEngine\Engines\ActiveAE</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResample.h"> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAEResampleFFMPEG.h"> <Filter>cores\AudioEngine\Engines\ActiveAE</Filter> </ClInclude> <ClInclude Include="..\..\xbmc\cores\AudioEngine\Engines\ActiveAE\ActiveAESink.h"> @@ -6007,6 +6025,15 @@ <ClInclude Include="..\..\xbmc\settings\DiscSettings.h"> <Filter>settings</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\filesystem\BlurayFile.h"> + <Filter>filesystem</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\video\videosync\VideoSyncD3D.h"> + <Filter>video\videosync</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\video\videosync\VideoSync.h"> + <Filter>video\videosync</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc"> @@ -6052,4 +6079,4 @@ <Filter>interfaces\swig</Filter> </None> </ItemGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/project/Win32BuildSetup/buildpvraddons.bat b/project/Win32BuildSetup/buildpvraddons.bat index 796309684a..c52b9c0479 100644 --- a/project/Win32BuildSetup/buildpvraddons.bat +++ b/project/Win32BuildSetup/buildpvraddons.bat @@ -9,7 +9,7 @@ SET DEPS_DIR=..\BuildDependencies SET TMP_DIR=%DEPS_DIR%\tmp SET LIBNAME=xbmc-pvr-addons -SET VERSION=3949502043d520e4707bc3109abf3c6edb23cf67 +SET VERSION=067befe6b8da81e29abca8cd394d08c84233677b SET SOURCE=%LIBNAME% SET GIT_URL=git://github.com/opdenkamp/%LIBNAME%.git SET SOURCE_DIR=%TMP_DIR%\%SOURCE% diff --git a/project/Win32BuildSetup/genNsisInstaller.nsi b/project/Win32BuildSetup/genNsisInstaller.nsi index 56a72a8ba0..3132bc761d 100644 --- a/project/Win32BuildSetup/genNsisInstaller.nsi +++ b/project/Win32BuildSetup/genNsisInstaller.nsi @@ -109,6 +109,10 @@ Function HandleUserdataMigration ${AndIfNot} ${FileExists} "$APPDATA\${APP_NAME}\*.*" Rename "$APPDATA\XBMC\" "$APPDATA\${APP_NAME}\" MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST|MB_SETFOREGROUND "Your current XBMC userdata folder was moved to the new ${APP_NAME} userdata location.$\nThis to make the transition as smooth as possible without any user interactions needed." + ;mark that it was migrated in the filesystem - kodi will show another info message during first Kodi startup + ;for really making sure that the user has read that message. + FileOpen $0 "$APPDATA\${APP_NAME}\.kodi_data_was_migrated" w + FileClose $0 ${EndIf} ${Else} ; old installation was found but not uninstalled - inform the user @@ -348,15 +352,6 @@ Section "Uninstall" ${If} $UnPageProfileCheckbox_State == ${BST_CHECKED} RMDir /r "$APPDATA\${APP_NAME}\" RMDir /r "$INSTDIR\portable_data\" - ${Else} - ;Check if %appdata%\${APP_NAME}\userdata and portable_data contain no guisettings.xml - ;If that file does not exists, then delete those folders and $INSTDIR - IfFileExists $INSTDIR\portable_data\userdata\guisettings.xml +2 - RMDir /r "$INSTDIR\portable_data\" - RMDir "$INSTDIR\" - IfFileExists "$APPDATA\${APP_NAME}\userdata\guisettings.xml" +2 - RMDir /r "$APPDATA\${APP_NAME}\userdata\" - RMDir "$APPDATA\${APP_NAME}" ${EndIf} RMDir "$INSTDIR" @@ -438,4 +433,4 @@ Function .onInit IntOp $0 ${SF_SELECTED} | ${SF_RO} SectionSetFlags ${SEC_DIRECTX} $0 StrCpy $CleanDestDir "-1" -FunctionEnd
\ No newline at end of file +FunctionEnd diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 6593be5657..e41ab0f951 100644 --- a/project/cmake/addons/CMakeLists.txt +++ b/project/cmake/addons/CMakeLists.txt @@ -1,4 +1,4 @@ -project(xbmc-addons) +project(kodi-addons) cmake_minimum_required(VERSION 2.8) @@ -15,12 +15,14 @@ endif() include(ExternalProject) ### setup all the necessary paths -if(NOT XBMCROOT) - set(XBMCROOT ${PROJECT_SOURCE_DIR}/../../..) +if(NOT APP_ROOT AND NOT XBMCROOT) + set(APP_ROOT ${PROJECT_SOURCE_DIR}/../../..) +elseif(NOT APP_ROOT) + file(TO_CMAKE_PATH "${XBMCROOT}" APP_ROOT) else() - file(TO_CMAKE_PATH "${XBMCROOT}" XBMCROOT) + file(TO_CMAKE_PATH "${APP_ROOT}" APP_ROOT) endif() -get_filename_component(XBMCROOT "${XBMCROOT}" ABSOLUTE) +get_filename_component(APP_ROOT "${APP_ROOT}" ABSOLUTE) if(NOT WIN32) if(NOT DEPENDS_PATH) @@ -38,7 +40,7 @@ if(NOT WIN32) endif() endif() -if(NOT CMAKE_INSTALL_PREFIX) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/output/addons") endif() list(APPEND CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX}) @@ -70,14 +72,14 @@ else() endif() if(NOT WIN32) - # copy the xbmc-prepare-env.cmake script to the depends path so that we can include it - file(COPY ${XBMCROOT}/project/cmake/scripts/common/xbmc-prepare-env.cmake DESTINATION ${DEPENDS_PATH}/lib/xbmc) + # copy the prepare-env.cmake script to the depends path so that we can include it + file(COPY ${APP_ROOT}/project/cmake/scripts/common/prepare-env.cmake DESTINATION ${DEPENDS_PATH}/lib/kodi) - # add the location of xbmc-prepare-env.cmake to CMAKE_MODULE_PATH so that it is found - list(APPEND CMAKE_MODULE_PATH ${DEPENDS_PATH}/lib/xbmc) + # add the location of prepare-env.cmake to CMAKE_MODULE_PATH so that it is found + list(APPEND CMAKE_MODULE_PATH ${DEPENDS_PATH}/lib/kodi) - # include xbmc-prepare-env.cmake which contains the logic to install the addon header bindings etc - include(xbmc-prepare-env) + # include prepare-env.cmake which contains the logic to install the addon header bindings etc + include(prepare-env) endif() ### get and build all the binary addons diff --git a/project/cmake/addons/README b/project/cmake/addons/README index 2af5f0f826..159f7c5a4b 100644 --- a/project/cmake/addons/README +++ b/project/cmake/addons/README @@ -1,4 +1,4 @@ -XBMC ADDONS +KODI ADDONS =========== This directory contains the cmake-based buildsystem for addons. It looks into the "addons" sub-directory and parses all *.txt files recursively. Each addon @@ -30,11 +30,11 @@ specific paths: builds. * DEPENDS_PATH points to the directory containing the "include" and "lib" directories of the addons' dependencies. - * XBMCROOT points to the root directory of the xbmc project (default is the + * APP_ROOT points to the root directory of the project (default is the absolute representation of ../../.. starting from this directory). * PACKAGE_ZIP=1 will mean the add-ons will be 'packaged' into a common folder, - rather than being placed in <CMAKE_INSTALL_PREFIX>/lib/xbmc/addons and - <CMAKE_INSTALL_PREFIX>/share/xbmc/addons. + rather than being placed in <CMAKE_INSTALL_PREFIX>/lib/kodi/addons and + <CMAKE_INSTALL_PREFIX>/share/kodi/addons. * ARCH_DEFINES specifies the platform-specific C/C++ preprocessor defines (defaults to empty). @@ -57,7 +57,7 @@ In case of additional options the call might look like this cmake <path> [-G <generator>] \ -DCMAKE_BUILD_TYPE=Release \ - -DXBMCROOT="<path-to-xbmc-root>" \ + -DAPP_ROOT="<path-to-app-root>" \ -DARCH_DEFINES="-DTARGET_LINUX" \ -DDEPENDS_PATH="<path-to-built-depends>" \ -DCMAKE_INSTALL_PREFIX="<path-to-install-directory" diff --git a/project/cmake/addons/depends/CMakeLists.txt b/project/cmake/addons/depends/CMakeLists.txt index 5c4853497d..042a739690 100644 --- a/project/cmake/addons/depends/CMakeLists.txt +++ b/project/cmake/addons/depends/CMakeLists.txt @@ -1,4 +1,4 @@ -project(xbmc-addons-depends) +project(kodi-addons-depends) cmake_minimum_required(VERSION 2.8) @@ -14,7 +14,7 @@ endif() include(ExternalProject) -if(NOT CMAKE_INSTALL_PREFIX) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/../output/depends) else() file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX) diff --git a/project/cmake/addons/depends/README b/project/cmake/addons/depends/README index 3ea8d8bd27..c26a41c9a6 100644 --- a/project/cmake/addons/depends/README +++ b/project/cmake/addons/depends/README @@ -1,4 +1,4 @@ -XBMC ADDON DEPENDENCIES +KODI ADDON DEPENDENCIES ======================= This directory contains the cmake-based buildsystem for addon dependencies. It looks into the "common" and the "<platform>/cmake" sub-directories and parses @@ -36,7 +36,7 @@ specific paths: builds. * CORE_SYSTEM_NAME is the name of the platform (e.g. "linux" or "android") in lower-case (defaults to lowercase(CMAKE_SYSTEM_NAME)). - * XBMCROOT points to the root directory of the xbmc project (default is the + * APP_ROOT points to the root directory of the project (default is the absolute representation of ../../.. starting from this directory). * ARCH_DEFINES specifies the platform-specific C/C++ preprocessor defines (defaults to empty). @@ -56,6 +56,6 @@ In case of additional options the call might look like this cmake <path> [-G <generator>] \ -DCMAKE_BUILD_TYPE=Release \ - -DXBMCROOT="<path-to-xbmc-root>" \ + -DAPP_ROOT="<path-to-project-root>" \ -DARCH_DEFINES="-DTARGET_LINUX" \ -DCMAKE_INSTALL_PREFIX="<path-to-install-directory" diff --git a/project/cmake/addons/depends/windows/CMakeLists.txt b/project/cmake/addons/depends/windows/CMakeLists.txt index e99cf0a8d5..83df09bb23 100644 --- a/project/cmake/addons/depends/windows/CMakeLists.txt +++ b/project/cmake/addons/depends/windows/CMakeLists.txt @@ -1,4 +1,4 @@ -project(xbmc-addons-depends-windows) +project(kodi-addons-depends-windows) cmake_minimum_required(VERSION 2.8) @@ -10,7 +10,7 @@ endif() include(ExternalProject) -if(NOT CMAKE_INSTALL_PREFIX) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX) message(FATAL_ERROR "CMAKE_INSTALL_PREFIX (${CMAKE_INSTALL_PREFIX}) is not a valid target directory.") else() file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX) diff --git a/project/cmake/addons/depends/windows/README b/project/cmake/addons/depends/windows/README index 3512f32ae6..67dc59451d 100644 --- a/project/cmake/addons/depends/windows/README +++ b/project/cmake/addons/depends/windows/README @@ -1,4 +1,4 @@ -XBMC WIN32 ADDON DEPENDENCIES +KODI WIN32 ADDON DEPENDENCIES ============================= This directory contains the cmake-based buildsystem for dependencies (currently only prebuilt) used by one or multiple addons. The buildsystem looks into the diff --git a/project/cmake/addons/depends/windows/cmake/kodi/CMakeLists.txt b/project/cmake/addons/depends/windows/cmake/kodi/CMakeLists.txt new file mode 100644 index 0000000000..811f5be2ae --- /dev/null +++ b/project/cmake/addons/depends/windows/cmake/kodi/CMakeLists.txt @@ -0,0 +1,33 @@ +project(kodi) + +cmake_minimum_required(VERSION 2.8) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) + +### setup all the necessary paths +if(NOT APP_ROOT AND NOT XBMCROOT) + set(APP_ROOT ${PROJECT_SOURCE_DIR}/../../../../../../..) +elseif(NOT APP_ROOT) + file(TO_CMAKE_PATH "${XBMCROOT}" APP_ROOT) +else() + file(TO_CMAKE_PATH "${APP_ROOT}" APP_ROOT) +endif() +get_filename_component(APP_ROOT "${APP_ROOT}" ABSOLUTE) + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX) + message(FATAL_ERROR "CMAKE_INSTALL_PREFIX (${CMAKE_INSTALL_PREFIX}) is not a valid target directory.") +else() + file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX) +endif() +get_filename_component(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) + +### prepare the environment +# set the DEPENDS_PATH variable used by prepare-env +set(DEPENDS_PATH "${CMAKE_INSTALL_PREFIX}") + +# copy the prepare-env.cmake script so that we can include it +file(COPY ${APP_ROOT}/project/cmake/scripts/common/prepare-env.cmake DESTINATION ${CMAKE_BINARY_DIR}) + +# include prepare-env.cmake which contains the logic to install the addon header bindings etc +include(prepare-env)
\ No newline at end of file diff --git a/project/cmake/addons/depends/windows/cmake/kodi/kodi.txt b/project/cmake/addons/depends/windows/cmake/kodi/kodi.txt new file mode 100644 index 0000000000..355d1b91e5 --- /dev/null +++ b/project/cmake/addons/depends/windows/cmake/kodi/kodi.txt @@ -0,0 +1 @@ +kodi
\ No newline at end of file diff --git a/project/cmake/addons/depends/windows/cmake/xbmc/noinstall.txt b/project/cmake/addons/depends/windows/cmake/kodi/noinstall.txt index e69de29bb2..e69de29bb2 100644 --- a/project/cmake/addons/depends/windows/cmake/xbmc/noinstall.txt +++ b/project/cmake/addons/depends/windows/cmake/kodi/noinstall.txt diff --git a/project/cmake/addons/depends/windows/cmake/xbmc/CMakeLists.txt b/project/cmake/addons/depends/windows/cmake/xbmc/CMakeLists.txt deleted file mode 100644 index 57d8a93065..0000000000 --- a/project/cmake/addons/depends/windows/cmake/xbmc/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -project(xbmc) - -cmake_minimum_required(VERSION 2.8) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) - -### setup all the necessary paths -if(NOT XBMCROOT) - set(XBMCROOT ${PROJECT_SOURCE_DIR}/../../../../../../..) -else() - file(TO_CMAKE_PATH "${XBMCROOT}" XBMCROOT) -endif() -get_filename_component(XBMCROOT "${XBMCROOT}" ABSOLUTE) - -if(NOT CMAKE_INSTALL_PREFIX) - message(FATAL_ERROR "CMAKE_INSTALL_PREFIX (${CMAKE_INSTALL_PREFIX}) is not a valid target directory.") -else() - file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX) -endif() -get_filename_component(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) - -### prepare the environment -# set the DEPENDS_PATH variable used by xbmc-prepare-env -set(DEPENDS_PATH "${CMAKE_INSTALL_PREFIX}") - -# copy the xbmc-prepare-env.cmake script so that we can include it -file(COPY ${XBMCROOT}/project/cmake/scripts/common/xbmc-prepare-env.cmake DESTINATION ${CMAKE_BINARY_DIR}) - -# include xbmc-prepare-env.cmake which contains the logic to install the addon header bindings etc -include(xbmc-prepare-env)
\ No newline at end of file diff --git a/project/cmake/addons/depends/windows/cmake/xbmc/xbmc.txt b/project/cmake/addons/depends/windows/cmake/xbmc/xbmc.txt deleted file mode 100644 index 0d53f64477..0000000000 --- a/project/cmake/addons/depends/windows/cmake/xbmc/xbmc.txt +++ /dev/null @@ -1 +0,0 @@ -xbmc
\ No newline at end of file diff --git a/project/cmake/addons/depends/windows/prebuilt/README b/project/cmake/addons/depends/windows/prebuilt/README index 11a05a5838..a0c70d6bde 100644 --- a/project/cmake/addons/depends/windows/prebuilt/README +++ b/project/cmake/addons/depends/windows/prebuilt/README @@ -1,4 +1,4 @@ -XBMC WIN32 PREBUILT ADDON DEPENDENCIES +KODI WIN32 PREBUILT ADDON DEPENDENCIES ====================================== This directory contains a file or sub-directory for every prebuilt dependency used by one of the addons being built. There are two different modes supported. diff --git a/project/cmake/kodi-config.cmake.in b/project/cmake/kodi-config.cmake.in new file mode 100644 index 0000000000..50e12a8a71 --- /dev/null +++ b/project/cmake/kodi-config.cmake.in @@ -0,0 +1,8 @@ +SET(KODI_INCLUDE_DIR @prefix@/include) +SET(APP_NAME @APP_NAME@) +SET(APP_VERSION_MAJOR @APP_VERSION_MAJOR@) +SET(APP_VERSION_MINOR @APP_VERSION_MINOR@) +LIST(APPEND CMAKE_MODULE_PATH @prefix@/lib/kodi) +ADD_DEFINITIONS(@ARCH_DEFINES@) + +include(addon-helpers) diff --git a/project/cmake/scripts/common/xbmc-addon-helpers.cmake b/project/cmake/scripts/common/addon-helpers.cmake index c882cfcd02..3f42ffa595 100644 --- a/project/cmake/scripts/common/xbmc-addon-helpers.cmake +++ b/project/cmake/scripts/common/addon-helpers.cmake @@ -62,13 +62,13 @@ macro (build_addon target prefix libs) ENDIF(WIN32) add_cpack_workaround(${target} ${${prefix}_VERSION} ${ext}) ELSE(PACKAGE_ZIP OR PACKAGE_TGZ) - INSTALL(TARGETS ${target} DESTINATION lib/xbmc/addons/${target}) - INSTALL(DIRECTORY ${target} DESTINATION share/xbmc/addons) + INSTALL(TARGETS ${target} DESTINATION lib/kodi/addons/${target}) + INSTALL(DIRECTORY ${target} DESTINATION share/kodi/addons) ENDIF(PACKAGE_ZIP OR PACKAGE_TGZ) endmacro() # finds a path to a given file (recursive) -function (xbmc_find_path var_name filename search_path strip_file) +function (kodi_find_path var_name filename search_path strip_file) file(GLOB_RECURSE PATH_TO_FILE ${search_path} ${filename}) if(strip_file) string(REPLACE ${filename} "" PATH_TO_FILE ${PATH_TO_FILE}) diff --git a/project/cmake/scripts/common/prepare-env.cmake b/project/cmake/scripts/common/prepare-env.cmake new file mode 100644 index 0000000000..c0b5217ac9 --- /dev/null +++ b/project/cmake/scripts/common/prepare-env.cmake @@ -0,0 +1,77 @@ +# parse version.txt to get the version info +if(EXISTS "${APP_ROOT}/version.txt") + file(STRINGS "${APP_ROOT}/version.txt" versions) + foreach (version ${versions}) + if(version MATCHES "^VERSION_.*") + string(REGEX MATCH "^[^ ]+" version_name ${version}) + string(REPLACE "${version_name} " "" version_value ${version}) + set(APP_${version_name} "${version_value}") + else() + string(REGEX MATCH "^[^ ]+" name ${version}) + string(REPLACE "${name} " "" value ${version}) + set(${name} "${value}") + endif() + endforeach() +endif() + +# bail if we can't parse versions +if(NOT DEFINED APP_VERSION_MAJOR OR NOT DEFINED APP_VERSION_MINOR) + message(FATAL_ERROR "Could not determine app version! make sure that ${APP_ROOT}/version.txt exists") +endif() + +### copy all the addon binding header files to include/kodi +# make sure include/kodi exists and is empty +set(KODI_LIB_DIR ${DEPENDS_PATH}/lib/kodi) +if(NOT EXISTS "${KODI_LIB_DIR}/") + file(MAKE_DIRECTORY ${KODI_LIB_DIR}) +endif() + +set(KODI_INCLUDE_DIR ${DEPENDS_PATH}/include/kodi) +if(NOT EXISTS "${KODI_INCLUDE_DIR}/") + file(MAKE_DIRECTORY ${KODI_INCLUDE_DIR}) +endif() + +# we still need XBMC_INCLUDE_DIR and XBMC_LIB_DIR for backwards compatibility to xbmc +set(XBMC_LIB_DIR ${DEPENDS_PATH}/lib/xbmc) +if(NOT EXISTS "${XBMC_LIB_DIR}/") + file(MAKE_DIRECTORY ${XBMC_LIB_DIR}) +endif() +set(XBMC_INCLUDE_DIR ${DEPENDS_PATH}/include/xbmc) +if(NOT EXISTS "${XBMC_INCLUDE_DIR}/") + file(MAKE_DIRECTORY ${XBMC_INCLUDE_DIR}) +endif() + +# kodi-config.cmake.in (further down) expects a "prefix" variable +get_filename_component(prefix "${DEPENDS_PATH}" ABSOLUTE) + +# generate the proper kodi-config.cmake file +configure_file(${APP_ROOT}/project/cmake/kodi-config.cmake.in ${KODI_LIB_DIR}/kodi-config.cmake @ONLY) +# copy cmake helpers to lib/kodi +file(COPY ${APP_ROOT}/project/cmake/scripts/common/addon-helpers.cmake ${APP_ROOT}/project/cmake/scripts/common/addoptions.cmake DESTINATION ${KODI_LIB_DIR}) + +# generate xbmc-config.cmake for backwards compatibility to xbmc +configure_file(${APP_ROOT}/project/cmake/xbmc-config.cmake.in ${XBMC_LIB_DIR}/xbmc-config.cmake @ONLY) + +### copy all the addon binding header files to include/kodi +# parse addon-bindings.mk to get the list of header files to copy +file(STRINGS ${APP_ROOT}/xbmc/addons/addon-bindings.mk bindings) +string(REPLACE "\n" ";" bindings "${bindings}") +foreach(binding ${bindings}) + string(REPLACE " =" ";" binding "${binding}") + string(REPLACE "+=" ";" binding "${binding}") + list(GET binding 1 header) + # copy the header file to include/kodi + file(COPY ${APP_ROOT}/${header} DESTINATION ${KODI_INCLUDE_DIR}) + + # auto-generate header files for backwards comaptibility to xbmc with deprecation warning + get_filename_component(headerfile ${header} NAME) + file(WRITE ${XBMC_INCLUDE_DIR}/${headerfile} +"#pragma once +#define DEPRECATION_WARNING \"Including xbmc/${headerfile} has been deprecated, please use kodi/${headerfile}\" +#ifdef _MSC_VER + #pragma message(\"WARNING: \" DEPRECATION_WARNING) +#else + #warning DEPRECATION_WARNING +#endif +#include \"kodi/${headerfile}\"") +endforeach()
\ No newline at end of file diff --git a/project/cmake/scripts/common/xbmc-prepare-env.cmake b/project/cmake/scripts/common/xbmc-prepare-env.cmake deleted file mode 100644 index ae3b9f28b8..0000000000 --- a/project/cmake/scripts/common/xbmc-prepare-env.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# parse version.txt to get the version info -if(EXISTS "${XBMCROOT}/version.txt") - file(STRINGS "${XBMCROOT}/version.txt" versions) - foreach (version ${versions}) - string(REGEX MATCH "^[^ ]+" version_name ${version}) - string(REPLACE "${version_name} " "" version_value ${version}) - set(APP_${version_name} "${version_value}") - endforeach() -endif() - -# bail if we can't parse versions -if(NOT DEFINED APP_VERSION_MAJOR OR NOT DEFINED APP_VERSION_MINOR) - message(FATAL_ERROR "Could not determine app version! make sure that ${XBMCROOT}/version.txt exists") -endif() - -### copy all the addon binding header files to include/xbmc -# make sure include/xbmc exists and is empty -set(XBMC_LIB_DIR ${DEPENDS_PATH}/lib/xbmc) -if(NOT EXISTS "${XBMC_LIB_DIR}/") - file(MAKE_DIRECTORY ${XBMC_LIB_DIR}) -endif() - -set(XBMC_INCLUDE_DIR ${DEPENDS_PATH}/include/xbmc) -if(NOT EXISTS "${XBMC_INCLUDE_DIR}/") - file(MAKE_DIRECTORY ${XBMC_INCLUDE_DIR}) -endif() - -# xbmc-config.cmake.in (further down) expects a "prefix" variable -get_filename_component(prefix "${DEPENDS_PATH}" ABSOLUTE) - -# generate the proper xbmc-config.cmake file -configure_file(${XBMCROOT}/project/cmake/xbmc-config.cmake.in ${XBMC_LIB_DIR}/xbmc-config.cmake @ONLY) -# copy cmake helpers to lib/xbmc -file(COPY ${XBMCROOT}/project/cmake/scripts/common/xbmc-addon-helpers.cmake ${XBMCROOT}/project/cmake/scripts/common/addoptions.cmake DESTINATION ${XBMC_LIB_DIR}) - -### copy all the addon binding header files to include/xbmc -# parse addon-bindings.mk to get the list of header files to copy -file(STRINGS ${XBMCROOT}/xbmc/addons/addon-bindings.mk bindings) -string(REPLACE "\n" ";" bindings "${bindings}") -foreach(binding ${bindings}) - string(REPLACE " =" ";" binding "${binding}") - string(REPLACE "+=" ";" binding "${binding}") - list(GET binding 1 header) - # copy the header file to include/xbmc - file(COPY ${XBMCROOT}/${header} DESTINATION ${XBMC_INCLUDE_DIR}) -endforeach()
\ No newline at end of file diff --git a/project/cmake/scripts/windows/xbmc-c-flag-overrides.cmake b/project/cmake/scripts/windows/c-flag-overrides.cmake index ab19701707..ab19701707 100644 --- a/project/cmake/scripts/windows/xbmc-c-flag-overrides.cmake +++ b/project/cmake/scripts/windows/c-flag-overrides.cmake diff --git a/project/cmake/scripts/windows/xbmc-cxx-flag-overrides.cmake b/project/cmake/scripts/windows/cxx-flag-overrides.cmake index ad3a0908ef..ad3a0908ef 100644 --- a/project/cmake/scripts/windows/xbmc-cxx-flag-overrides.cmake +++ b/project/cmake/scripts/windows/cxx-flag-overrides.cmake diff --git a/project/cmake/xbmc-config.cmake.in b/project/cmake/xbmc-config.cmake.in index ba271f3a6e..73d1c9c3a5 100644 --- a/project/cmake/xbmc-config.cmake.in +++ b/project/cmake/xbmc-config.cmake.in @@ -1,8 +1,4 @@ -SET(XBMC_INCLUDE_DIR @prefix@/include) -SET(APP_NAME @APP_NAME@) -SET(APP_VERSION_MAJOR @APP_VERSION_MAJOR@) -SET(APP_VERSION_MINOR @APP_VERSION_MINOR@) -LIST(APPEND CMAKE_MODULE_PATH @prefix@/lib/xbmc) -ADD_DEFINITIONS(@ARCH_DEFINES@) +message(WARNING "find_package(xbmc) has been deprecated, please use find_package(kodi)") -include(xbmc-addon-helpers) +find_package(kodi REQUIRED) +set(XBMC_INCLUDE_DIR ${KODI_INCLUDE_DIR})
\ No newline at end of file diff --git a/system/keyboardlayouts.xml b/system/keyboardlayouts.xml index c077009046..56bf53ecff 100644 --- a/system/keyboardlayouts.xml +++ b/system/keyboardlayouts.xml @@ -1,6 +1,10 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- +Please use English language names instead. +Default font lacks support for all characters +--> <keyboardlayouts> - <layout name="QWERTY"> + <layout name="English QWERTY"> <keyboard> <row>1234567890</row> <row>qwertyuiop</row> @@ -20,7 +24,7 @@ <row>`~</row> </keyboard> </layout> - <layout name="AZERTY"> + <layout name="English AZERTY"> <keyboard> <row>1234567890</row> <row>azertyuiop</row> @@ -40,7 +44,7 @@ <row>`~éèçà</row> </keyboard> </layout> - <layout name="ABC"> + <layout name="English ABC"> <keyboard> <row>0123456789</row> <row>abcdefghij</row> @@ -60,7 +64,7 @@ <row>`~</row> </keyboard> </layout> - <layout name="Български ЯВЕРТЪ"> + <layout name="Bulgarian ЯВЕРТЪ"> <keyboard> <row>ч1234567890</row> <row>явертъуиопшщ</row> @@ -80,7 +84,7 @@ <row>`~</row> </keyboard> </layout> - <layout name="Български АБВ"> + <layout name="Bulgarian АБВ"> <keyboard> <row>0123456789</row> <row>абвгдежзий</row> @@ -100,7 +104,7 @@ <row>`~</row> </keyboard> </layout> - <layout name="Русская ЙЦУКЕН"> + <layout name="Russian ЙЦУКЕН"> <keyboard> <row>ё1234567890</row> <row>йцукенгшщзхъ</row> @@ -120,7 +124,7 @@ <row>`~</row> </keyboard> </layout> - <layout name="Русская АБВ"> + <layout name="Russian АБВ"> <keyboard> <row>0123456789</row> <row>абвгдеёжзий</row> @@ -240,4 +244,24 @@ <row>`~</row> </keyboard> </layout> + <layout name="Turkish QWERTY"> + <keyboard> + <row>1234567890</row> + <row>qwertyuıopğü</row> + <row>asdfghjklşi</row> + <row>zxcvbnmöç</row> + </keyboard> + <keyboard modifiers="shift"> + <row>1234567890</row> + <row>QWERTYUIOPĞÜ</row> + <row>ASDFGHJKLŞİ</row> + <row>ZXCVBNMÖÇ</row> + </keyboard> + <keyboard modifiers="symbol,shift+symbol"> + <row>)!@#$%^&*(</row> + <row>[]{}-_=+;:</row> + <row>'",.<>/?\|</row> + <row>`~</row> + </keyboard> + </layout> </keyboardlayouts> diff --git a/system/keymaps/appcommand.xml b/system/keymaps/appcommand.xml index 2d14bd9748..2cbee66a6f 100644 --- a/system/keymaps/appcommand.xml +++ b/system/keymaps/appcommand.xml @@ -17,7 +17,7 @@ <stop>Stop</stop> <play_pause>PlayPause</play_pause> <launch_mail/> - <launch_media_select>XBMC.ActivateWindow(MyMusic)</launch_media_select> + <launch_media_select>ActivateWindow(MyMusic)</launch_media_select> <launch_app1>ActivateWindow(MyPrograms)</launch_app1> <launch_app2>ActivateWindow(MyPrograms)</launch_app2> <play>Play</play> diff --git a/system/keymaps/gamepad.xml b/system/keymaps/gamepad.xml index a21f07098e..6015eb4f7c 100644 --- a/system/keymaps/gamepad.xml +++ b/system/keymaps/gamepad.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -44,14 +44,14 @@ <Y>Queue</Y> <white>ContextMenu</white> <black/> - <start>XBMC.ActivateWindow(PlayerControls)</start> + <start>ActivateWindow(PlayerControls)</start> <back>PreviousMenu</back> <dpadleft>Left</dpadleft> <dpadright>Right</dpadright> <dpadup>Up</dpadup> <dpaddown>Down</dpaddown> <leftthumbbutton>Screenshot</leftthumbbutton> - <rightthumbbutton>XBMC.ActivateWindow(ShutdownMenu)</rightthumbbutton> + <rightthumbbutton>ActivateWindow(ShutdownMenu)</rightthumbbutton> <leftanalogtrigger>ScrollUp</leftanalogtrigger> <rightanalogtrigger>ScrollDown</rightanalogtrigger> <rightthumbstickleft>AnalogSeekBack</rightthumbstickleft> @@ -62,7 +62,7 @@ </global> <Home> <gamepad> - <black>XBMC.Skin.ToggleSetting(HomeViewToggle)</black> + <black>Skin.ToggleSetting(HomeViewToggle)</black> </gamepad> </Home> <MyFiles> @@ -144,7 +144,7 @@ <gamepad> <A>Pause</A> <B>Stop</B> - <Y>XBMC.ActivateWindow(VisualisationPresetList)</Y> + <Y>ActivateWindow(VisualisationPresetList)</Y> <black>CodecInfo</black> <white>Info</white> <start>OSD</start> diff --git a/system/keymaps/joystick.Alienware.Dual.Compatible.Controller.xml b/system/keymaps/joystick.Alienware.Dual.Compatible.Controller.xml index d9872d6e8c..0e3a02ccbc 100644 --- a/system/keymaps/joystick.Alienware.Dual.Compatible.Controller.xml +++ b/system/keymaps/joystick.Alienware.Dual.Compatible.Controller.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -50,9 +50,9 @@ <button id="11">Screenshot</button> <!-- l3 - left analog --> <button id="5"></button> <!-- r1 --> <button id="8"></button> <!-- r2 --> - <button id="12">XBMC.ActivateWindow(ShutdownMenu)</button> <!-- R3 - right analog --> + <button id="12">ActivateWindow(ShutdownMenu)</button> <!-- R3 - right analog --> <button id="9"></button> <!-- select --> - <button id="10">XBMC.ActivateWindow(PlayerControls)</button> <!-- start --> + <button id="10">ActivateWindow(PlayerControls)</button> <!-- start --> <!-- Left Analog Left and Right--> <axis limit="-1" id="0">AnalogSeekBack</axis> <axis limit="+1" id="0">AnalogSeekForward</axis> diff --git a/system/keymaps/joystick.AppleRemote.xml b/system/keymaps/joystick.AppleRemote.xml index bf1fcb8277..fa6335a3db 100644 --- a/system/keymaps/joystick.AppleRemote.xml +++ b/system/keymaps/joystick.AppleRemote.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <button id="6">XBMC.ActivateWindow(Favourites)</button> --> +<!-- eg <button id="6">ActivateWindow(Favourites)</button> --> <!-- would bring up Favourites when the button with the id of 6 is press. In this case, "Menu" --> <!-- --> @@ -84,7 +84,7 @@ </global> <Home> <joystick name="AppleRemote"> - <button id="6">XBMC.ActivateWindow(Favourites)</button> + <button id="6">ActivateWindow(Favourites)</button> <button id="8">ActivateWindow(shutdownmenu)</button> </joystick> </Home> diff --git a/system/keymaps/joystick.Harmony.xml b/system/keymaps/joystick.Harmony.xml index 3ab4104b8e..1567cd7d3f 100644 --- a/system/keymaps/joystick.Harmony.xml +++ b/system/keymaps/joystick.Harmony.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -84,37 +84,37 @@ <!-- # enter --> <button id="36">Select</button> <!-- Mute --> <button id="25">Mute</button> <!-- Aspect --> <button id="61">AspectRatio</button> - <!-- F1 --> <button id="53">XBMC.ActivateWindow(Music)</button> - <!-- F3 --> <button id="55">XBMC.ActivateWindow(videolibrary,tvshowtitles,return)</button> - <!-- F2 --> <button id="54">XBMC.ActivateWindow(videolibrary,movietitles,return)</button> - <!-- F4 --> <button id="56">XBMC.ActivateWindow(Weather)</button> + <!-- F1 --> <button id="53">ActivateWindow(Music)</button> + <!-- F3 --> <button id="55">ActivateWindow(videolibrary,tvshowtitles,return)</button> + <!-- F2 --> <button id="54">ActivateWindow(videolibrary,movietitles,return)</button> + <!-- F4 --> <button id="56">ActivateWindow(Weather)</button> <!-- F5 --> <button id="93">OSD</button> - <!-- F7 --> <button id="95">XBMC.ActivateWindow(Home)</button> - <!-- F6 --> <button id="94">XBMC.ActivateWindow(Scripts)</button> - <!-- F8 --> <button id="96">XBMC.ActivateWindow(favourites)</button> + <!-- F7 --> <button id="95">ActivateWindow(Home)</button> + <!-- F6 --> <button id="94">ActivateWindow(Scripts)</button> + <!-- F8 --> <button id="96">ActivateWindow(favourites)</button> <!-- F9 --> <button id="73">ShowVideoMenu</button> <!-- F10 --> <button id="74">ShowSubtitles</button> <!-- F11 --> <button id="75">NextSubtitle</button> - <!-- F12 --> <button id="76">XBMC.ActivateWindow(VideoFiles)</button> + <!-- F12 --> <button id="76">ActivateWindow(VideoFiles)</button> <!-- F13 --> <button id="63">Playlist</button> <!-- F14 --> <button id="64">AudioNextLanguage</button> <!-- Large Down --> <button id="82">PageDown</button> <!-- Large Up --> <button id="81">PageUp</button> - <!-- pwrToggle --> <button id="66">XBMC.ShutDown()</button> + <!-- pwrToggle --> <button id="66">ShutDown()</button> <!-- Queue --> <button id="62">Queue</button> - <!-- Sleep --> <button id="46">XBMC.Suspend()</button> + <!-- Sleep --> <button id="46">Suspend()</button> <!-- Red --> <button id="83">CodecInfo</button> - <!-- Green --> <button id="84">XBMC.ActivateWindow(Settings)</button> + <!-- Green --> <button id="84">ActivateWindow(Settings)</button> <!-- Yellow --> <button id="85">xbmc.ActivateWindow(SystemSettings)</button> - <!-- Blue --> <button id="86">XBMC.ActivateWindow(SystemInfo)</button> + <!-- Blue --> <button id="86">ActivateWindow(SystemInfo)</button> </joystick> </global> <Home> <joystick name="Harmony"> - <!-- menu --> <button id="6">XBMC.ActivateWindow(PlayerControls)</button> - <!-- Info --> <button id="31">XBMC.ActivateWindow(Settings)</button> - <!-- Exit --> <button id="51">XBMC.ActivateWindow(ShutdownMenu)</button> - <!-- #enter --> <button id="36">XBMC.ActivateWindow(SystemInfo)</button> + <!-- menu --> <button id="6">ActivateWindow(PlayerControls)</button> + <!-- Info --> <button id="31">ActivateWindow(Settings)</button> + <!-- Exit --> <button id="51">ActivateWindow(ShutdownMenu)</button> + <!-- #enter --> <button id="36">ActivateWindow(SystemInfo)</button> <!-- 1 --> <button id="11">ToggleFullScreen</button> </joystick> </Home> @@ -208,8 +208,8 @@ <!-- menu --> <button id="6">OSD</button> <!-- Prev --> <button id="32">LockPreset</button> <!-- Info --> <button id="31">Info</button> - <!-- F8 --> <button id="96">XBMC.ActivateWindow(VisualisationPresetList)</button> - <!-- F9 --> <button id="73">XBMC.ActivateWindow(VisualisationSettings)</button> + <!-- F8 --> <button id="96">ActivateWindow(VisualisationPresetList)</button> + <!-- F9 --> <button id="73">ActivateWindow(VisualisationSettings)</button> </joystick> </Visualisation> <MusicOSD> diff --git a/system/keymaps/joystick.Interact.AxisPad.xml b/system/keymaps/joystick.Interact.AxisPad.xml index 922642aefd..2d292474fc 100644 --- a/system/keymaps/joystick.Interact.AxisPad.xml +++ b/system/keymaps/joystick.Interact.AxisPad.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -50,7 +50,7 @@ <button id="8"></button> <!-- r2 --> <button id="10">PreviousMenu</button> <!-- R3 - right analog --> <button id="11"></button> <!-- select/Escape --> - <button id="12">XBMC.ActivateWindow(PlayerControls)</button> <!-- start/enter --> + <button id="12">ActivateWindow(PlayerControls)</button> <!-- start/enter --> <button id="20"></button> <!-- Toggle Switch--> <!-- Left Analog Left and Right--> <axis limit="-1" id="0">AnalogSeekBack</axis> diff --git a/system/keymaps/joystick.Logitech.RumblePad.2.xml b/system/keymaps/joystick.Logitech.RumblePad.2.xml index 5e1bb71ba0..6d1485274d 100644 --- a/system/keymaps/joystick.Logitech.RumblePad.2.xml +++ b/system/keymaps/joystick.Logitech.RumblePad.2.xml @@ -9,7 +9,7 @@ <button id="3">Back</button> <button id="7">FullScreen</button> <button id="8">ContextMenu</button> - <button id="10">XBMC.ActivateWindow(Home)</button> + <button id="10">ActivateWindow(Home)</button> <button id="11">ActivateWindow(shutdownmenu)</button> <button id="12">Screenshot</button> @@ -31,7 +31,7 @@ <joystick name="Logitech Logitech Cordless RumblePad 2"> <altname>Logitech Cordless RumblePad 2</altname> <altname>Logitech RumblePad 2 USB</altname> - <button id="3">XBMC.ActivateWindow(Favourites)</button> + <button id="3">ActivateWindow(Favourites)</button> </joystick> </Home> @@ -97,7 +97,7 @@ <altname>Logitech RumblePad 2 USB</altname> <button id="2">Pause</button> <button id="3">Stop</button> - <button id="4">XBMC.ActivateWindow(VisualisationPresetList)</button> + <button id="4">ActivateWindow(VisualisationPresetList)</button> <button id="5">Rewind</button> <button id="6">FastForward</button> <button id="10">OSD</button> diff --git a/system/keymaps/joystick.Microsoft.Xbox.360.Controller.xml b/system/keymaps/joystick.Microsoft.Xbox.360.Controller.xml index 22bcd95545..7e807a1702 100644 --- a/system/keymaps/joystick.Microsoft.Xbox.360.Controller.xml +++ b/system/keymaps/joystick.Microsoft.Xbox.360.Controller.xml @@ -14,7 +14,7 @@ <!-- </device> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <button id="x">XBMC.ActivateWindow(Home)</button> --> +<!-- eg <button id="x">ActivateWindow(Home)</button> --> <!-- would automatically go to Home on the press of button 'x'. --> <!-- Joystick Name: Xbox 360 Wireless Receiver --> @@ -47,7 +47,9 @@ <!-- 13 D-Pad Right --> <!-- 14 D-Pad Up --> <!-- 15 D-Pad Down --> -<!-- Axis 6 +1/-1 Triggers - malfunctioning --> +<!-- Axis 3 +1/-1 Triggers left/right (win) --> +<!-- Axis 3 Left Trigger (linux) --> +<!-- Axis 6 Right Trigger (linux) --> <!-- Axis Mappings: --> <!-- --> @@ -90,6 +92,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <!-- A selects. B goes back. X gets context menu. Y goes fullscreen and back. --> <button id="1">Select</button> <button id="2">Back</button> @@ -99,10 +102,10 @@ <button id="5">Queue</button> <button id="6">Playlist</button> <button id="7">PreviousMenu</button> - <button id="8">XBMC.ActivateWindow(Home)</button> + <button id="8">ActivateWindow(Home)</button> <!-- Left stick click activates the shutdown menu. --> - <button id="9">XBMC.ActivateWindow(ShutdownMenu)</button> - <button id="10">XBMC.ActivateWindow(PlayerControls)</button> + <button id="9">ActivateWindow(ShutdownMenu)</button> + <button id="10">ActivateWindow(PlayerControls)</button> <button id="11">Up</button> <button id="12">Down</button> <button id="13">Left</button> @@ -112,8 +115,8 @@ <axis id="1" limit="+1">AnalogSeekForward</axis> <axis id="2" limit="-1">AnalogSeekForward</axis> <axis id="2" limit="+1">AnalogSeekBack</axis> - <axis id="3" limit="+1">ScrollUp</axis> - <axis id="3" limit="-1">ScrollDown</axis> + <axis id="3" trigger="true" limit="+1">ScrollUp</axis> + <axis id="3" trigger="true" limit="-1">ScrollDown</axis> <!-- Push up on the right stick for volueme up. Push down for volume down. --> <axis id="5" limit="-1">VolumeUp</axis> <axis id="5" limit="+1">VolumeDown</axis> @@ -134,6 +137,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="1">Select</button> <button id="2">Back</button> <button id="3">ContextMenu</button> @@ -141,10 +145,10 @@ <button id="5">Queue</button> <button id="6">Playlist</button> <button id="7">PreviousMenu</button> - <button id="8">XBMC.ActivateWindow(Home)</button> - <button id="9">XBMC.ActivateWindow(Home)</button> - <button id="10">XBMC.ActivateWindow(ShutdownMenu)</button> - <button id="11">XBMC.ActivateWindow(PlayerControls)</button> + <button id="8">ActivateWindow(Home)</button> + <button id="9">ActivateWindow(Home)</button> + <button id="10">ActivateWindow(ShutdownMenu)</button> + <button id="11">ActivateWindow(PlayerControls)</button> <button id="12">Left</button> <button id="13">Right</button> <button id="14">Up</button> @@ -153,12 +157,12 @@ <axis id="1" limit="+1">AnalogSeekForward</axis> <axis id="2" limit="-1">AnalogSeekForward</axis> <axis id="2" limit="+1">AnalogSeekBack</axis> + <axis id="3" trigger="true" rest="-32768">ScrollUp</axis> <axis id="4" limit="-1">VolumeDown</axis> <axis id="4" limit="+1">VolumeUp</axis> <axis id="5" limit="-1">VolumeUp</axis> <axis id="5" limit="+1">VolumeDown</axis> - <axis id="6" limit="-1">ScrollUp</axis> - <axis id="6" limit="+1">ScrollDown</axis> + <axis id="6" trigger="true" rest="-32768">ScrollDown</axis> <hat id="1" position="up">Up</hat> <hat id="1" position="down">Down</hat> <hat id="1" position="left">Left</hat> @@ -183,7 +187,8 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> - <button id="8">XBMC.Skin.ToggleSetting(HomeViewToggle)</button> + <altname>Razer Sabertooth Elite (Controller)</altname> + <button id="8">Skin.ToggleSetting(HomeViewToggle)</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> <altname>BigBen Interactive XBOX 360 Controller</altname> @@ -195,7 +200,8 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> - <button id="8">XBMC.Skin.ToggleSetting(HomeViewToggle)</button> + <altname>Razer Sabertooth</altname> + <button id="8">Skin.ToggleSetting(HomeViewToggle)</button> </joystick> </Home> <MyFiles> @@ -216,6 +222,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="6">Highlight</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -228,6 +235,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="6">Highlight</button> </joystick> </MyFiles> @@ -249,6 +257,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="5">Delete</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -261,6 +270,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="5">Delete</button> </joystick> </MyMusicPlaylist> @@ -286,6 +296,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <!-- A pauses and starts the video. B stops the video. @@ -328,6 +339,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="1">Pause</button> <button id="2">Stop</button> <button id="3">OSD</button> @@ -335,15 +347,15 @@ <button id="6">ShowSubtitles</button> <button id="7">SmallStepBack</button> <button id="8">Info</button> - <button id="9">XBMC.ActivateWindow(Home)</button> <!-- guide --> - <button id="10">XBMC.ActivateWindow(ShutdownMenu)</button> <!-- left stick --> + <button id="9">ActivateWindow(Home)</button> <!-- guide --> + <button id="10">ActivateWindow(ShutdownMenu)</button> <!-- left stick --> <button id="11">AudioNextLanguage</button> <!-- right stick --> <button id="12">StepBack</button> <button id="13">StepForward</button> <button id="14">ChapterOrBigStepForward</button> <button id="15">ChapterOrBigStepBack</button> - <axis id="6" limit="-1">AnalogRewind</axis> - <axis id="6" limit="+1">AnalogFastForward</axis> + <axis id="3">AnalogRewind</axis> + <axis id="6">AnalogFastForward</axis> <hat id="1" position="up">BigStepForward</hat> <hat id="1" position="down">BigStepBack</hat> <hat id="1" position="left">StepBack</hat> @@ -368,6 +380,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="11">ChannelUp</button> <button id="12">ChannelDown</button> <button id="13">PreviousChannelGroup</button> @@ -387,6 +400,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="12">PreviousChannelGroup</button> <button id="13">NextChannelGroup</button> <button id="14">ChannelUp</button> @@ -462,6 +476,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> <button id="3">OSD</button> <button id="8">Close</button> @@ -478,11 +493,12 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> <button id="3">OSD</button> <button id="8">Close</button> - <axis id="6" limit="+1">AnalogRewind</axis> - <axis id="6" limit="-1">AnalogFastForward</axis> + <axis id="3">AnalogRewind</axis> + <axis id="6">AnalogFastForward</axis> </joystick> </FullscreenInfo> <PlayerControls> @@ -503,6 +519,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="3">Close</button> <button id="9">Close</button> <button id="10">Close</button> @@ -517,6 +534,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="3">Close</button> <button id="10">Close</button> <button id="11">Close</button> @@ -540,12 +558,13 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="1">Pause</button> <button id="2">Stop</button> - <button id="3">XBMC.ActivateWindow(MusicOSD)</button> - <button id="5">XBMC.ActivateWindow(VisualisationPresetList)</button> + <button id="3">ActivateWindow(MusicOSD)</button> + <button id="5">ActivateWindow(VisualisationPresetList)</button> <button id="6">Info</button> - <button id="10">XBMC.ActivateWindow(MusicOSD)</button> + <button id="10">ActivateWindow(MusicOSD)</button> <button id="11">SkipNext</button> <button id="12">SkipPrevious</button> <button id="13">PreviousPreset</button> @@ -567,18 +586,19 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="1">Pause</button> <button id="2">Stop</button> - <button id="3">XBMC.ActivateWindow(MusicOSD)</button> - <button id="5">XBMC.ActivateWindow(VisualisationPresetList)</button> + <button id="3">ActivateWindow(MusicOSD)</button> + <button id="5">ActivateWindow(VisualisationPresetList)</button> <button id="6">Info</button> - <button id="11">XBMC.ActivateWindow(MusicOSD)</button> + <button id="11">ActivateWindow(MusicOSD)</button> <button id="12">PreviousPreset</button> <button id="13">NextPreset</button> <button id="14">SkipPrevious</button> <button id="15">SkipNext</button> - <axis id="6" limit="-1">AnalogRewind</axis> - <axis id="6" limit="+1">AnalogFastForward</axis> + <axis id="3">AnalogRewind</axis> + <axis id="6">AnalogFastForward</axis> <hat id="1" position="up">SkipNext</hat> <hat id="1" position="down">SkipPrevious</hat> <hat id="1" position="left">PreviousPreset</hat> @@ -603,6 +623,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="3">Close</button> <button id="6">Info</button> </joystick> @@ -616,6 +637,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="3">Close</button> <button id="6">Info</button> </joystick> @@ -638,6 +660,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -650,6 +673,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> </joystick> </VisualisationSettings> @@ -671,6 +695,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -683,6 +708,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> </joystick> </VisualisationPresetList> @@ -704,6 +730,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="1">Pause</button> <button id="2">Stop</button> <button id="4">ZoomNormal</button> @@ -732,6 +759,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="1">Pause</button> <button id="2">Stop</button> <button id="4">ZoomNormal</button> @@ -743,8 +771,8 @@ <button id="15">ZoomOut</button> <axis id="1">AnalogMove</axis> <axis id="2">AnalogMove</axis> - <axis id="6" limit="+1">ZoomOut</axis> - <axis id="6" limit="-1">ZoomIn</axis> + <axis id="3">ZoomOut</axis> + <axis id="6">ZoomIn</axis> <hat id="1" position="up">ZoomIn</hat> <hat id="1" position="down">ZoomOut</hat> <hat id="1" position="left">PreviousPicture</hat> @@ -769,6 +797,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="3">ResetCalibration</button> <button id="5">NextResolution</button> <button id="6">NextCalibration</button> @@ -783,6 +812,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="3">ResetCalibration</button> <button id="5">NextResolution</button> <button id="6">NextCalibration</button> @@ -806,6 +836,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="3">ResetCalibration</button> <button id="5">NextResolution</button> <button id="6">NextCalibration</button> @@ -820,6 +851,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="3">ResetCalibration</button> <button id="5">NextResolution</button> <button id="6">NextCalibration</button> @@ -843,6 +875,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="3">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -855,6 +888,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="3">Close</button> </joystick> </VideoOSD> @@ -876,6 +910,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Stop</button> <button id="3">OSD</button> <button id="5">AspectRatio</button> @@ -891,6 +926,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Stop</button> <button id="3">OSD</button> <button id="5">AspectRatio</button> @@ -915,6 +951,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="5">AspectRatio</button> <button id="3">Close</button> </joystick> @@ -928,6 +965,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="5">AspectRatio</button> <button id="3">Close</button> </joystick> @@ -950,6 +988,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="5">AspectRatio</button> <button id="3">Close</button> </joystick> @@ -963,6 +1002,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="5">AspectRatio</button> <button id="3">Close</button> </joystick> @@ -985,6 +1025,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="5">Delete</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -997,6 +1038,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="5">Delete</button> </joystick> </VideoBookmarks> @@ -1022,6 +1064,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="5">Delete</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1034,6 +1077,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="5">Delete</button> </joystick> </MyVideoPlaylist> @@ -1055,6 +1099,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">BackSpace</button> <button id="4">Symbols</button> <button id="5">Shift</button> @@ -1072,12 +1117,13 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">BackSpace</button> <button id="4">Symbols</button> <button id="5">Shift</button> <button id="10">Enter</button> - <axis id="6" limit="+1">CursorLeft</axis> - <axis id="6" limit="-1">CursorRight</axis> + <axis id="3">CursorLeft</axis> + <axis id="6">CursorRight</axis> </joystick> </VirtualKeyboard> <ContextMenu> @@ -1098,6 +1144,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> <button id="3">Close</button> </joystick> @@ -1111,6 +1158,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> <button id="3">Close</button> </joystick> @@ -1133,6 +1181,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="3">Info</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1145,6 +1194,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="3">Info</button> </joystick> </Scripts> @@ -1166,6 +1216,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">PreviousMenu</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1178,6 +1229,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">PreviousMenu</button> </joystick> </Settings> @@ -1199,6 +1251,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1211,6 +1264,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> </joystick> </AddonInformation> @@ -1232,6 +1286,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1244,6 +1299,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> </joystick> </AddonSettings> @@ -1265,6 +1321,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1277,6 +1334,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> </joystick> </TextViewer> @@ -1298,6 +1356,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">PreviousMenu</button> <button id="9">PreviousMenu</button> </joystick> @@ -1311,6 +1370,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">PreviousMenu</button> <button id="10">PreviousMenu</button> </joystick> @@ -1333,6 +1393,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">PreviousMenu</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1345,6 +1406,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">PreviousMenu</button> </joystick> </submenu> @@ -1366,6 +1428,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1378,6 +1441,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> </joystick> </MusicInformation> @@ -1399,6 +1463,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">Close</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1411,6 +1476,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">Close</button> </joystick> </MovieInformation> @@ -1432,6 +1498,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">BackSpace</button> <button id="9">Enter</button> </joystick> @@ -1445,6 +1512,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">BackSpace</button> <button id="10">Enter</button> </joystick> @@ -1467,6 +1535,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="9">Stop</button> </joystick> <joystick name="Microsoft X-Box 360 pad"> @@ -1479,6 +1548,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="11">Stop</button> </joystick> </GamepadInput> @@ -1500,6 +1570,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">PreviousMenu</button> <button id="9">Close</button> </joystick> @@ -1513,6 +1584,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">PreviousMenu</button> <button id="11">Close</button> </joystick> @@ -1535,6 +1607,7 @@ <altname>Xbox Receiver for Windows (Wireless Controller)</altname> <altname>Xbox wireless receiver for windows (Controller)</altname> <altname>Gamepad F310 (Controller)</altname> + <altname>Razer Sabertooth Elite (Controller)</altname> <button id="2">PreviousMenu</button> <button id="9">Close</button> </joystick> @@ -1548,6 +1621,7 @@ <altname>Pelican PL-3601 'TSZ' Wired Xbox 360 Controller</altname> <altname>Xbox 360 Wireless Receiver</altname> <altname>Xbox 360 Wireless Receiver (XBOX)</altname> + <altname>Razer Sabertooth</altname> <button id="2">PreviousMenu</button> <button id="11">Close</button> </joystick> diff --git a/system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml b/system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml index e2697e84dc..897f6fcaea 100644 --- a/system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml +++ b/system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -49,10 +49,10 @@ <button id="6">ContextMenu</button> <button id="7"/> <button id="8"/> - <button id="9">XBMC.ActivateWindow(PlayerControls)</button> + <button id="9">ActivateWindow(PlayerControls)</button> <button id="10"/> <button id="11">Screenshot</button> - <button id="12">XBMC.ActivateWindow(ShutdownMenu)</button> + <button id="12">ActivateWindow(ShutdownMenu)</button> <button id="13">Up</button> <button id="14">Right</button> <button id="15">Down</button> @@ -71,7 +71,7 @@ <altname>Mad Catz MicroCON</altname> <altname>Logitech Xbox Cordless Controller</altname> <altname>Microsoft X-Box pad (Japan)</altname> - <button id="3">XBMC.Skin.ToggleSetting(HomeViewToggle)</button> + <button id="3">Skin.ToggleSetting(HomeViewToggle)</button> </joystick> </Home> <MyFiles> @@ -179,7 +179,7 @@ <button id="1">Pause</button> <button id="2">Stop</button> <button id="3">CodecInfo</button> - <button id="5">XBMC.ActivateWindow(VisualisationPresetList)</button> + <button id="5">ActivateWindow(VisualisationPresetList)</button> <button id="6">Info</button> <button id="9">OSD</button> <button id="13">NextPreset</button> diff --git a/system/keymaps/joystick.Nintendo.Wii.U.Pro.Controller.xml b/system/keymaps/joystick.Nintendo.Wii.U.Pro.Controller.xml index 4ada215aa9..2b0d422545 100644 --- a/system/keymaps/joystick.Nintendo.Wii.U.Pro.Controller.xml +++ b/system/keymaps/joystick.Nintendo.Wii.U.Pro.Controller.xml @@ -52,11 +52,11 @@ <button id="8">ScrollDown</button> <!-- Home --> - <button id="11">XBMC.ActivateWindow(Home)</button> + <button id="11">ActivateWindow(Home)</button> <!-- Left/Right stick click --> - <button id="12">XBMC.ActivateWindow(ShutdownMenu)</button> - <button id="13">XBMC.ActivateWindow(PlayerControls)</button> + <button id="12">ActivateWindow(ShutdownMenu)</button> + <button id="13">ActivateWindow(PlayerControls)</button> <!-- D-Pad --> <button id="14">Up</button> diff --git a/system/keymaps/joystick.PS3.Remote.Keyboard.xml b/system/keymaps/joystick.PS3.Remote.Keyboard.xml index f930059260..4bc629cc09 100644 --- a/system/keymaps/joystick.PS3.Remote.Keyboard.xml +++ b/system/keymaps/joystick.PS3.Remote.Keyboard.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -50,7 +50,7 @@ <button id="10">FullScreen</button> <button id="12">VolumeUp</button> <button id="11">VolumeDown</button> - <button id="13">XBMC.ActivateWindow(Home)</button> + <button id="13">ActivateWindow(Home)</button> <hat id="1" position="left">Left</hat> <hat id="1" position="right">Right</hat> <hat id="1" position="up">Up</hat> diff --git a/system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml b/system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml index 1dc997b31e..18231cc164 100644 --- a/system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml +++ b/system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -37,7 +37,7 @@ <!-- Coming soon. --> <keymap> <global> - <joystick name="Sony PLAYSTATION(R)3 Controller"> + <joystick name="/Sony PLAYSTATION\(R\)3 Controller.*"> <altname>PLAYSTATION(R)3 Controller</altname> <altname>PS3 Controller</altname> <altname>Sony Computer Entertainment Wireless Controller</altname> @@ -51,8 +51,8 @@ <button id="5">Up</button> <button id="7">Down</button> <button id="2">Screenshot</button> - <button id="3">XBMC.ActivateWindow(ShutdownMenu)</button> - <button id="4">XBMC.ActivateWindow(PlayerControls)</button> + <button id="3">ActivateWindow(ShutdownMenu)</button> + <button id="4">ActivateWindow(PlayerControls)</button> <axis limit="+1" id="4">VolumeDown</axis> <axis limit="-1" id="4">VolumeUp</axis> <axis limit="+1" id="1">AnalogSeekForward</axis> diff --git a/system/keymaps/joystick.WiiRemote.xml b/system/keymaps/joystick.WiiRemote.xml index aedeec5c47..1e1d42b9f9 100644 --- a/system/keymaps/joystick.WiiRemote.xml +++ b/system/keymaps/joystick.WiiRemote.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -45,17 +45,17 @@ <button id="5">Select</button> <button id="6">Back</button> <button id="7">VolumeDown</button> - <button id="8">XBMC.ActivateWindow(Home)</button> + <button id="8">ActivateWindow(Home)</button> <button id="9">VolumeUp</button> <button id="10">ContextMenu</button> - <button id="11">XBMC.ActivateWindow(PlayerControls)</button> + <button id="11">ActivateWindow(PlayerControls)</button> </joystick> </global> <Home> <joystick name="WiiRemote"> <button id="8">Fullscreen</button> - <button id="10">XBMC.ActivateWindow(Favourites)</button> - <button id="11">XBMC.ActivateWindow(ShutdownMenu)</button> + <button id="10">ActivateWindow(Favourites)</button> + <button id="11">ActivateWindow(ShutdownMenu)</button> </joystick> </Home> <MyFiles> @@ -126,7 +126,7 @@ <button id="4">SkipPrevious</button> <button id="5">OSD</button> <button id="6">Info</button> - <button id="8">XBMC.ActivateWindow(music)</button> + <button id="8">ActivateWindow(music)</button> <button id="10">IncreaseRating</button> <button id="11">DecreaseRating</button> </joystick> @@ -139,8 +139,8 @@ </MusicOSD> <VisualisationSettings> <joystick name="WiiRemote"> - <button id="10">XBMC.ActivateWindow(VisualisationPresetList)</button> - <button id="11">XBMC.ActivateWindow(MusicPlaylist)</button> + <button id="10">ActivateWindow(VisualisationPresetList)</button> + <button id="11">ActivateWindow(MusicPlaylist)</button> </joystick> </VisualisationSettings> <SlideShow> diff --git a/system/keymaps/joystick.xml.sample b/system/keymaps/joystick.xml.sample index 001e5e2903..ddaa88c801 100644 --- a/system/keymaps/joystick.xml.sample +++ b/system/keymaps/joystick.xml.sample @@ -42,10 +42,10 @@ <button id="5">Queue</button> <button id="6">Playlist</button> <button id="7">PreviousMenu</button> - <button id="8">XBMC.ActivateWindow(Home)</button> + <button id="8">ActivateWindow(Home)</button> <!-- Left stick click activates the shutdown menu. --> - <button id="9">XBMC.ActivateWindow(ShutdownMenu)</button> - <button id="10">XBMC.ActivateWindow(PlayerControls)</button> + <button id="9">ActivateWindow(ShutdownMenu)</button> + <button id="10">ActivateWindow(PlayerControls)</button> <button id="11">Up</button> <button id="12">Down</button> <button id="13">Left</button> @@ -70,7 +70,7 @@ </global> <Home> <joystick> - <button id="8">XBMC.Skin.ToggleSetting(HomeViewToggle)</button> + <button id="8">Skin.ToggleSetting(HomeViewToggle)</button> </joystick> </Home> <MyFiles> @@ -166,10 +166,10 @@ <joystick> <button id="1">Pause</button> <button id="2">Stop</button> - <button id="3">XBMC.ActivateWindow(MusicOSD)</button> - <button id="5">XBMC.ActivateWindow(VisualisationPresetList)</button> + <button id="3">ActivateWindow(MusicOSD)</button> + <button id="5">ActivateWindow(VisualisationPresetList)</button> <button id="6">Info</button> - <button id="10">XBMC.ActivateWindow(MusicOSD)</button> + <button id="10">ActivateWindow(MusicOSD)</button> <button id="11">SkipNext</button> <button id="12">SkipPrevious</button> <button id="13">PreviousPreset</button> diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml index c162aa867d..c764b41996 100644 --- a/system/keymaps/keyboard.xml +++ b/system/keymaps/keyboard.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -99,11 +99,11 @@ <power>ActivateWindow(shutdownmenu)</power> <sleep>ActivateWindow(shutdownmenu)</sleep> <!-- PVR windows --> - <e>XBMC.ActivateWindow(TVGuide)</e> - <h>XBMC.ActivateWindow(TVChannels)</h> - <j>XBMC.ActivateWindow(RadioChannels)</j> - <k>XBMC.ActivateWindow(TVRecordings)</k> - <b>XBMC.ActivateWindow(TVTimers)</b> + <e>ActivateWindow(TVGuide)</e> + <h>ActivateWindow(TVChannels)</h> + <j>ActivateWindow(RadioChannels)</j> + <k>ActivateWindow(TVRecordings)</k> + <b>ActivateWindow(TVTimers)</b> <!-- Multimedia keyboard keys --> <browser_back>Back</browser_back> <browser_forward/> @@ -111,7 +111,7 @@ <browser_stop/> <browser_search/> <browser_favorites>ActivateWindow(Favourites)</browser_favorites> - <browser_home>XBMC.ActivateWindow(Home)</browser_home> + <browser_home>ActivateWindow(Home)</browser_home> <volume_mute>Mute</volume_mute> <volume_down>VolumeDown</volume_down> <volume_up>VolumeUp</volume_up> @@ -123,7 +123,7 @@ <rewind>Rewind</rewind> <record/> <launch_mail></launch_mail> - <launch_media_select>XBMC.ActivateWindow(MyMusic)</launch_media_select> + <launch_media_select>ActivateWindow(MyMusic)</launch_media_select> <launch_app1_pc_icon>ActivateWindow(MyPrograms)</launch_app1_pc_icon> <launch_app2_pc_icon>ActivateWindow(MyPrograms)</launch_app2_pc_icon> <launch_file_browser/> @@ -158,13 +158,13 @@ </global> <LoginScreen> <keyboard> - <end mod="ctrl">XBMC.ShutDown()</end> + <end mod="ctrl">ShutDown()</end> </keyboard> </LoginScreen> <Home> <keyboard> <i>info</i> - <end mod="ctrl">XBMC.ShutDown()</end> + <end mod="ctrl">ShutDown()</end> </keyboard> </Home> <VirtualKeyboard> @@ -268,7 +268,7 @@ <a>AudioDelay</a> <escape>Fullscreen</escape> <c>Playlist</c> - <v>XBMC.ActivateWindow(Teletext)</v> + <v>ActivateWindow(Teletext)</v> <up mod="ctrl">SubtitleShiftUp</up> <down mod="ctrl">SubtitleShiftDown</down> <pageup>SkipNext</pageup> @@ -318,8 +318,8 @@ <o>CodecInfo</o> <l>LockPreset</l> <escape>FullScreen</escape> - <g>XBMC.ActivateWindow(PVROSDGuide)</g> - <c>XBMC.ActivateWindow(PVROSDChannels)</c> + <g>ActivateWindow(PVROSDGuide)</g> + <c>ActivateWindow(PVROSDChannels)</c> </keyboard> </Visualisation> <MusicOSD> diff --git a/system/keymaps/nyxboard/keyboard.xml b/system/keymaps/nyxboard/keyboard.xml index dc50bd69cf..7075f3934c 100644 --- a/system/keymaps/nyxboard/keyboard.xml +++ b/system/keymaps/nyxboard/keyboard.xml @@ -3,7 +3,7 @@ <keymap> <global> <keyboard> - <home>XBMC.ActivateWindow(Home)</home> + <home>ActivateWindow(Home)</home> <f3>OSD</f3> <!-- EPG: same as Guide (ctrl-G) on MCE remote --> <f3 mod="shift">ActivateWindow(video)</f3> <!-- Red --> <f4 mod="shift">ActivateWindow(music)</f4> <!-- Green --> diff --git a/system/keymaps/remote.xml b/system/keymaps/remote.xml index 3b7ddfc0d3..f1f851a813 100644 --- a/system/keymaps/remote.xml +++ b/system/keymaps/remote.xml @@ -19,7 +19,7 @@ <!-- </universalremote> --> <!-- Note that the action can be a built-in function. --> -<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> --> +<!-- eg <B>ActivateWindow(MyMusic)</B> --> <!-- would automatically go to My Music on the press of the B button. --> <!-- Joysticks / Gamepads: --> @@ -60,24 +60,24 @@ <display>FullScreen</display> <start>PreviousMenu</start> <record>Record</record> - <eject>XBMC.EjectTray()</eject> + <eject>EjectTray()</eject> <volumeplus>VolumeUp</volumeplus> <volumeminus>VolumeDown</volumeminus> <mute>Mute</mute> - <power>XBMC.ShutDown()</power> - <myvideo>XBMC.ActivateWindow(MyVideos)</myvideo> - <mymusic>XBMC.ActivateWindow(MyMusic)</mymusic> - <mypictures>XBMC.ActivateWindow(MyPictures)</mypictures> - <mytv>XBMC.ActivateWindow(TVChannels)</mytv> - <guide>XBMC.ActivateWindow(TVGuide)</guide> - <livetv>XBMC.ActivateWindow(TVChannels)</livetv> - <liveradio>XBMC.ActivateWindow(RadioChannels)</liveradio> - <recordedtv>XBMC.ActivateWindow(TVRecordings)</recordedtv> - <epgsearch>XBMC.ActivateWindow(TVSearch)</epgsearch> - <red>XBMC.ActivateWindow(TVChannels)</red> - <green>XBMC.ActivateWindow(MyVideos)</green> - <yellow>XBMC.ActivateWindow(MyMusic)</yellow> - <blue>XBMC.ActivateWindow(MyPictures)</blue> + <power>ShutDown()</power> + <myvideo>ActivateWindow(MyVideos)</myvideo> + <mymusic>ActivateWindow(MyMusic)</mymusic> + <mypictures>ActivateWindow(MyPictures)</mypictures> + <mytv>ActivateWindow(TVChannels)</mytv> + <guide>ActivateWindow(TVGuide)</guide> + <livetv>ActivateWindow(TVChannels)</livetv> + <liveradio>ActivateWindow(RadioChannels)</liveradio> + <recordedtv>ActivateWindow(TVRecordings)</recordedtv> + <epgsearch>ActivateWindow(TVSearch)</epgsearch> + <red>ActivateWindow(TVChannels)</red> + <green>ActivateWindow(MyVideos)</green> + <yellow>ActivateWindow(MyMusic)</yellow> + <blue>ActivateWindow(MyPictures)</blue> <zero>Number0</zero> <one>Number1</one> <two>JumpSMS2</two> @@ -93,9 +93,9 @@ </global> <Home> <remote> - <info>XBMC.ActivateWindow(SystemInfo)</info> - <clear>XBMC.ActivateWindow(Weather)</clear> - <hash>XBMC.ActivateWindow(Settings)</hash> + <info>ActivateWindow(SystemInfo)</info> + <clear>ActivateWindow(Weather)</clear> + <hash>ActivateWindow(Settings)</hash> </remote> </Home> <MyTVRecordings> @@ -187,8 +187,8 @@ <select>OSD</select> <title>CodecInfo</title> <info>Info</info> - <guide>XBMC.ActivateWindow(PVROSDGuide)</guide> - <teletext>XBMC.ActivateWindow(Teletext)</teletext> + <guide>ActivateWindow(PVROSDGuide)</guide> + <teletext>ActivateWindow(Teletext)</teletext> <subtitle>NextSubtitle</subtitle> <star>NextSubtitle</star> <language>AudioNextLanguage</language> @@ -224,12 +224,12 @@ <down>DecreaseRating</down> <back>Back</back> <title>CodecInfo</title> - <select>XBMC.ActivateWindow(VisualisationPresetList)</select> + <select>ActivateWindow(VisualisationPresetList)</select> <menu>OSD</menu> <start>OSD</start> <info>Info</info> - <guide>XBMC.ActivateWindow(PVROSDGuide)</guide> - <playlist>XBMC.ActivateWindow(PVROSDChannels)</playlist> + <guide>ActivateWindow(PVROSDGuide)</guide> + <playlist>ActivateWindow(PVROSDChannels)</playlist> </remote> </Visualisation> <MusicOSD> diff --git a/system/peripherals.xml b/system/peripherals.xml index a906628994..a67dc2f251 100644 --- a/system/peripherals.xml +++ b/system/peripherals.xml @@ -4,7 +4,7 @@ <setting key="do_not_use_custom_keymap" type="bool" value="0" label="35009" order="1" /> <setting key="keymap" value="nyxboard" label="35007" configurable="0" /> <setting key="enable_flip_commands" type="bool" value="1" label="36005" order="2" /> - <setting key="flip_keyboard" value="XBMC.VideoLibrary.Search" label="36002" order="3" /> + <setting key="flip_keyboard" value="VideoLibrary.Search" label="36002" order="3" /> <setting key="flip_remote" value="Dialog.Close(virtualkeyboard)" label="36003" order="4" /> </peripheral> @@ -26,11 +26,11 @@ <setting key="port" type="string" value="" label="36022" order="15" /> <setting key="tv_vendor" type="int" value="0" configurable="0" /> - <setting key="device_name" type="string" value="XBMC" configurable="0" /> + <setting key="device_name" type="string" value="Kodi" configurable="0" /> <setting key="device_type" type="int" value="1" configurable="0" /> <setting key="wake_devices_advanced" type="string" value="" configurable="0" /> <setting key="standby_devices_advanced" type="string" value="" configurable="0" /> - <setting key="double_tap_timeout_ms" type="int" min="0" value="2000" configurable="0" /> + <setting key="double_tap_timeout_ms" type="int" min="0" value="300" configurable="0" /> </peripheral> <peripheral vendor_product="2548:1001,2548:1002" bus="usb" name="Pulse-Eight CEC Adapter" mapTo="cec"> diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml index 570798bf0b..f572eedbfa 100644 --- a/system/settings/rbp.xml +++ b/system/settings/rbp.xml @@ -1,13 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <settings> <section id="videos"> - <category id="videoplayer"> - <group id="2"> - <setting id="videoplayer.synctype"> - <visible>false</visible> - </setting> - </group> - </category> <category id="videoacceleration"> <group id="1"> <visible>false</visible> @@ -61,10 +54,8 @@ </category> <category id="audiooutput"> <group id="1"> - <setting id="audiooutput.dualaudio" type="boolean" label="37017" help="36542"> - <level>2</level> - <default>false</default> - <control type="toggle" /> + <setting id="audiooutput.processquality"> + <default>101</default> <!-- AE_QUALITY_GPU --> </setting> </group> <group id="3"> diff --git a/system/settings/settings.xml b/system/settings/settings.xml index d8736c3a8d..ea6bafce50 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -144,7 +144,7 @@ </setting> <setting id="locale.keyboardlayouts" type="list[string]" label="310" help="36432"> <level>1</level> - <default>QWERTY</default> + <default>English QWERTY</default> <constraints> <options>keyboardlayouts</options> <delimiter>|</delimiter> @@ -1974,7 +1974,7 @@ <group id="1"> <setting id="services.devicename" type="string" label="1271" help="36321"> <level>0</level> - <default>XBMC</default> + <default>Kodi</default> <control type="edit" format="string" /> </setting> </group> @@ -2751,12 +2751,12 @@ </setting> <setting id="debug.extralogging" type="boolean" label="666" help="36394"> <level>1</level> - <default>false</default> + <default>true</default> <control type="toggle" /> </setting> <setting id="debug.setextraloglevel" type="list[integer]" parent="debug.extralogging" label="668" help="36534"> <level>1</level> - <default></default> + <default>32,64,128,256,512,1024,2048,4096,16384,32768</default> <constraints> <options>loggingcomponents</options> <delimiter>,</delimiter> diff --git a/tools/EventClients/Clients/J2ME Client/j2me_remote.py b/tools/EventClients/Clients/J2ME Client/j2me_remote.py index 5f78f83ffd..b963a87a79 100755 --- a/tools/EventClients/Clients/J2ME Client/j2me_remote.py +++ b/tools/EventClients/Clients/J2ME Client/j2me_remote.py @@ -21,9 +21,9 @@ import sys try: - from xbmc.xbmcclient import * - from xbmc.bt.bt import * - from xbmc.defs import * + from kodi.xbmcclient import * + from kodi.bt.bt import * + from kodi.defs import * except: sys.path.append('../../lib/python') from xbmcclient import * diff --git a/tools/EventClients/Clients/XBMC Send/xbmc-send.py b/tools/EventClients/Clients/Kodi Send/kodi-send.py index 4dfbc5734d..f4a6527def 100755 --- a/tools/EventClients/Clients/XBMC Send/xbmc-send.py +++ b/tools/EventClients/Clients/Kodi Send/kodi-send.py @@ -23,15 +23,15 @@ import sys import getopt from socket import * try: - from xbmc.xbmcclient import * + from kodi.xbmcclient import * except: sys.path.append('../../lib/python') from xbmcclient import * def usage(): - print "xbmc-send [OPTION] --action=ACTION" + print "kodi-send [OPTION] --action=ACTION" print 'Example' - print '\txbmc-send --host=192.168.0.1 --port=9777 --action="XBMC.Quit"' + print '\tkodi-send --host=192.168.0.1 --port=9777 --action="Quit"' print "Options" print "\t-?, --help\t\t\tWill bring up this message" print "\t--host=HOST\t\t\tChoose what HOST to connect to (default=localhost)" diff --git a/tools/EventClients/Clients/OSXRemote/XBMCHelper.m b/tools/EventClients/Clients/OSXRemote/XBMCHelper.m index 1e945499ec..20d0f6fe8f 100644 --- a/tools/EventClients/Clients/OSXRemote/XBMCHelper.m +++ b/tools/EventClients/Clients/OSXRemote/XBMCHelper.m @@ -268,7 +268,7 @@ NSFileManager *fileManager = [NSFileManager defaultManager]; if([fileManager fileExistsAtPath:mp_app_path]){ if(mp_home_path && [mp_home_path length]) - setenv("XBMC_HOME", [mp_home_path UTF8String], 1); + setenv("APP_HOME", [mp_home_path UTF8String], 1); //launch or activate xbmc if(![[NSWorkspace sharedWorkspace] launchApplication:mp_app_path]) ELOG(@"Error launching %@", mp_app_path); diff --git a/tools/EventClients/Clients/OSXRemote/xbmchelper_main.mm b/tools/EventClients/Clients/OSXRemote/xbmchelper_main.mm index 57d86c5c02..bedcfda45a 100644 --- a/tools/EventClients/Clients/OSXRemote/xbmchelper_main.mm +++ b/tools/EventClients/Clients/OSXRemote/xbmchelper_main.mm @@ -47,7 +47,7 @@ static const char *options = "hs:umt:vxa:z:"; void usage(void) { printf("%s (version %s)\n", PROGNAME, PROGVERS); - printf(" Sends Apple Remote events to XBMC.\n\n"); + printf(" Sends Apple Remote events to Kodi.\n\n"); printf("Usage: %s [OPTIONS...]\n\nOptions:\n", PROGNAME); printf(" -h, --help print this help message and exit.\n"); printf(" -s, --server <addr> send events to the specified IP.\n"); @@ -55,8 +55,8 @@ void usage(void) printf(" -u, --universal runs in Universal Remote mode.\n"); printf(" -t, --timeout <ms> timeout length for sequences (default: 500ms).\n"); printf(" -m, --multiremote runs in Multi-Remote mode (adds remote identifier as additional idenfier to buttons)\n"); - printf(" -a, --appPath path to XBMC.app (MenuPress launch support).\n"); - printf(" -z, --appHome path to XBMC.app/Content/Resources/XBMX \n"); + printf(" -a, --appPath path to Kodi.app (MenuPress launch support).\n"); + printf(" -z, --appHome path to Kodi.app/Content/Resources \n"); printf(" -v, --verbose prints lots of debugging information.\n"); } @@ -65,7 +65,7 @@ void ReadConfig() { // Compute filename. std::string strFile = getenv("HOME"); - strFile += "/Library/Application Support/XBMC/XBMCHelper.conf"; + strFile += "/Library/Application Support/Kodi/XBMCHelper.conf"; // Open file. std::ifstream ifs(strFile.c_str()); diff --git a/tools/EventClients/Clients/PS3 BD Remote/ps3_remote.py b/tools/EventClients/Clients/PS3 BD Remote/ps3_remote.py index 6a83406d8a..c5bb6ca9cc 100755 --- a/tools/EventClients/Clients/PS3 BD Remote/ps3_remote.py +++ b/tools/EventClients/Clients/PS3 BD Remote/ps3_remote.py @@ -43,10 +43,10 @@ try: ICON_PATH = "../../icons/" except: # fallback to system wide modules - from xbmc.xbmcclient import * - from xbmc.ps3.keymaps import keymap_remote as g_keymap # look here to change the keymapping - from xbmc.bt.bt import * - from xbmc.defs import * + from kodi.xbmcclient import * + from kodi.ps3.keymaps import keymap_remote as g_keymap # look here to change the keymapping + from kodi.bt.bt import * + from kodi.defs import * import os import time diff --git a/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py b/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py index a88c550f0a..1b54700edd 100755 --- a/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py +++ b/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py @@ -45,19 +45,19 @@ if os.path.exists("../../lib/python"): ICON_PATH = "../../icons/" else: # fallback to system wide modules - from xbmc.bt.hid import HID - from xbmc.bt.bt import bt_lookup_name - from xbmc.xbmcclient import XBMCClient - from xbmc.ps3 import sixaxis - from xbmc.ps3_remote import process_keys as process_remote - from xbmc.defs import * + from kodi.bt.hid import HID + from kodi.bt.bt import bt_lookup_name + from kodi.xbmcclient import XBMCClient + from kodi.ps3 import sixaxis + from kodi.ps3_remote import process_keys as process_remote + from kodi.defs import * try: - from xbmc.ps3 import sixwatch + from kodi.ps3 import sixwatch except Exception, e: print "Failed to import sixwatch now disabled: " + str(e) sixwatch = None try: - import xbmc.zeroconf as zeroconf + import kodi.zeroconf as zeroconf except: zeroconf = None diff --git a/tools/EventClients/Makefile b/tools/EventClients/Makefile deleted file mode 100644 index 7460851e67..0000000000 --- a/tools/EventClients/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -WII_EXTRA_OPTS= -CLEAN_FILES=Clients/WiiRemote/WiiRemote -PYTHON_SITEDIR := $(shell python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()") - -all: install - -wiimote: Clients/WiiRemote/WiiRemote - -Clients/WiiRemote/WiiRemote: - cd Clients/WiiRemote && \ - $(CXX) $(CXXFLAGS) $(LDFLAGS) CWIID_WiiRemote.cpp -lcwiid -lbluetooth -DICON_PATH="\"$(datarootdir)/pixmaps/xbmc/\"" $(WII_EXTRA_OPTS) -o WiiRemote - -j2me-remote: - cd Clients/J2ME\ Client - ant -f build.xml - -install: Clients/WiiRemote/WiiRemote - mkdir -p $(DESTDIR)$(bindir) - cp -a Clients/WiiRemote/WiiRemote $(DESTDIR)$(bindir)/xbmc-wiiremote - cp -a Clients/J2ME\ Client/j2me_remote.py $(DESTDIR)$(bindir)/xbmc-j2meremote - cp -a Clients/PS3\ BD\ Remote/ps3_remote.py $(DESTDIR)$(bindir)/xbmc-ps3remote - cp -a Clients/PS3\ Sixaxis\ Controller/ps3d.py $(DESTDIR)$(bindir)/xbmc-ps3d - cp -a Clients/XBMC\ Send/xbmc-send.py $(DESTDIR)$(bindir)/xbmc-send - mkdir -p $(DESTDIR)$(PYTHON_SITEDIR)/xbmc - echo 'ICON_PATH="$(datarootdir)/pixmaps/xbmc/"' > $(DESTDIR)$(PYTHON_SITEDIR)/xbmc/defs.py - cp -a lib/python/* $(DESTDIR)$(PYTHON_SITEDIR)/xbmc/ - cp -a Clients/PS3\ BD\ Remote/ps3_remote.py $(DESTDIR)$(PYTHON_SITEDIR)/xbmc/ - mkdir -p $(DESTDIR)$(includedir)/xbmc - cp -a lib/c++/* $(DESTDIR)$(includedir)/xbmc/ - mkdir -p $(DESTDIR)$(datarootdir)/pixmaps/xbmc - cp -a icons/* $(DESTDIR)$(datarootdir)/pixmaps/xbmc/ - -include ../../Makefile.include diff --git a/tools/EventClients/Makefile.in b/tools/EventClients/Makefile.in new file mode 100644 index 0000000000..757ee0b141 --- /dev/null +++ b/tools/EventClients/Makefile.in @@ -0,0 +1,33 @@ +WII_EXTRA_OPTS= +CLEAN_FILES=Clients/WiiRemote/WiiRemote +PYTHON_SITEDIR := $(shell python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()") + +all: install + +wiimote: Clients/WiiRemote/WiiRemote + +Clients/WiiRemote/WiiRemote: + cd Clients/WiiRemote && \ + $(CXX) $(CXXFLAGS) $(LDFLAGS) CWIID_WiiRemote.cpp -lcwiid -lbluetooth -DICON_PATH="\"$(datarootdir)/pixmaps/@APP_NAME_LC@/\"" $(WII_EXTRA_OPTS) -o WiiRemote + +j2me-remote: + cd Clients/J2ME\ Client + ant -f build.xml + +install: Clients/WiiRemote/WiiRemote + mkdir -p $(DESTDIR)$(bindir) + cp -a Clients/WiiRemote/WiiRemote $(DESTDIR)$(bindir)/@APP_NAME_LC@-wiiremote + cp -a Clients/J2ME\ Client/j2me_remote.py $(DESTDIR)$(bindir)/@APP_NAME_LC@-j2meremote + cp -a Clients/PS3\ BD\ Remote/ps3_remote.py $(DESTDIR)$(bindir)/@APP_NAME_LC@-ps3remote + cp -a Clients/PS3\ Sixaxis\ Controller/ps3d.py $(DESTDIR)$(bindir)/@APP_NAME_LC@-ps3d + cp -a Clients/Kodi\ Send/kodi-send.py $(DESTDIR)$(bindir)/@APP_NAME_LC@-send + mkdir -p $(DESTDIR)$(PYTHON_SITEDIR)/@APP_NAME_LC@ + echo 'ICON_PATH="$(datarootdir)/pixmaps/@APP_NAME_LC@/"' > $(DESTDIR)$(PYTHON_SITEDIR)/@APP_NAME_LC@/defs.py + cp -a lib/python/* $(DESTDIR)$(PYTHON_SITEDIR)/@APP_NAME_LC@/ + cp -a Clients/PS3\ BD\ Remote/ps3_remote.py $(DESTDIR)$(PYTHON_SITEDIR)/@APP_NAME_LC@/ + mkdir -p $(DESTDIR)$(includedir)/@APP_NAME_LC@ + cp -a lib/c++/* $(DESTDIR)$(includedir)/@APP_NAME_LC@/ + mkdir -p $(DESTDIR)$(datarootdir)/pixmaps/@APP_NAME_LC@ + cp -a icons/* $(DESTDIR)$(datarootdir)/pixmaps/@APP_NAME_LC@/ + +include ../../Makefile.include diff --git a/tools/EventClients/examples/python/example_action.py b/tools/EventClients/examples/python/example_action.py index d5ab9cf61c..2e84bc1573 100755 --- a/tools/EventClients/examples/python/example_action.py +++ b/tools/EventClients/examples/python/example_action.py @@ -27,7 +27,7 @@ def main(): xbmc.send_action(sys.argv[1], ACTION_EXECBUILTIN) except Exception, e: print str(e) - xbmc.send_action("XBMC.ActivateWindow(ShutdownMenu)") + xbmc.send_action("ActivateWindow(ShutdownMenu)") # ok we're done, close the connection diff --git a/tools/Linux/xbmc-standalone.sh.in b/tools/Linux/kodi-standalone.sh.in index d392a6cbd4..6d015b5546 100644 --- a/tools/Linux/xbmc-standalone.sh.in +++ b/tools/Linux/kodi-standalone.sh.in @@ -18,10 +18,12 @@ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # http://www.gnu.org/copyleft/gpl.html +APP=@APP_NAME@ prefix="@prefix@" exec_prefix="@exec_prefix@" bindir="@bindir@" -XBMC="${bindir}/xbmc --standalone $@" +bin_name=@APP_NAME_LC@ +APP="${bindir}/${bin_name} --standalone $@" @XBMC_STANDALONE_SH_PULSE@ @@ -31,7 +33,7 @@ LASTSUCCESSFULSTART=$(date +%s) while [ $(( $LOOP )) = "1" ] do - $XBMC + $APP RET=$? NOW=$(date +%s) if [ $(( ($RET >= 64 && $RET <=66) || $RET == 0 )) = "1" ]; then # clean exit @@ -45,7 +47,7 @@ do CRASHCOUNT=$((CRASHCOUNT+1)) if [ $(($CRASHCOUNT >= 3)) = "1" ]; then # Too many, bail out LOOP=0 - echo "XBMC has exited uncleanly 3 times in the last ${DIFF} seconds." + echo "${APP} has exited uncleanly 3 times in the last ${DIFF} seconds." echo "Something is probably wrong" fi fi diff --git a/tools/Linux/xbmc-standalone.sh.pulse b/tools/Linux/kodi-standalone.sh.pulse index c4d5564344..c4d5564344 100644 --- a/tools/Linux/xbmc-standalone.sh.pulse +++ b/tools/Linux/kodi-standalone.sh.pulse diff --git a/tools/Linux/kodi-xsession.desktop.in b/tools/Linux/kodi-xsession.desktop.in new file mode 100644 index 0000000000..73436dbd2b --- /dev/null +++ b/tools/Linux/kodi-xsession.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Name=@APP_NAME@ +Comment=This session will start @APP_NAME@ Media Center +Exec=@APP_NAME_LC@-standalone +TryExec=@APP_NAME_LC@-standalone +Type=Application diff --git a/tools/Linux/xbmc.desktop b/tools/Linux/kodi.desktop index 4519ad2167..351be2e9a0 100644 --- a/tools/Linux/xbmc.desktop +++ b/tools/Linux/kodi.desktop @@ -1,10 +1,10 @@ [Desktop Entry] Version=1.0 -Name=XBMC Media Center +Name=KODI Media Center GenericName=Media Center -Comment=Manage and view your media -Exec=xbmc -Icon=xbmc +Comment=Manage and view your media +Exec=kodi +Icon=kodi Terminal=false Type=Application Categories=AudioVideo;Video;Player;TV; @@ -13,10 +13,10 @@ Actions=Fullscreen;Standalone; [Desktop Action Fullscreen] Name=Open in fullscreen -Exec=xbmc -fs +Exec=kodi -fs OnlyShowIn=Unity; [Desktop Action Standalone] Name=Open in standalone mode -Exec=xbmc --standalone +Exec=kodi --standalone OnlyShowIn=Unity; diff --git a/tools/Linux/xbmc.sh.in b/tools/Linux/kodi.sh.in index ce850fda82..ccb44b6f73 100644 --- a/tools/Linux/xbmc.sh.in +++ b/tools/Linux/kodi.sh.in @@ -18,12 +18,16 @@ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # http://www.gnu.org/copyleft/gpl.html +APP=@APP_NAME@ +bin_name=@APP_NAME_LC@ SAVED_ARGS="$@" prefix="@prefix@" exec_prefix="@exec_prefix@" datarootdir="@datarootdir@" LIBDIR="@libdir@" CRASHLOG_DIR=${CRASHLOG_DIR:-$HOME} +USERDATA_DIR="${HOME}/.${bin_name}" + # Check for some options used by this script while [ "$#" -gt "0" ] @@ -39,6 +43,18 @@ do esac done +migrate_home() +{ + [ "$(basename $0)" = "xbmc" ] && echo "WARNING: running ${bin_name} as "xbmc" is deprecated and will be removed in later versions, please switch to using the ${bin_name} binary" + + #check if data migration is needed + if [ -d "${HOME}/.xbmc" ] && [ ! -d "${USERDATA_DIR}" ]; then + echo "INFO: migrating userdata folder. Renaming ${HOME}/.xbmc to $USERDATA_DIR" + mv ${HOME}/.xbmc $USERDATA_DIR + touch ${USERDATA_DIR}/.kodi_data_was_migrated + fi +} + command_exists() { command -v $1 >/dev/null 2>&1 @@ -48,23 +64,23 @@ single_stacktrace() { # core filename is either "core.$PID" or "core" find "$1" -maxdepth $2 -name 'core*' | while read core; do - LC_ALL=C gdb --core="$core" --batch 2> /dev/null | grep -q "^Core was generated by \`$LIBDIR/xbmc/xbmc.bin" || continue + LC_ALL=C gdb --core="$core" --batch 2> /dev/null | grep -q "^Core was generated by \`$LIBDIR/${bin_name}/${bin_name}.bin" || continue echo "=====> Core file: "$core" ($(stat -c%y "$core"))" >> $FILE echo " =========================================" >> $FILE - gdb "$LIBDIR/xbmc/xbmc.bin" --core="$core" --batch -ex "thread apply all bt" 2> /dev/null >> $FILE + gdb "$LIBDIR/${bin_name}/${bin_name}.bin" --core="$core" --batch -ex "thread apply all bt" 2> /dev/null >> $FILE rm -f "$core" done } print_crash_report() { - FILE="$CRASHLOG_DIR/xbmc_crashlog-`date +%Y%m%d_%H%M%S`.log" - echo "############## XBMC CRASH LOG ###############" >> $FILE + FILE="$CRASHLOG_DIR/${bin_name}_crashlog-`date +%Y%m%d_%H%M%S`.log" + echo "############## $APP CRASH LOG ###############" >> $FILE echo >> $FILE echo "################ SYSTEM INFO ################" >> $FILE echo -n " Date: " >> $FILE date >> $FILE - echo " XBMC Options: $*" >> $FILE + echo " $APP Options: $*" >> $FILE echo -n " Arch: " >> $FILE uname -m >> $FILE echo -n " Kernel: " >> $FILE @@ -84,18 +100,18 @@ print_crash_report() echo "############### STACK TRACE #################" >> $FILE if command_exists gdb; then if command_exists systemd-coredumpctl; then - systemd-coredumpctl dump -o core xbmc.bin > /dev/null 2>&1 + systemd-coredumpctl dump -o core ${bin_name}.bin > /dev/null 2>&1 fi single_stacktrace "$PWD" 1 # Find in plugins directories - if [ $XBMC_HOME ]; then - BASEDIR=$XBMC_HOME + if [ $APP_HOME ]; then + BASEDIR=$APP_HOME else - BASEDIR="$LIBDIR/xbmc/" + BASEDIR="$LIBDIR/${bin_name}/" fi single_stacktrace "$BASEDIR" 5 - # find in user xbmc dir - single_stacktrace $HOME/.xbmc/ 5 + # find in userdata dir + single_stacktrace $USERDATA_DIR/ 5 else echo "gdb not installed, can't get stack trace." >> $FILE fi @@ -103,9 +119,9 @@ print_crash_report() echo >> $FILE echo "################# LOG FILE ##################" >> $FILE echo >> $FILE - if [ -f ~/.xbmc/temp/xbmc.log ] + if [ -f $USERDATA_DIR/temp/@APP_NAME_LC@.log ] then - cat ~/.xbmc/temp/xbmc.log >> $FILE + cat $USERDATA_DIR/temp/@APP_NAME_LC@.log >> $FILE echo >> $FILE else echo "Logfile not found in the usual place." >> $FILE @@ -115,11 +131,12 @@ print_crash_report() echo >> $FILE echo "############### END LOG FILE ################" >> $FILE echo >> $FILE - echo "############ END XBMC CRASH LOG #############" >> $FILE + echo "############ END $APP CRASH LOG #############" >> $FILE echo "Crash report available at $FILE" } -python @datadir@/xbmc/FEH.py $SAVED_ARGS +migrate_home +python @datadir@/${bin_name}/FEH.py $SAVED_ARGS RET=$? if [ $RET -ne 0 ]; then exit $RET @@ -129,7 +146,7 @@ if command_exists gdb; then # Output warning in case ulimit is unsupported by shell eval ulimit -c unlimited if [ ! $? = "0" ]; then - echo "xbmc: ulimit is unsupported by this shell" 1>&2 + echo "${bin_name}: ulimit is unsupported by this shell" 1>&2 fi fi @@ -137,7 +154,7 @@ LOOP=1 while [ $(( $LOOP )) = "1" ] do LOOP=0 - "$LIBDIR/xbmc/xbmc.bin" $SAVED_ARGS + "$LIBDIR/${bin_name}/${bin_name}.bin" $SAVED_ARGS RET=$? if [ $(( $RET == 65 )) = "1" ] then # User requested to restart app diff --git a/tools/Linux/packaging/mk-debian-package.sh b/tools/Linux/packaging/mk-debian-package.sh index 9a39dfc1c0..4bdab82629 100755 --- a/tools/Linux/packaging/mk-debian-package.sh +++ b/tools/Linux/packaging/mk-debian-package.sh @@ -1,7 +1,7 @@ #!/bin/bash # # Copyright (C) 2013 Team XBMC -# http://xbmc.org +# http://kodi.tv # # This Program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -99,7 +99,7 @@ function archiveRepo { cd $REPO_DIR || exit 1 git clean -xfd echo $REV > VERSION - DEST="xbmc-${RELEASEV}~git$(date '+%Y%m%d.%H%M')-${TAG}" + DEST="kodi-${RELEASEV}~git$(date '+%Y%m%d.%H%M')-${TAG}" [[ -d debian ]] && rm -rf debian cd .. tar -czf ${DEST}.tar.gz -h --exclude .git $(basename $REPO_DIR) diff --git a/tools/Linux/xbmc-xsession.desktop b/tools/Linux/xbmc-xsession.desktop deleted file mode 100644 index 6455dfeaa8..0000000000 --- a/tools/Linux/xbmc-xsession.desktop +++ /dev/null @@ -1,6 +0,0 @@ -[Desktop Entry] -Name=XBMC -Comment=This session will start XBMC Media Center -Exec=xbmc-standalone -TryExec=xbmc-standalone -Type=Application diff --git a/tools/android/packaging/.gitignore b/tools/android/packaging/.gitignore index 0401aa1d7e..467d2ac3e6 100644 --- a/tools/android/packaging/.gitignore +++ b/tools/android/packaging/.gitignore @@ -5,6 +5,6 @@ xbmc/libs/* xbmc/obj/* xbmc/res/drawable/splash.png xbmc/src/R.java -xbmc/src/org/xbmc/xbmc/*.class +xbmc/src/org/xbmc/kodi/*.class xbmc/classes.dex tmp/* diff --git a/tools/android/packaging/Makefile b/tools/android/packaging/Makefile.in index c54578a942..121b515a05 100644 --- a/tools/android/packaging/Makefile +++ b/tools/android/packaging/Makefile.in @@ -13,6 +13,16 @@ EXCLUDED_ADDONS = screensaver.rsxs.euphoria visualization.dxspectrum visualizati XBMCROOT = $(shell cd $(CURDIR)/../../..; pwd) COPYDIRS = system addons language media GCC_VERSION=$(shell $(CC) -dumpversion) +ZIP=zip + +SIGN_STORE=~/.android/debug.keystore +SIGN_STOREPASS=android +SIGN_KEY=androiddebugkey +SIGN_KEYPASS= + +ifneq ($(strip $(SIGN_KEYPASS)),) +SIGN_KEYPASS_OPT=-keypass $(SIGN_KEYPASS) +endif X86OVERRIDES=XBMC_OVERRIDE_HOST=i686-android-linux XBMC_OVERRIDE_TOOLCHAIN=$(XBMC_X86_TOOLCHAIN) ARMOVERRIDES=XBMC_OVERRIDE_HOST=arm-linux-androideabi XBMC_OVERRIDE_TOOLCHAIN=$(XBMC_ARM_TOOLCHAIN) @@ -26,6 +36,7 @@ CPU=x86 endif ifeq ($(findstring arm,$(CPU)),arm) ARCH=arm +CPU=armeabi-v7a endif #older ndk x86 @@ -41,60 +52,71 @@ ifneq ($(shell test -f $(GDBPATH) && echo 1),1) GDBPATH=$(NDKROOT)/prebuilt/android-$(ARCH)/gdbserver/gdbserver endif -all: package SRCLIBS = $(addprefix $(PREFIX)/lib/,$(OBJS)) $(addprefix $(PREFIX)/lib/$(SDK_PLATFORM)/,$(PLATFORM_OBJS)) -DSTLIBS = $(CPU)/lib/libxbmc.so $(addprefix $(CPU)/lib/,$(OBJS)) $(addprefix $(CPU)/lib/,$(PLATFORM_OBJS)) +DSTLIBS = $(CPU)/lib/lib@APP_NAME_LC@.so $(addprefix $(CPU)/lib/,$(OBJS)) $(addprefix $(CPU)/lib/,$(PLATFORM_OBJS)) libs= $(DSTLIBS) -multi: x86 arm - @cp images/xbmcapp-debug-skeleton.apk images/xbmcapp-debug-multi-unaligned.apk - @cd xbmc; zip -r -q ../images/xbmcapp-debug-multi-unaligned.apk lib/ assets - @jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore ~/.android/debug.keystore -storepass android images/xbmcapp-debug-multi-unaligned.apk androiddebugkey - @$(ZIPALIGN) -f 4 images/xbmcapp-debug-multi-unaligned.apk $(XBMCROOT)/xbmcapp-multi-debug.apk - @rm images/xbmcapp-debug-multi-unaligned.apk - @echo "$(XBMCROOT)/xbmcapp-multi-debug.apk created" +all: apk -package: extras - @cp images/xbmcapp-debug-skeleton.apk images/xbmcapp-debug-$(CPU)-unaligned.apk - @javac -classpath $(SDKROOT)/platforms/$(SDK_PLATFORM)/android.jar:xbmc/obj -d xbmc/obj -sourcepath xbmc/src xbmc/src/*.java - @javac -classpath $(SDKROOT)/platforms/$(SDK_PLATFORM)/android.jar:xbmc/obj -d xbmc/obj -sourcepath xbmc/src xbmc/src/org/xbmc/xbmc/*.java - @$(DX) --dex --output=xbmc/classes.dex xbmc/obj - @cd xbmc; zip -r -q ../images/xbmcapp-debug-$(CPU)-unaligned.apk lib/$(CPU) assets classes.dex - @jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore ~/.android/debug.keystore -storepass android images/xbmcapp-debug-$(CPU)-unaligned.apk androiddebugkey - @$(ZIPALIGN) -f 4 images/xbmcapp-debug-$(CPU)-unaligned.apk $(XBMCROOT)/xbmcapp-$(CPU)-debug.apk - @rm images/xbmcapp-debug-$(CPU)-unaligned.apk - @echo "$(XBMCROOT)/xbmcapp-$(CPU)-debug.apk created" +apk: apk-clean sharedapk package apk-sign -extras: libs - rm -rf xbmc/assets - mkdir -p xbmc/assets xbmc/res xbmc/res/raw xbmc/assets/python2.6/lib/ - cp -rfp $(PREFIX)/share/xbmc/* ./xbmc/assets - find `pwd`/xbmc/assets/ -depth -name ".git" -exec rm -rf {} \; - find `pwd`/xbmc/assets/system/ -name "*.so" -exec rm {} \; - find `pwd`/xbmc/assets/addons/skin.*/media/* -depth -not -iname "Textures.xbt" -exec rm -rf {} \; - find `pwd`/xbmc/assets/system/keymaps/ -depth -name "joystick*.xml" -exec rm {} \; - mv -f `pwd`/xbmc/assets/system/keymaps/joystick.xml.sample `pwd`/xbmc/assets/system/keymaps/joystick.xml - @echo "native_arch=$(ARCH)" > xbmc/res/raw/xbmc.properties - cd xbmc/assets/addons; rm -rf $(EXCLUDED_ADDONS) +obb: apk-clean sharedobb + +apk-unsigned: apk-clean sharedapk package + +apk-obb: apk-clean sharedobb package apk-sign + +apk-obb-unsigned: apk-clean sharedobb package + +apk-noobb: apk-clean package apk-sign + +xbmc/assets: + mkdir -p xbmc/assets + +shared: + mkdir -p assets + cp -rfp $(PREFIX)/share/@APP_NAME_LC@/* ./assets + find `pwd`/assets/ -depth -name ".git" -exec rm -rf {} \; + find `pwd`/assets/system/ -name "*.so" -exec rm {} \; + find `pwd`/assets/addons/skin.*/media/* -depth -not -iname "Textures.xbt" -exec rm -rf {} \; + find `pwd`/assets/system/keymaps/ -depth -name "joystick*.xml" ! -name "joystick.xml" -exec rm {} \; + mv -f `pwd`/assets/system/keymaps/joystick.xml.sample `pwd`/assets/system/keymaps/joystick.xml + cd assets; rm -rf $(EXCLUDED_ADDONS) + +sharedapk: shared | xbmc/assets + cp -rfp assets/* ./xbmc/assets + +sharedobb: shared + rm -f $(XBMCROOT)/main.@APP_NAME_LC@.obb + $(ZIP) -9 -q -r $(XBMCROOT)/main.@APP_NAME_LC@.obb assets + @echo "$(XBMCROOT)/main.@APP_NAME_LC@.obb created" + +python: | xbmc/assets + mkdir -p xbmc/assets/python2.6/lib/ cp -rfp $(PREFIX)/lib/python2.6 xbmc/assets/python2.6/lib/ + cd xbmc/assets/python2.6/lib/python2.6/; rm -rf test config lib-dynload + +res: + mkdir -p xbmc/res xbmc/res/raw xbmc/res/values images + @echo "native_arch=$(ARCH)" > xbmc/res/raw/xbmc.properties cp -fp $(XBMCROOT)/media/Splash.png xbmc/res/drawable/splash.png cp -fp media/drawable-hdpi/ic_launcher.png xbmc/res/drawable-hdpi/ic_launcher.png cp -fp media/drawable-ldpi/ic_launcher.png xbmc/res/drawable-ldpi/ic_launcher.png cp -fp media/drawable-mdpi/ic_launcher.png xbmc/res/drawable-mdpi/ic_launcher.png cp -fp media/drawable-xhdpi/ic_launcher.png xbmc/res/drawable-xhdpi/ic_launcher.png cp -fp media/drawable-xxhdpi/ic_launcher.png xbmc/res/drawable-xxhdpi/ic_launcher.png - cd xbmc/assets/python2.6/lib/python2.6/; rm -rf test config lib-dynload + cp xbmc/strings.xml xbmc/res/values/ mkdir -p tmp/res; $(AAPT) c -S xbmc/res -C tmp/res; cp -r -n xbmc/res tmp/ || true - $(AAPT) p -f -I $(SDKROOT)/platforms/$(SDK_PLATFORM)/android.jar -S tmp/res/ -M xbmc/AndroidManifest.xml -F images/xbmcapp-debug-skeleton.apk -J xbmc/src + $(AAPT) p -f -I $(SDKROOT)/platforms/$(SDK_PLATFORM)/android.jar -S tmp/res/ -M xbmc/AndroidManifest.xml -F images/@APP_NAME_LC@app-debug-skeleton.apk -J xbmc/src @rm -rf tmp/ -libs: $(PREFIX)/lib/xbmc/libxbmc.so +libs: $(PREFIX)/lib/@APP_NAME_LC@/lib@APP_NAME_LC@.so rm -rf xbmc/lib/$(CPU) xbmc/libs/$(CPU) xbmc/obj/local/$(CPU) - mkdir -p xbmc/lib/$(CPU) images xbmc/assets/python2.6/lib/ xbmc/libs/$(CPU) xbmc/obj/local/$(CPU) + mkdir -p xbmc/lib/$(CPU) xbmc/assets/python2.6/lib/ xbmc/libs/$(CPU) xbmc/obj/local/$(CPU) cp -fp $(SRCLIBS) xbmc/obj/local/$(CPU)/ - cp -fp $(PREFIX)/lib/xbmc/libxbmc.so xbmc/obj/local/$(CPU)/ - find $(PREFIX)/lib/xbmc/addons -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \; - find $(PREFIX)/lib/xbmc/system -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \; + cp -fp $(PREFIX)/lib/@APP_NAME_LC@/lib@APP_NAME_LC@.so xbmc/obj/local/$(CPU)/ + find $(PREFIX)/lib/@APP_NAME_LC@/addons -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \; + find $(PREFIX)/lib/@APP_NAME_LC@/system -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \; cd xbmc/obj/local/$(CPU)/; find . -name "*.so" -not -name "lib*.so" | sed "s/\.\///" | xargs -I@ mv @ lib@ cp -fp xbmc/obj/local/$(CPU)/*.so xbmc/lib/$(CPU)/ $(STRIP) --strip-unneeded xbmc/lib/$(CPU)/*.so @@ -104,29 +126,42 @@ libs: $(PREFIX)/lib/xbmc/libxbmc.so "$(NDKROOT)/sources/cxx-stl/gnu-libstdc++/$(GCC_VERSION)/include $(XBMCROOT) $(PREFIX)/include jni" >> ./xbmc/libs/$(CPU)/gdb.setup cp -fp xbmc/libs/$(CPU)/* xbmc/lib/$(CPU) -$(PREFIX)/lib/xbmc/libxbmc.so: $(SRCLIBS) - $(MAKE) -C ../../depends/target/xbmc +xbmc/classes.dex: res + mkdir -p xbmc/obj + @javac -classpath $(SDKROOT)/platforms/$(SDK_PLATFORM)/android.jar:xbmc/obj -d xbmc/obj -sourcepath xbmc/src xbmc/src/*.java + @javac -classpath $(SDKROOT)/platforms/$(SDK_PLATFORM)/android.jar:xbmc/obj -d xbmc/obj -sourcepath xbmc/src xbmc/src/org/xbmc/@APP_NAME_LC@/*.java + @$(DX) --dex --output=xbmc/classes.dex xbmc/obj -$(SRCLIBS): +package: libs python xbmc/classes.dex + @echo "Creating package..." + @cp images/@APP_NAME_LC@app-debug-skeleton.apk images/@APP_NAME_LC@app-debug-$(CPU)-unaligned.apk + @cd xbmc; $(ZIP) -r -q ../images/@APP_NAME_LC@app-debug-$(CPU)-unaligned.apk lib/$(CPU) assets classes.dex -arm: armeabi-v7a +apk-sign: + @echo "Signing..." + @jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore $(SIGN_STORE) -storepass $(SIGN_STOREPASS) $(SIGN_KEYPASS_OPT) images/@APP_NAME_LC@app-debug-$(CPU)-unaligned.apk $(SIGN_KEY) + @$(ZIPALIGN) -f 4 images/@APP_NAME_LC@app-debug-$(CPU)-unaligned.apk $(XBMCROOT)/@APP_NAME_LC@app-$(CPU)-debug.apk + @rm images/@APP_NAME_LC@app-debug-$(CPU)-unaligned.apk + @echo "$(XBMCROOT)/@APP_NAME_LC@app-$(CPU)-debug.apk created" -armeabi-v7a: $(XBMC_ARM_TOOLCHAIN) force - XBMC_OVERRIDE_PLATFORM=$@ $(ARMOVERRIDES) $(MAKE) package +$(PREFIX)/lib/xbmc/lib@APP_NAME_LC@.so: $(SRCLIBS) + $(MAKE) -C ../../depends/target/xbmc -x86: $(XBMC_X86_TOOLCHAIN) force - XBMC_OVERRIDE_PLATFORM=$@ $(X86OVERRIDES) $(MAKE) package +$(SRCLIBS): -clean: +apk-clean: rm -rf images rm -rf xbmc/lib rm -rf xbmc/libs rm -rf xbmc/assets rm -rf xbmc/obj rm -rf xbmc/res/raw + rm -rf xbmc/res/values rm -rf tmp rm -f xbmc/res/drawable/splash.png rm -f xbmc/src/R.java rm -f xbmc/classes.dex + rm -rf assets + +.PHONY: force libs assets python sharedapk sharedobb res package -.PHONY: arm armeabi-v7a x86 force extras libs diff --git a/tools/android/packaging/apksign b/tools/android/packaging/apksign new file mode 100755 index 0000000000..0a2289b6c7 --- /dev/null +++ b/tools/android/packaging/apksign @@ -0,0 +1,10 @@ +#!/bin/bash +usage(){ + echo "Usage: $0 <keystore_filename> <keystore_password> <key_name> [<key_password>]" + exit 1 +} + +[[ $# -lt 3 ]] && usage + +make apk-sign SIGN_STORE=$1 SIGN_STOREPASS=$2 SIGN_KEY=$3 SIGN_KEYPASS=$4 + diff --git a/tools/android/packaging/xbmc/AndroidManifest.xml.in b/tools/android/packaging/xbmc/AndroidManifest.xml.in index 0eaa2cdee3..e185665507 100644 --- a/tools/android/packaging/xbmc/AndroidManifest.xml.in +++ b/tools/android/packaging/xbmc/AndroidManifest.xml.in @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!-- BEGIN_INCLUDE(manifest) --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.xbmc.xbmc" + package="org.xbmc.@APP_NAME_LC@" android:versionCode="@APP_VERSION_CODE@" android:versionName="@APP_VERSION_MAJOR@.@APP_VERSION_MINOR@-@APP_VERSION_TAG@" > @@ -13,9 +13,14 @@ <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-feature android:name="android.hardware.screen.landscape" android:required="true" /> <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> + <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" /> + <uses-feature android:name="android.hardware.type.television" android:required="false" /> + <uses-feature android:name="android.hardware.usb.host" android:required="false" /> + <uses-feature android:name="android.hardware.wifi" android:required="false" /> - <application android:icon="@drawable/ic_launcher" android:debuggable="true" android:label="@string/app_name" android:hasCode="true"> + <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:hasCode="true"> <activity android:name=".Splash" android:configChanges="orientation|keyboard|keyboardHidden|navigation|touchscreen" @@ -63,7 +68,7 @@ android:name=".Main" android:configChanges="orientation|keyboard|keyboardHidden|navigation|touchscreen" android:finishOnTaskLaunch="true" - android:label="XBMC" + android:label="@string/app_name" android:launchMode="singleInstance" android:screenOrientation="sensorLandscape" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" > @@ -71,7 +76,7 @@ <!-- Tell NativeActivity the name of or .so --> <meta-data android:name="android.app.lib_name" - android:value="xbmc" /> + android:value="@APP_NAME_LC@" /> </activity> </application> diff --git a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/Main.java b/tools/android/packaging/xbmc/src/org/xbmc/kodi/Main.java.in index 43e6117ce7..963149407f 100644 --- a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/Main.java +++ b/tools/android/packaging/xbmc/src/org/xbmc/kodi/Main.java.in @@ -1,4 +1,4 @@ -package org.xbmc.xbmc; +package org.xbmc.@APP_NAME_LC@; import android.app.NativeActivity; import android.content.Intent; diff --git a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/Splash.java b/tools/android/packaging/xbmc/src/org/xbmc/kodi/Splash.java.in index b1e3189686..b5f46fcdda 100644 --- a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/Splash.java +++ b/tools/android/packaging/xbmc/src/org/xbmc/kodi/Splash.java.in @@ -1,4 +1,4 @@ -package org.xbmc.xbmc; +package org.xbmc.@APP_NAME_LC@; import java.io.BufferedOutputStream; import java.io.File; @@ -14,6 +14,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import java.util.Arrays; +import java.util.Comparator; import java.util.Properties; import java.util.Enumeration; import java.util.ArrayList; @@ -57,7 +59,7 @@ public class Splash extends Activity { private static final int StorageChecked = 8; private static final int StartingXBMC = 99; - private static final String TAG = "XBMC"; + private static final String TAG = "@APP_NAME@"; private String mCpuinfo = ""; private ArrayList<String> mMounts = new ArrayList<String>(); @@ -132,7 +134,7 @@ public class Splash extends Activity { break; case StartingXBMC: - mSplash.mTextView.setText("Starting XBMC..."); + mSplash.mTextView.setText("Starting @APP_NAME@..."); mSplash.mProgress.setVisibility(View.INVISIBLE); mSplash.startXBMC(); break; @@ -357,11 +359,85 @@ public class Splash extends Activity { sXbmcHome = fCacheDir.getAbsolutePath() + "/apk"; } - sPackagePath = getPackageResourcePath(); - fPackagePath = new File(sPackagePath); fXbmcHome = new File(sXbmcHome); + + try + { + sPackagePath = Environment.getExternalStorageDirectory() + + "/Android/obb/" + getPackageName() + "/main." + + getPackageManager().getPackageInfo(getPackageName(), 0).versionCode + + "." + getPackageName() + ".obb"; + } catch (Exception e) + { + } + + fPackagePath = new File(sPackagePath); + if (!fPackagePath.exists()) + { + // Check for latest obb + String obbdir = Environment.getExternalStorageDirectory() + + "/Android/obb/" + getPackageName(); + File[] obbfiles = new File(obbdir).listFiles(); + if (obbfiles != null && obbfiles.length > 0) + { + Arrays.sort(obbfiles, new Comparator<File>() + { + public int compare(File f1, File f2) + { + // Sort by lastmodified descending + return Long.valueOf(f2.lastModified()).compareTo(f1.lastModified()); + } + }); + fPackagePath = obbfiles[0]; + } + } + + if (fPackagePath.exists()) + { + sPackagePath = fPackagePath.getAbsolutePath(); + Log.i(TAG, "Using OBB: " + sPackagePath); + } else + { + sPackagePath = getPackageResourcePath(); + fPackagePath = new File(sPackagePath); + if (fPackagePath.length() < 50 * 1024 * 1024) + { + // No OBB and apk < 50Mb? Nah... + mErrorMsg = "OBB not yet present. Please retry later..."; + Log.e(TAG, mErrorMsg); + mState = InError; + } + } } + private void MigrateUserData() { + String sOldUserDir = getExternalFilesDir(null).getParentFile().getParentFile() + "/org.xbmc.xbmc/files/.xbmc"; + File fOldUserDir = new File(sOldUserDir); + File fNewUserDir = new File(getExternalFilesDir(null), ".@APP_NAME_LC@"); + String sKodiMigrated = fNewUserDir.getAbsolutePath() + "/.kodi_data_was_migrated"; + File fKodiMigrated = new File(sKodiMigrated); + + Log.d(TAG, "External_dir = " + fOldUserDir); + if (fOldUserDir.exists() && !fNewUserDir.exists()) { + Log.d(TAG, "XBMC user data detected at " + fOldUserDir.getAbsolutePath() + ", migrating to " + fNewUserDir.getAbsolutePath()); + if (!fNewUserDir.getParentFile().exists() && !fNewUserDir.getParentFile().mkdirs()) { + Log.d(TAG, "Error creating " + fNewUserDir.getParentFile().getAbsolutePath()); + return; + } + if (fOldUserDir.renameTo(fNewUserDir)) { + try { + new FileOutputStream(fKodiMigrated).close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + Log.d(TAG, "XBMC user data migrated to @APP_NAME@ successfully"); + } else { + Log.d(TAG, "Error migrating XBMC user data"); + } + } + } + + private boolean ParseCpuFeature() { ProcessBuilder cmd; @@ -466,13 +542,13 @@ public class Splash extends Activity { } protected void startXBMC() { - // NB: We only preload libxbmc to be able to get info on missing symbols. + // NB: We only preload lib@APP_NAME_LC@ to be able to get info on missing symbols. // This is not normally needed - System.loadLibrary("xbmc"); + System.loadLibrary("@APP_NAME_LC@"); - // Run XBMC + // Run @APP_NAME@ Intent intent = getIntent(); - intent.setClass(this, org.xbmc.xbmc.Main.class); + intent.setClass(this, org.xbmc.@APP_NAME_LC@.Main.class); intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); startActivity(intent); finish(); @@ -482,15 +558,15 @@ public class Splash extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Check if XBMC is not already running + // Check if @APP_NAME@ is not already running ActivityManager activityManager = (ActivityManager) getBaseContext() .getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> tasks = activityManager .getRunningTasks(Integer.MAX_VALUE); for (RunningTaskInfo task : tasks) if (task.topActivity.toString().equalsIgnoreCase( - "ComponentInfo{org.xbmc.xbmc/org.xbmc.xbmc.Main}")) { - // XBMC already running; just activate it + "ComponentInfo{org.xbmc.@APP_NAME_LC@/org.xbmc.@APP_NAME_LC@.Main}")) { + // @APP_NAME@ already running; just activate it startXBMC(); return; } @@ -517,7 +593,7 @@ public class Splash extends Activity { properties.load(xbmcprop); if (!curArch.equalsIgnoreCase(properties.getProperty("native_arch"))) { - mErrorMsg = "This XBMC package is not compatible with your device (" + curArch + " vs. " + properties.getProperty("native_arch") +").\nPlease check the <a href=\"http://wiki.xbmc.org/index.php?title=XBMC_for_Android_specific_FAQ\">XBMC Android wiki</a> for more information."; + mErrorMsg = "This @APP_NAME@ package is not compatible with your device (" + curArch + " vs. " + properties.getProperty("native_arch") +").\nPlease check the <a href=\"http://wiki.kodi.tv/index.php?title=XBMC_for_Android_specific_FAQ\">Kodi Android wiki</a> for more information."; Log.e(TAG, mErrorMsg); mState = InError; } @@ -543,7 +619,7 @@ public class Splash extends Activity { } else { ret = CheckCpuFeature("neon"); if (!ret) { - mErrorMsg = "This XBMC package is not compatible with your device (NEON).\nPlease check the <a href=\"http://wiki.xbmc.org/index.php?title=XBMC_for_Android_specific_FAQ\">XBMC Android wiki</a> for more information."; + mErrorMsg = "This @APP_NAME@ package is not compatible with your device (NEON).\nPlease check the <a href=\"http://wiki.kodi.tv/index.php?title=XBMC_for_Android_specific_FAQ\">Kodi Android wiki</a> for more information."; Log.e(TAG, mErrorMsg); mState = InError; } @@ -559,6 +635,8 @@ public class Splash extends Activity { mState = ChecksDone; SetupEnvironment(); + MigrateUserData(); + if (fXbmcHome.exists() && fXbmcHome.lastModified() >= fPackagePath.lastModified() && !mInstallLibs) { mState = CachingDone; mCachingDone = true; diff --git a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCBroadcastReceiver.java b/tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCBroadcastReceiver.java.in index 93e37a43de..2909644f62 100644 --- a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCBroadcastReceiver.java +++ b/tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCBroadcastReceiver.java.in @@ -1,4 +1,4 @@ -package org.xbmc.xbmc; +package org.xbmc.@APP_NAME_LC@; import android.content.BroadcastReceiver; import android.content.Context; diff --git a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCOnFrameAvailableListener.java b/tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCOnFrameAvailableListener.java.in index 6d1732f296..9778ed35e1 100644 --- a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCOnFrameAvailableListener.java +++ b/tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCOnFrameAvailableListener.java.in @@ -1,4 +1,4 @@ -package org.xbmc.xbmc; +package org.xbmc.@APP_NAME_LC@; import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture.OnFrameAvailableListener; diff --git a/tools/android/packaging/xbmc/res/values/strings.xml b/tools/android/packaging/xbmc/strings.xml.in index f938cf354d..44b88b6b1e 100644 --- a/tools/android/packaging/xbmc/res/values/strings.xml +++ b/tools/android/packaging/xbmc/strings.xml.in @@ -2,6 +2,6 @@ <resources> <string name="hello">bruhahaha</string> - <string name="app_name">XBMC</string> + <string name="app_name">@APP_NAME@</string> -</resources>
\ No newline at end of file +</resources> diff --git a/tools/buildsteps/android/package b/tools/buildsteps/android/package index 4708d969bb..5501d35ded 100644 --- a/tools/buildsteps/android/package +++ b/tools/buildsteps/android/package @@ -2,9 +2,19 @@ WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )} XBMC_PLATFORM_DIR=android . $WORKSPACE/tools/buildsteps/defaultenv -cd $WORKSPACE;make apk +if [ "x$BUILD_OBB" == "xtrue" ] +then + cd $WORKSPACE;make apk-obb-unsigned +else + cd $WORKSPACE;make apk-unsigned +fi +$RUN_SIGNSTEP #rename for upload #e.x. xbmc-20130314-8c2fb31-Frodo-armeabi-v7a.apk -UPLOAD_FILENAME="xbmc-$(getBuildRevDateStr)-armeabi-v7a.apk" -mv xbmcapp-armeabi-*.apk $UPLOAD_FILENAME +UPLOAD_FILENAME="kodi-$(getBuildRevDateStr)-armeabi-v7a" +mv kodiapp-armeabi-*.apk $UPLOAD_FILENAME.apk +if [ -f *.obb ] +then + mv *.obb $UPLOAD_FILENAME.obb +fi diff --git a/tools/buildsteps/androidx86/package b/tools/buildsteps/androidx86/package index d95392bed3..f7fed28eec 100644 --- a/tools/buildsteps/androidx86/package +++ b/tools/buildsteps/androidx86/package @@ -2,9 +2,19 @@ WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )} XBMC_PLATFORM_DIR=android . $WORKSPACE/tools/buildsteps/defaultenv -cd $WORKSPACE;make apk +if [ "x$BUILD_OBB" == "xtrue" ] +then + cd $WORKSPACE;make apk-obb-unsigned +else + cd $WORKSPACE;make apk-unsigned +fi +$RUN_SIGNSTEP #rename for upload #e.x. xbmc-20130314-8c2fb31-Frodo-x86.apk -UPLOAD_FILENAME="xbmc-$(getBuildRevDateStr)-x86.apk" -mv xbmcapp-x86-*.apk $UPLOAD_FILENAME +UPLOAD_FILENAME="kodi-$(getBuildRevDateStr)-x86" +mv kodiapp-x86-*.apk $UPLOAD_FILENAME.apk +if [ -f *.obb ] +then + mv *.obb $UPLOAD_FILENAME.obb +fi diff --git a/tools/buildsteps/atv2/make-xbmc b/tools/buildsteps/atv2/make-xbmc index a3a8b9b0e0..5b8bb111f7 100755 --- a/tools/buildsteps/atv2/make-xbmc +++ b/tools/buildsteps/atv2/make-xbmc @@ -3,6 +3,6 @@ XBMC_PLATFORM_DIR=atv2 . $WORKSPACE/tools/buildsteps/defaultenv cd $WORKSPACE;make -j$BUILDTHREADS xcode_depends -cd $WORKSPACE;xcodebuild -project XBMC.xcodeproj -target XBMC-ATV2 -configuration $Configuration build \ +cd $WORKSPACE;xcodebuild -project Kodi.xcodeproj -target Kodi-ATV2 -configuration $Configuration build \ ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.2 \ SDKROOT=iphoneos$SDK_VERSION XBMC_DEPENDS_ROOT=$XBMC_DEPENDS_ROOT CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO diff --git a/tools/buildsteps/atv2/package b/tools/buildsteps/atv2/package index 2fa40de122..f4f4dbb59e 100755 --- a/tools/buildsteps/atv2/package +++ b/tools/buildsteps/atv2/package @@ -5,9 +5,9 @@ XBMC_PLATFORM_DIR=atv2 #ensure that dpkg tools are used from our toolchain export PATH=$XBMC_DEPENDS_ROOT/buildtools-native/bin/:$PATH -cd $WORKSPACE/tools/darwin/packaging/xbmc-atv2/;sh mkdeb-xbmc-atv2.sh $Configuration +cd $WORKSPACE/tools/darwin/packaging/atv2/;sh mkdeb-atv2.sh $Configuration #rename for upload -#e.x. xbmc-20130314-8c2fb31-Frodo-atv2.deb -UPLOAD_FILENAME="xbmc-$(getBuildRevDateStr)-atv2.deb" +#e.x. kodi-20130314-8c2fb31-Frodo-atv2.deb +UPLOAD_FILENAME="kodi-$(getBuildRevDateStr)-atv2.deb" mv *.deb $UPLOAD_FILENAME diff --git a/tools/buildsteps/ios/make-xbmc b/tools/buildsteps/ios/make-xbmc index 417a968c17..90003383bc 100755 --- a/tools/buildsteps/ios/make-xbmc +++ b/tools/buildsteps/ios/make-xbmc @@ -3,7 +3,7 @@ XBMC_PLATFORM_DIR=ios . $WORKSPACE/tools/buildsteps/defaultenv cd $WORKSPACE;make -j$BUILDTHREADS xcode_depends -cd $WORKSPACE;xcodebuild -project XBMC.xcodeproj -target XBMC-iOS -configuration $Configuration build \ +cd $WORKSPACE;xcodebuild -project Kodi.xcodeproj -target Kodi-iOS -configuration $Configuration build \ ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.2 \ SDKROOT=iphoneos$SDK_VERSION XBMC_DEPENDS_ROOT=$XBMC_DEPENDS_ROOT CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO diff --git a/tools/buildsteps/ios/package b/tools/buildsteps/ios/package index f6c9c2299f..310e68118c 100755 --- a/tools/buildsteps/ios/package +++ b/tools/buildsteps/ios/package @@ -5,9 +5,9 @@ XBMC_PLATFORM_DIR=ios #ensure that dpkg tools are used from our toolchain export PATH=$XBMC_DEPENDS_ROOT/buildtools-native/bin/:$PATH -cd $WORKSPACE/tools/darwin/packaging/xbmc-ios/;sh mkdeb-xbmc-ios.sh $Configuration +cd $WORKSPACE/tools/darwin/packaging/ios/;sh mkdeb-ios.sh $Configuration #rename for upload -#e.x. xbmc-20130314-8c2fb31-Frodo-ios.deb -UPLOAD_FILENAME="xbmc-$(getBuildRevDateStr)-ios.deb" +#e.x. kodi-20130314-8c2fb31-Frodo-ios.deb +UPLOAD_FILENAME="kodi-$(getBuildRevDateStr)-ios.deb" mv *.deb $UPLOAD_FILENAME diff --git a/tools/buildsteps/linux32/run-tests b/tools/buildsteps/linux32/run-tests index 429e094b92..088c21a101 100755 --- a/tools/buildsteps/linux32/run-tests +++ b/tools/buildsteps/linux32/run-tests @@ -3,7 +3,7 @@ XBMC_PLATFORM_DIR=linux32 . $WORKSPACE/tools/buildsteps/defaultenv cd $WORKSPACE;make -j$BUILDTHREADS testsuite -cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml +cd $WORKSPACE;./kodi-test --gtest_output=xml:gtestresults.xml awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml rm gtestresults.xml mv gtestresults-skipped.xml gtestresults.xml diff --git a/tools/buildsteps/linux64/run-tests b/tools/buildsteps/linux64/run-tests index 43469c3db5..6677939d5c 100755 --- a/tools/buildsteps/linux64/run-tests +++ b/tools/buildsteps/linux64/run-tests @@ -3,7 +3,7 @@ XBMC_PLATFORM_DIR=linux64 . $WORKSPACE/tools/buildsteps/defaultenv cd $WORKSPACE;make -j$BUILDTHREADS testsuite -cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml +cd $WORKSPACE;./kodi-test --gtest_output=xml:gtestresults.xml awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml rm gtestresults.xml mv gtestresults-skipped.xml gtestresults.xml diff --git a/tools/buildsteps/osx32/make-xbmc b/tools/buildsteps/osx32/make-xbmc index f93348ba7c..e3d79f6910 100755 --- a/tools/buildsteps/osx32/make-xbmc +++ b/tools/buildsteps/osx32/make-xbmc @@ -4,5 +4,5 @@ XBMC_PLATFORM_DIR=osx32 cd $WORKSPACE;make -j$BUILDTHREADS xcode_depends -cd $WORKSPACE;xcodebuild -sdk macosx$SDK_VERSION -project XBMC.xcodeproj -target XBMC.app ONLY_ACTIVE_ARCH=YES \ +cd $WORKSPACE;xcodebuild -sdk macosx$SDK_VERSION -project Kodi.xcodeproj -target Kodi.app ONLY_ACTIVE_ARCH=YES \ ARCHS=i386 VALID_ARCHS=i386 XBMC_DEPENDS_ROOT=$XBMC_DEPENDS_ROOT -configuration $Configuration build diff --git a/tools/buildsteps/osx32/package b/tools/buildsteps/osx32/package index ca9c655123..95a7a5b677 100755 --- a/tools/buildsteps/osx32/package +++ b/tools/buildsteps/osx32/package @@ -2,9 +2,9 @@ WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )} XBMC_PLATFORM_DIR=osx32 . $WORKSPACE/tools/buildsteps/defaultenv -cd $WORKSPACE/tools/darwin/packaging/xbmc-osx/; sh ./mkdmg-xbmc-osx.sh $Configuration +cd $WORKSPACE/tools/darwin/packaging/osx/; sh ./mkdmg-osx.sh $Configuration #rename for upload -#e.x. xbmc-20130314-8c2fb31-Frodo-i386.dmg -UPLOAD_FILENAME="xbmc-$(getBuildRevDateStr)-i386.dmg" +#e.x. kodi-20130314-8c2fb31-Frodo-i386.dmg +UPLOAD_FILENAME="kodi-$(getBuildRevDateStr)-i386.dmg" mv *.dmg $UPLOAD_FILENAME diff --git a/tools/buildsteps/osx32/run-tests b/tools/buildsteps/osx32/run-tests index a77fb8139c..ca1856272d 100755 --- a/tools/buildsteps/osx32/run-tests +++ b/tools/buildsteps/osx32/run-tests @@ -3,7 +3,7 @@ XBMC_PLATFORM_DIR=osx32 . $WORKSPACE/tools/buildsteps/defaultenv cd $WORKSPACE;make -j$BUILDTHREADS testsuite -cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml +cd $WORKSPACE;./kodi-test --gtest_output=xml:gtestresults.xml awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml rm gtestresults.xml mv gtestresults-skipped.xml gtestresults.xml diff --git a/tools/buildsteps/osx64/make-xbmc b/tools/buildsteps/osx64/make-xbmc index 421613e5e3..61022f233e 100755 --- a/tools/buildsteps/osx64/make-xbmc +++ b/tools/buildsteps/osx64/make-xbmc @@ -4,5 +4,5 @@ XBMC_PLATFORM_DIR=osx64 cd $WORKSPACE;make -j$BUILDTHREADS xcode_depends -cd $WORKSPACE;xcodebuild -sdk macosx$SDK_VERSION -project XBMC.xcodeproj -target XBMC.app ONLY_ACTIVE_ARCH=YES \ +cd $WORKSPACE;xcodebuild -sdk macosx$SDK_VERSION -project Kodi.xcodeproj -target Kodi.app ONLY_ACTIVE_ARCH=YES \ ARCHS=x86_64 VALID_ARCHS=x86_64 XBMC_DEPENDS_ROOT=$XBMC_DEPENDS_ROOT -configuration $Configuration build diff --git a/tools/buildsteps/osx64/package b/tools/buildsteps/osx64/package index 6ce8da47e6..cffd7943b3 100755 --- a/tools/buildsteps/osx64/package +++ b/tools/buildsteps/osx64/package @@ -2,9 +2,9 @@ WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )} XBMC_PLATFORM_DIR=osx64 . $WORKSPACE/tools/buildsteps/defaultenv -cd $WORKSPACE/tools/darwin/packaging/xbmc-osx/; sh ./mkdmg-xbmc-osx.sh $Configuration +cd $WORKSPACE/tools/darwin/packaging/osx/; sh ./mkdmg-osx.sh $Configuration #rename for upload -#e.x. xbmc-20130314-8c2fb31-Frodo-x86_64.dmg -UPLOAD_FILENAME="xbmc-$(getBuildRevDateStr)-x86_64.dmg" +#e.x. kodi-20130314-8c2fb31-Frodo-x86_64.dmg +UPLOAD_FILENAME="kodi-$(getBuildRevDateStr)-x86_64.dmg" mv *.dmg $UPLOAD_FILENAME diff --git a/tools/buildsteps/osx64/run-tests b/tools/buildsteps/osx64/run-tests index b3113e356f..5d0712fb9f 100755 --- a/tools/buildsteps/osx64/run-tests +++ b/tools/buildsteps/osx64/run-tests @@ -3,7 +3,7 @@ XBMC_PLATFORM_DIR=osx64 . $WORKSPACE/tools/buildsteps/defaultenv cd $WORKSPACE;make -j$BUILDTHREADS testsuite -cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml +cd $WORKSPACE;./kodi-test --gtest_output=xml:gtestresults.xml awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml rm gtestresults.xml mv gtestresults-skipped.xml gtestresults.xml diff --git a/tools/buildsteps/win32/make-addon-depends.bat b/tools/buildsteps/win32/make-addon-depends.bat index d649445a37..fd4ac3ce4a 100644 --- a/tools/buildsteps/win32/make-addon-depends.bat +++ b/tools/buildsteps/win32/make-addon-depends.bat @@ -66,8 +66,8 @@ IF "%dependency%" NEQ "" ( rem execute cmake to generate makefiles processable by nmake cmake "%ADDON_DEPENDS_PATH%" -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Release ^ - -DCMAKE_USER_MAKE_RULES_OVERRIDE="%SCRIPTS_PATH%/xbmc-c-flag-overrides.cmake" ^ - -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX="%SCRIPTS_PATH%/xbmc-cxx-flag-overrides.cmake" ^ ^ + -DCMAKE_USER_MAKE_RULES_OVERRIDE="%SCRIPTS_PATH%/c-flag-overrides.cmake" ^ + -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX="%SCRIPTS_PATH%/cxx-flag-overrides.cmake" ^ ^ -DCMAKE_INSTALL_PREFIX=%ADDONS_OUTPUT_PATH% ^ -DARCH_DEFINES="-DTARGET_WINDOWS -DNOMINMAX -D_CRT_SECURE_NO_WARNINGS -D_USE_32BIT_TIME_T -D_WINSOCKAPI_" ^ -DDEPENDS_TO_BUILD="%DEPENDS_TO_BUILD%" diff --git a/tools/buildsteps/win32/make-addons.bat b/tools/buildsteps/win32/make-addons.bat index c10b340396..48ff14073b 100644 --- a/tools/buildsteps/win32/make-addons.bat +++ b/tools/buildsteps/win32/make-addons.bat @@ -93,10 +93,10 @@ IF "%addon%" NEQ "" ( rem execute cmake to generate makefiles processable by nmake cmake "%ADDONS_PATH%" -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Release ^ - -DCMAKE_USER_MAKE_RULES_OVERRIDE="%SCRIPTS_PATH%/xbmc-c-flag-overrides.cmake" ^ - -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX="%SCRIPTS_PATH%/xbmc-cxx-flag-overrides.cmake" ^ + -DCMAKE_USER_MAKE_RULES_OVERRIDE="%SCRIPTS_PATH%/c-flag-overrides.cmake" ^ + -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX="%SCRIPTS_PATH%/cxx-flag-overrides.cmake" ^ -DCMAKE_INSTALL_PREFIX=%ADDONS_INSTALL_PATH% ^ - -DXBMCROOT=%WORKDIR% ^ + -DAPP_ROOT=%WORKDIR% ^ -DCMAKE_PREFIX_PATH=%ADDON_DEPENDS_PATH% ^ -DPACKAGE_ZIP=1 ^ -DARCH_DEFINES="-DTARGET_WINDOWS -DNOMINMAX -D_CRT_SECURE_NO_WARNINGS -D_USE_32BIT_TIME_T -D_WINSOCKAPI_" ^ diff --git a/tools/darwin/Configurations/App-iOS.xcconfig b/tools/darwin/Configurations/App-iOS.xcconfig index b2876549e7..8a2cc41f50 100644 --- a/tools/darwin/Configurations/App-iOS.xcconfig +++ b/tools/darwin/Configurations/App-iOS.xcconfig @@ -20,7 +20,7 @@ #include "App.xcconfig" -PRODUCT_NAME = XBMC +PRODUCT_NAME = $(APP_NAME) //build against latest SDKROOT = iphoneos IPHONEOS_DEPLOYMENT_TARGET = 4.2 diff --git a/tools/darwin/Configurations/Common.xcconfig.in b/tools/darwin/Configurations/Common.xcconfig.in index 626f8631ec..f682c6ce3f 100644 --- a/tools/darwin/Configurations/Common.xcconfig.in +++ b/tools/darwin/Configurations/Common.xcconfig.in @@ -18,6 +18,7 @@ // // +APP_NAME=@APP_NAME@ XBMC_DEPENDS_ROOT = @DEPENDS_ROOT_FOR_XCODE@ XBMC_GCC_PREPROCESSOR_DEFINITIONS_COMMON = TARGET_POSIX TARGET_DARWIN _LINUX _REENTRANT _FILE_DEFINED _FILE_OFFSET_BITS=64 _LARGEFILE64_SOURCE __STDC_CONSTANT_MACROS HAVE_CONFIG_H HAS_SPC_CODEC NPT_CONFIG_ENABLE_LOGGINGPLT_HTTP_DEFAULT_USER_AGENT="\"UPnP/1.0 DLNADOC/1.50 XBMC\"" PLT_HTTP_DEFAULT_SERVER="\"UPnP/1.0 DLNADOC/1.50 XBMC\"" diff --git a/tools/darwin/Support/Codesign.command b/tools/darwin/Support/Codesign.command index 8df9860c67..2334741caf 100755 --- a/tools/darwin/Support/Codesign.command +++ b/tools/darwin/Support/Codesign.command @@ -1,7 +1,7 @@ #!/bin/bash #this is the list of binaries we have to sign for beeing able to run un-jailbroken -LIST_BINARY_EXTENSIONS="dylib so 0 vis" +LIST_BINARY_EXTENSIONS="dylib so 0 vis pvr" export CODESIGN_ALLOCATE=`xcodebuild -find codesign_allocate` @@ -17,7 +17,7 @@ if [ "${PLATFORM_NAME}" == "iphoneos" ]; then if [ -f "/Users/Shared/buildslave/keychain_unlock.sh" ]; then /Users/Shared/buildslave/keychain_unlock.sh fi - ${GEN_ENTITLEMENTS} "org.xbmc.xbmc-ios" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent"; + ${GEN_ENTITLEMENTS} "org.xbmc.kodi-ios" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent"; codesign -v -f -s "iPhone Developer" --entitlements "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/" #if user has set a code_sign_identity different from iPhone Developer we do a real codesign (for deployment on non-jailbroken devices) @@ -25,7 +25,7 @@ if [ "${PLATFORM_NAME}" == "iphoneos" ]; then echo Doing a full bundle sign using genuine identity "${CODE_SIGN_IDENTITY}" for binext in $LIST_BINARY_EXTENSIONS do - codesign -fvvv -s "${CODE_SIGN_IDENTITY}" -i org.xbmc.xbmc-ios `find ${CODESIGNING_FOLDER_PATH} -name "*.$binext"` ${CODESIGNING_FOLDER_PATH} + codesign -fvvv -s "${CODE_SIGN_IDENTITY}" -i org.xbmc.kodi-ios `find ${CODESIGNING_FOLDER_PATH} -name "*.$binext" -type f` ${CODESIGNING_FOLDER_PATH} done echo In case your app crashes with SIG_SIGN check the variable LIST_BINARY_EXTENSIONS in tools/darwin/Support/Codesign.command fi diff --git a/tools/darwin/Support/CopyRootFiles-atv2.command b/tools/darwin/Support/CopyRootFiles-atv2.command index 4f45dd76ee..3ebb6ab668 100755 --- a/tools/darwin/Support/CopyRootFiles-atv2.command +++ b/tools/darwin/Support/CopyRootFiles-atv2.command @@ -6,8 +6,8 @@ if [ "$ACTION" = build ] ; then # for external testing TARGET_NAME=$PRODUCT_NAME.$WRAPPER_EXTENSION -#SRCROOT=/Users/Shared/xbmc_svn/XBMC -#TARGET_BUILD_DIR=/Users/Shared/xbmc_svn/XBMC/build/Debug +#SRCROOT=/Users/Shared/xbmc_svn/$APP_NAME +#TARGET_BUILD_DIR=/Users/Shared/xbmc_svn/$APP_NAME/build/Debug # rsync command with exclusions for items we don't want in the app package SYNC="rsync -aq --exclude .git* --exclude .DS_Store* --exclude *.dll --exclude *.DLL --exclude *linux.* --exclude *x86-osx.* --exclude *.zlib --exclude *.a --exclude *.pyd --exclude *x86-osx.so --exclude *powerpc-osx.so" @@ -19,38 +19,38 @@ SKINSYNC="rsync -aq --exclude .git* --exclude CVS* --exclude .svn* --exclude .cv # rsync command for including everything but the skins ADDONSYNC="rsync -aq --exclude .git* --exclude CVS* --exclude .svn* --exclude .cvsignore* --exclude .cvspass* --exclude .DS_Store* --exclude addons/skin.confluence --exclude addons/skin.re-touched --exclude screensaver.rsxs* --exclude visualization.*" -# binary name is XBMC but we build XBMC.bin so to get a clean binary each time -mv $TARGET_BUILD_DIR/$TARGET_NAME/XBMC.bin $TARGET_BUILD_DIR/$TARGET_NAME/XBMC - -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/language" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/media" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/sounds" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/system" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/userdata" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/media" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/tools/darwin/runtime" - -${SYNC} "$SRCROOT/LICENSE.GPL" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/" -${SYNC} "$SRCROOT/xbmc/osx/Credits.html" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/" -${ADDONSYNC} "$SRCROOT/addons" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/addons/visualization.glspectrum" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -${SYNC} "$SRCROOT/addons/visualization.waveform" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -${SYNC} "$SRCROOT/language" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/media" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" +# binary name is Kodi but we build Kodi.bin so to get a clean binary each time +mv $TARGET_BUILD_DIR/$TARGET_NAME/$APP_NAME.bin $TARGET_BUILD_DIR/$TARGET_NAME/$APP_NAME + +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/language" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/media" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/sounds" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/system" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/userdata" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/media" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/tools/darwin/runtime" + +${SYNC} "$SRCROOT/LICENSE.GPL" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/" +${SYNC} "$SRCROOT/xbmc/osx/Credits.html" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/" +${ADDONSYNC} "$SRCROOT/addons" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/addons/visualization.glspectrum" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +${SYNC} "$SRCROOT/addons/visualization.waveform" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +${SYNC} "$SRCROOT/language" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/media" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" SYNCSKIN_A=${SKINSYNC} if [ -f "$SRCROOT/addons/skin.confluence/media/Textures.xbt" ]; then SYNCSKIN_A="${SKINSYNC} --exclude *.png --exclude *.jpg" fi -${SYNCSKIN_A} "$SRCROOT/addons/skin.confluence" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -${SYNC} "$SRCROOT/addons/skin.confluence/backgrounds" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons/skin.confluence" -${SYNC} "$SRCROOT/addons/skin.confluence/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons/skin.confluence" +${SYNCSKIN_A} "$SRCROOT/addons/skin.confluence" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +${SYNC} "$SRCROOT/addons/skin.confluence/backgrounds" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.confluence" +${SYNC} "$SRCROOT/addons/skin.confluence/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.confluence" -${SYNC} "$SRCROOT/sounds" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/system" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/userdata" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" +${SYNC} "$SRCROOT/sounds" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/system" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/userdata" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" fi diff --git a/tools/darwin/Support/CopyRootFiles-ios.command b/tools/darwin/Support/CopyRootFiles-ios.command index 9249aa025a..81bccd6ceb 100755 --- a/tools/darwin/Support/CopyRootFiles-ios.command +++ b/tools/darwin/Support/CopyRootFiles-ios.command @@ -6,8 +6,8 @@ if [ "$ACTION" = build ] ; then # for external testing TARGET_NAME=$PRODUCT_NAME.$WRAPPER_EXTENSION -#SRCROOT=/Users/Shared/xbmc_svn/XBMC -#TARGET_BUILD_DIR=/Users/Shared/xbmc_svn/XBMC/build/Debug +#SRCROOT=/Users/Shared/xbmc_svn/$APP_NAME +#TARGET_BUILD_DIR=/Users/Shared/xbmc_svn/$APP_NAME/build/Debug # rsync command with exclusions for items we don't want in the app package SYNC="rsync -aq --exclude .git* --exclude .DS_Store* --exclude *.dll --exclude *.DLL --exclude *linux.* --exclude *x86-osx.so --exclude *.zlib --exclude *.a" @@ -19,26 +19,26 @@ SKINSYNC="rsync -aq --exclude .git* --exclude CVS* --exclude .svn* --exclude .cv # rsync command for including everything but the skins ADDONSYNC="rsync -aq --exclude .git* --exclude CVS* --exclude .svn* --exclude .cvsignore* --exclude .cvspass* --exclude .DS_Store* --exclude addons/skin.confluence --exclude addons/skin.re-touched --exclude screensaver.rsxs* --exclude visualization.*" -# binary name is XBMC but we build XBMC.bin so to get a clean binary each time -mv $TARGET_BUILD_DIR/$TARGET_NAME/XBMC.bin $TARGET_BUILD_DIR/$TARGET_NAME/XBMC +# binary name is Kodi but we build Kodi.bin so to get a clean binary each time +mv $TARGET_BUILD_DIR/$TARGET_NAME/$APP_NAME.bin $TARGET_BUILD_DIR/$TARGET_NAME/$APP_NAME -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/language" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/media" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/sounds" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/system" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/userdata" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/media" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/tools/darwin/runtime" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/language" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/media" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/sounds" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/system" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/userdata" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/media" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/tools/darwin/runtime" -${SYNC} "$SRCROOT/LICENSE.GPL" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/" -${SYNC} "$SRCROOT/xbmc/osx/Credits.html" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/" -${ADDONSYNC} "$SRCROOT/addons" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/addons/visualization.glspectrum" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -${SYNC} "$SRCROOT/addons/visualization.waveform" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -${SYNC} "$SRCROOT/language" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/media" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" +${SYNC} "$SRCROOT/LICENSE.GPL" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/" +${SYNC} "$SRCROOT/xbmc/osx/Credits.html" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/" +${ADDONSYNC} "$SRCROOT/addons" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/addons/visualization.glspectrum" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +${SYNC} "$SRCROOT/addons/visualization.waveform" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +${SYNC} "$SRCROOT/language" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/media" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" # sync touch skin if it exists if [ -f "$SRCROOT/addons/skin.re-touched/addon.xml" ]; then @@ -46,9 +46,9 @@ SYNCSKIN_A=${SKINSYNC} if [ -f "$SRCROOT/addons/skin.re-touched/media/Textures.xbt" ]; then SYNCSKIN_A="${SKINSYNC} --exclude *.png --exclude *.jpg" fi -${SYNCSKIN_A} "$SRCROOT/addons/skin.re-touched" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -${SYNC} "$SRCROOT/addons/skin.re-touched/background" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons/skin.re-touched" -${SYNC} "$SRCROOT/addons/skin.re-touched/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons/skin.re-touched" +${SYNCSKIN_A} "$SRCROOT/addons/skin.re-touched" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +${SYNC} "$SRCROOT/addons/skin.re-touched/background" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.re-touched" +${SYNC} "$SRCROOT/addons/skin.re-touched/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.re-touched" fi # sync skin.confluence @@ -56,12 +56,12 @@ SYNCSKIN_B=${SKINSYNC} if [ -f "$SRCROOT/addons/skin.confluence/media/Textures.xbt" ]; then SYNCSKIN_B="${SKINSYNC} --exclude *.png --exclude *.jpg" fi -${SYNCSKIN_B} "$SRCROOT/addons/skin.confluence" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons" -${SYNC} "$SRCROOT/addons/skin.confluence/backgrounds" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons/skin.confluence" -${SYNC} "$SRCROOT/addons/skin.confluence/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome/addons/skin.confluence" +${SYNCSKIN_B} "$SRCROOT/addons/skin.confluence" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons" +${SYNC} "$SRCROOT/addons/skin.confluence/backgrounds" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.confluence" +${SYNC} "$SRCROOT/addons/skin.confluence/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.confluence" -${SYNC} "$SRCROOT/sounds" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/system" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" -${SYNC} "$SRCROOT/userdata" "$TARGET_BUILD_DIR/$TARGET_NAME/XBMCData/XBMCHome" +${SYNC} "$SRCROOT/sounds" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/system" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" +${SYNC} "$SRCROOT/userdata" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome" fi diff --git a/tools/darwin/Support/CopyRootFiles-osx.command b/tools/darwin/Support/CopyRootFiles-osx.command index 8bc01f2cd1..8c10364cbe 100755 --- a/tools/darwin/Support/CopyRootFiles-osx.command +++ b/tools/darwin/Support/CopyRootFiles-osx.command @@ -5,9 +5,9 @@ echo "copy root files" if [ "$ACTION" = build ] ; then # for external testing -#TARGET_NAME=XBMC.app -#SRCROOT=/Users/Shared/xbmc_svn/XBMC -#TARGET_BUILD_DIR=/Users/Shared/xbmc_svn/XBMC/build/Debug +#TARGET_NAME=$APP_NAME.app +#SRCROOT=/Users/Shared/xbmc_svn/$APP_NAME +#TARGET_BUILD_DIR=/Users/Shared/xbmc_svn/$APP_NAME/build/Debug # rsync command with exclusions for items we don't want in the app package SYNC="rsync -aq --exclude .git* --exclude .DS_Store* --exclude *.dll --exclude *.DLL --exclude *linux.* --exclude *arm-osx.* --exclude *.zlib --exclude *.a" @@ -19,38 +19,38 @@ SYNCSKIN="rsync -aq --exclude .git* --exclude CVS* --exclude .svn* --exclude .cv # rsync command for including everything but the skins ADDONSYNC="rsync -aq --exclude .git* --exclude .DS_Store* --exclude addons/skin.confluence --exclude addons/skin.re-touched" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/addons" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/language" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/media" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/sounds" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/system" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/userdata" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/media" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/tools/darwin/runtime" -mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/extras/user" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/language" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/media" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/sounds" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/system" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/userdata" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/media" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/tools/darwin/runtime" +mkdir -p "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/extras/user" ${SYNC} "$SRCROOT/LICENSE.GPL" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/" ${SYNC} "$SRCROOT/xbmc/osx/Credits.html" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/" -${SYNC} "$SRCROOT/tools/darwin/runtime" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/tools/darwin" -${ADDONSYNC} "$SRCROOT/addons" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" -${SYNC} "$SRCROOT/language" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" -${SYNC} "$SRCROOT/media" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" -${SYNCSKIN} "$SRCROOT/addons/skin.confluence" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/addons" -${SYNC} "$SRCROOT/addons/skin.confluence/backgrounds" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/addons/skin.confluence" -${SYNC} "$SRCROOT/addons/skin.confluence/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/addons/skin.confluence" -${SYNC} "$SRCROOT/sounds" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" -${SYNC} "$SRCROOT/system" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" -${SYNC} "$SRCROOT/userdata" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" +${SYNC} "$SRCROOT/tools/darwin/runtime" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/tools/darwin" +${ADDONSYNC} "$SRCROOT/addons" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" +${SYNC} "$SRCROOT/language" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" +${SYNC} "$SRCROOT/media" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" +${SYNCSKIN} "$SRCROOT/addons/skin.confluence" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons" +${SYNC} "$SRCROOT/addons/skin.confluence/backgrounds" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons/skin.confluence" +${SYNC} "$SRCROOT/addons/skin.confluence/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons/skin.confluence" +${SYNC} "$SRCROOT/sounds" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" +${SYNC} "$SRCROOT/system" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" +${SYNC} "$SRCROOT/userdata" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" # copy extra packages if applicable if [ -d "$SRCROOT/extras/system" ]; then - ${SYNC} "$SRCROOT/extras/system/" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC" + ${SYNC} "$SRCROOT/extras/system/" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME" fi # copy extra user packages if applicable if [ -d "$SRCROOT/extras/user" ]; then - ${SYNC} "$SRCROOT/extras/user/" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/XBMC/extras/user" + ${SYNC} "$SRCROOT/extras/user/" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/extras/user" fi @@ -59,6 +59,6 @@ fi touch "$TARGET_BUILD_DIR/$TARGET_NAME" # not sure we want to do this with out major testing, many scripts cannot handle the spaces in the app name -#mv "$TARGET_BUILD_DIR/$TARGET_NAME" "$TARGET_BUILD_DIR/XBMC Media Center.app" +#mv "$TARGET_BUILD_DIR/$TARGET_NAME" "$TARGET_BUILD_DIR/$APP_NAME Media Center.app" fi diff --git a/tools/darwin/Support/copyframeworks-atv2.command b/tools/darwin/Support/copyframeworks-atv2.command index c604682907..21cdd55ff7 100755 --- a/tools/darwin/Support/copyframeworks-atv2.command +++ b/tools/darwin/Support/copyframeworks-atv2.command @@ -53,18 +53,18 @@ EXTERNAL_LIBS=$XBMC_DEPENDS TARGET_NAME=$PRODUCT_NAME.$WRAPPER_EXTENSION TARGET_CONTENTS=$TARGET_BUILD_DIR/$TARGET_NAME -TARGET_BINARY=$TARGET_CONTENTS/XBMC +TARGET_BINARY=$TARGET_CONTENTS/$APP_NAME TARGET_FRAMEWORKS=$TARGET_CONTENTS/Frameworks -DYLIB_NAMEPATH=@executable_path/Appliances/XBMC.frappliance/Frameworks -XBMC_HOME=$TARGET_CONTENTS/XBMCData/XBMCHome +DYLIB_NAMEPATH=@executable_path/Appliances/$APP_NAME.frappliance/Frameworks +XBMC_HOME=$TARGET_CONTENTS/AppData/AppHome mkdir -p "$TARGET_CONTENTS" -mkdir -p "$TARGET_CONTENTS/XBMCData/XBMCHome" +mkdir -p "$TARGET_CONTENTS/AppData/AppHome" # start clean so we don't keep old dylibs rm -rf "$TARGET_CONTENTS/Frameworks" mkdir -p "$TARGET_CONTENTS/Frameworks" -echo "Package $TARGET_BUILD_DIR/XBMC" +echo "Package $TARGET_BUILD_DIR/$APP_NAME" # Copy all of XBMC's dylib dependencies and rename their locations to inside the Framework echo "Checking $TARGET_BINARY dylib dependencies" diff --git a/tools/darwin/Support/copyframeworks-ios.command b/tools/darwin/Support/copyframeworks-ios.command index 025f15dad4..328258bd08 100755 --- a/tools/darwin/Support/copyframeworks-ios.command +++ b/tools/darwin/Support/copyframeworks-ios.command @@ -53,18 +53,18 @@ EXTERNAL_LIBS=$XBMC_DEPENDS TARGET_NAME=$PRODUCT_NAME.$WRAPPER_EXTENSION TARGET_CONTENTS=$TARGET_BUILD_DIR/$TARGET_NAME -TARGET_BINARY=$TARGET_CONTENTS/XBMC +TARGET_BINARY=$TARGET_CONTENTS/$APP_NAME TARGET_FRAMEWORKS=$TARGET_CONTENTS/Frameworks DYLIB_NAMEPATH=@executable_path/Frameworks -XBMC_HOME=$TARGET_CONTENTS/XBMCData/XBMCHome +XBMC_HOME=$TARGET_CONTENTS/AppData/AppHome mkdir -p "$TARGET_CONTENTS" -mkdir -p "$TARGET_CONTENTS/XBMCData/XBMCHome" +mkdir -p "$TARGET_CONTENTS/AppData/AppHome" # start clean so we don't keep old dylibs rm -rf "$TARGET_CONTENTS/Frameworks" mkdir -p "$TARGET_CONTENTS/Frameworks" -echo "Package $TARGET_BUILD_DIR/XBMC" +echo "Package $TARGET_BUILD_DIR/$APP_NAME" # Copy all of XBMC's dylib dependencies and rename their locations to inside the Framework echo "Checking $TARGET_BINARY dylib dependencies" diff --git a/tools/darwin/Support/copyframeworks-osx.command b/tools/darwin/Support/copyframeworks-osx.command index 234b116422..df041c1ab1 100755 --- a/tools/darwin/Support/copyframeworks-osx.command +++ b/tools/darwin/Support/copyframeworks-osx.command @@ -53,10 +53,10 @@ EXTERNAL_LIBS=$XBMC_DEPENDS TARGET_NAME=$PRODUCT_NAME TARGET_CONTENTS=$TARGET_BUILD_DIR/$TARGET_NAME/Contents -TARGET_BINARY=$TARGET_CONTENTS/MacOS/XBMC +TARGET_BINARY=$TARGET_CONTENTS/MacOS/$APP_NAME TARGET_FRAMEWORKS=$TARGET_CONTENTS/Libraries DYLIB_NAMEPATH=@executable_path/../Libraries -XBMC_HOME=$TARGET_CONTENTS/Resources/XBMC +XBMC_HOME=$TARGET_CONTENTS/Resources/$APP_NAME mkdir -p "$TARGET_CONTENTS/MacOS" mkdir -p "$TARGET_CONTENTS/Resources" @@ -64,11 +64,11 @@ mkdir -p "$TARGET_CONTENTS/Resources" rm -rf "$TARGET_CONTENTS/Libraries" mkdir -p "$TARGET_CONTENTS/Libraries" -echo "Package $TARGET_BUILD_DIR/XBMC" -cp -f "$TARGET_BUILD_DIR/XBMC" "$TARGET_BINARY" +echo "Package $TARGET_BUILD_DIR/$APP_NAME" +cp -f "$TARGET_BUILD_DIR/$APP_NAME" "$TARGET_BINARY" echo "Creating icon" -iconutil -c icns --output "$TARGET_CONTENTS/Resources/xbmc.icns" "$SRCROOT/tools/darwin/packaging/media/osx/icon.iconset" +iconutil -c icns --output "$TARGET_CONTENTS/Resources/kodi.icns" "$SRCROOT/tools/darwin/packaging/media/osx/icon.iconset" cp -f "$SRCROOT/xbmc/osx/Info.plist" "$TARGET_CONTENTS/" diff --git a/tools/darwin/Support/updateversioninfo-osx.command b/tools/darwin/Support/updateversioninfo-osx.command index 2cd18cefc0..0d5cdf98e1 100755 --- a/tools/darwin/Support/updateversioninfo-osx.command +++ b/tools/darwin/Support/updateversioninfo-osx.command @@ -2,7 +2,7 @@ # Update version in Info.plist with Git revision GIT_REVISION="Unknown" -BUNDLE_NAME="XBMC" +BUNDLE_NAME="$APP_NAME" GIT_REVISION="Git-"$(cat git_revision.h | sed -n 's/\(.*\)\"\(.*\)\"\(.*\)/\2/p') perl -p -i -e "s/r####/$GIT_REVISION/" "$TARGET_BUILD_DIR/$BUNDLE_NAME.app/Contents/Info.plist" diff --git a/tools/darwin/packaging/xbmc-atv2/mkdeb-xbmc-atv2.sh.in b/tools/darwin/packaging/atv2/mkdeb-atv2.sh.in index 10a15b4c36..db637ebcbe 100644 --- a/tools/darwin/packaging/xbmc-atv2/mkdeb-xbmc-atv2.sh.in +++ b/tools/darwin/packaging/atv2/mkdeb-atv2.sh.in @@ -1,21 +1,21 @@ #!/bin/sh -# usage: ./mkdeb-xbmc-atv2.sh release/debug (case insensitive) -# Allows us to run mkdeb-xbmc-atv2.sh from anywhere in the three, rather than the tools/darwin/packaging/xbmc-atv2 folder only +# usage: ./mkdeb-atv2.sh release/debug (case insensitive) +# Allows us to run mkdeb-atv2.sh from anywhere in the three, rather than the tools/darwin/packaging/atv2 folder only XBMC_DEPENDS_ROOT=@DEPENDS_ROOT_FOR_XCODE@ SWITCH=`echo $1 | tr [A-Z] [a-z]` DIRNAME=`dirname $0` DSYM_TARGET_DIR=${XBMC_DEPENDS_ROOT}/dSyms -DSYM_FILENAME=XBMC.frappliance.dSYM +DSYM_FILENAME=@APP_NAME@.frappliance.dSYM if [ ${SWITCH:-""} = "debug" ]; then echo "Packaging Debug target for ATV2" - XBMC="$DIRNAME/../../../../build/Debug-iphoneos/XBMC.frappliance" + APP="$DIRNAME/../../../../build/Debug-iphoneos/@APP_NAME@.frappliance" DSYM="$DIRNAME/../../../../build/Debug-iphoneos/$DSYM_FILENAME" elif [ ${SWITCH:-""} = "release" ]; then echo "Packaging Release target for ATV2" - XBMC="$DIRNAME/../../../../build/Release-iphoneos/XBMC.frappliance" + APP="$DIRNAME/../../../../build/Release-iphoneos/@APP_NAME@.frappliance" DSYM="$DIRNAME/../../../../build/Release-iphoneos/$DSYM_FILENAME" - echo $XBMC + echo $APP else echo "You need to specify the build target" exit 1 @@ -28,8 +28,8 @@ if [ -d $DSYM ]; then fi fi -if [ ! -d $XBMC ]; then - echo "XBMC.frappliance not found! are you sure you built $1 target?" +if [ ! -d $APP ]; then + echo "@APP_NAME@.frappliance not found! are you sure you built $1 target?" exit 1 fi if [ -f "$XBMC_DEPENDS_ROOT/buildtools-native/bin/fakeroot" ]; then @@ -45,12 +45,12 @@ if [ -f "$XBMC_DEPENDS_ROOT/buildtools-native/bin/dpkg-deb" ]; then export PATH=${bin_path}:${PATH} fi -PACKAGE=org.xbmc.xbmc-atv2 +PACKAGE=org.xbmc.@APP_NAME_LC@-atv2 VERSION=@APP_VERSION_MAJOR@.@APP_VERSION_MINOR@ REVISION=0~@APP_VERSION_TAG_LC@ ARCHIVE=${PACKAGE}_${VERSION}-${REVISION}_iphoneos-arm.deb -XBMCSIZE="$(du -s -k ${XBMC} | awk '{print $1}')" +SIZE="$(du -s -k ${APP} | awk '{print $1}')" echo Creating $PACKAGE package version $VERSION revision $REVISION ${SUDO} rm -rf $DIRNAME/$PACKAGE @@ -60,40 +60,40 @@ ${SUDO} rm -rf $DIRNAME/$ARCHIVE mkdir -p $DIRNAME/$PACKAGE/DEBIAN echo "Package: $PACKAGE" > $DIRNAME/$PACKAGE/DEBIAN/control echo "Priority: Extra" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Name: XBMC-ATV2" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Depends: curl, org.awkwardtv.whitelist, com.nito.updatebegone, org.xbmc.xbmc-seatbeltunlock" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Name: @APP_NAME@-ATV2" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Depends: curl, org.awkwardtv.whitelist, com.nito.updatebegone, org.xbmc.@APP_NAME_LC@-seatbeltunlock" >> $DIRNAME/$PACKAGE/DEBIAN/control echo "Version: $VERSION-$REVISION" >> $DIRNAME/$PACKAGE/DEBIAN/control echo "Architecture: iphoneos-arm" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Installed-Size: $XBMCSIZE" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Description: XBMC Multimedia Center for AppleTV 2" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Homepage: http://xbmc.org/" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Maintainer: Scott Davilla, Edgar Hucek" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Author: TeamXBMC" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Installed-Size: $SIZE" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Description: @APP_NAME@ Entertainment Center for AppleTV 2" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Homepage: http://kodi.tv/" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Maintainer: Memphiz" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Author: Team-@APP_NAME@" >> $DIRNAME/$PACKAGE/DEBIAN/control echo "Section: Multimedia" >> $DIRNAME/$PACKAGE/DEBIAN/control # prerm: called on remove and upgrade - get rid of existing bits. echo "#!/bin/sh" > $DIRNAME/$PACKAGE/DEBIAN/prerm -echo "find /Applications/XBMC.frappliance -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm +echo "find /Applications/@APP_NAME@.frappliance -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm echo "if [ \"\`uname -r\`\" = \"10.3.1\" ]; then" >> $DIRNAME/$PACKAGE/DEBIAN/prerm -echo " find /Applications/Lowtide.app/Appliances/XBMC.frappliance -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm +echo " find /Applications/Lowtide.app/Appliances/@APP_NAME@.frappliance -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm echo "else" >> $DIRNAME/$PACKAGE/DEBIAN/prerm -echo " find /Applications/AppleTV.app/Appliances/XBMC.frappliance -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm +echo " find /Applications/AppleTV.app/Appliances/@APP_NAME@.frappliance -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm echo "fi" >> $DIRNAME/$PACKAGE/DEBIAN/prerm chmod +x $DIRNAME/$PACKAGE/DEBIAN/prerm -# postinst: symlink XBMC.frappliance into correct location and reload Lowtide/AppleTV. +# postinst: symlink @APP_NAME@.frappliance into correct location and reload Lowtide/AppleTV. echo "#!/bin/sh" > $DIRNAME/$PACKAGE/DEBIAN/postinst -echo "chown -R mobile:mobile /Applications/XBMC.frappliance" >> $DIRNAME/$PACKAGE/DEBIAN/postinst -echo "cp /Applications/XBMC.frappliance/AppIcon.png /Applications/AppleTV.app/com.apple.frontrow.appliance.xbmc\@720p.png" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +echo "chown -R mobile:mobile /Applications/@APP_NAME@.frappliance" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +echo "cp /Applications/@APP_NAME@.frappliance/AppIcon.png /Applications/AppleTV.app/com.apple.frontrow.appliance.@APP_NAME_LC@\@720p.png" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo "mkdir -p /private/var/mobile/Library/Caches/AppleTV/MainMenu/" >> $DIRNAME/$PACKAGE/DEBIAN/postinst -echo "cp /Applications/XBMC.frappliance/AppIcon.png /private/var/mobile/Library/Caches/AppleTV/MainMenu/com.apple.frontrow.appliance.xbmc@720.png" >> $DIRNAME/$PACKAGE/DEBIAN/postinst -echo "cp /Applications/XBMC.frappliance/AppIcon.png /Applications/XBMC.frappliance/TopRowIcon.png" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +echo "cp /Applications/@APP_NAME@.frappliance/AppIcon.png /private/var/mobile/Library/Caches/AppleTV/MainMenu/com.apple.frontrow.appliance.@APP_NAME_LC@@720.png" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +echo "cp /Applications/@APP_NAME@.frappliance/AppIcon.png /Applications/@APP_NAME@.frappliance/TopRowIcon.png" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo "if [ \"\`uname -r\`\" = \"10.3.1\" ]; then" >> $DIRNAME/$PACKAGE/DEBIAN/postinst -echo " ln -sf /Applications/XBMC.frappliance /Applications/Lowtide.app/Appliances/XBMC.frappliance" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +echo " ln -sf /Applications/@APP_NAME@.frappliance /Applications/Lowtide.app/Appliances/@APP_NAME@.frappliance" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo " killall Lowtide" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo "else" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo " mkdir -p /Applications/AppleTV.app/Appliances" >> $DIRNAME/$PACKAGE/DEBIAN/postinst -echo " ln -sf /Applications/XBMC.frappliance /Applications/AppleTV.app/Appliances/XBMC.frappliance" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +echo " ln -sf /Applications/@APP_NAME@.frappliance /Applications/AppleTV.app/Appliances/@APP_NAME@.frappliance" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo " killall AppleTV" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo "fi" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo "FILE=/var/mobile/Media/Photos/seas0nTV.png" >> $DIRNAME/$PACKAGE/DEBIAN/postinst @@ -101,11 +101,12 @@ echo "if [ -f \$FILE ]; then" >> $DIRNAME/$PACKAGE/DEBIAN/po echo " echo \"File \$FILE exists. removing...\"" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo " rm \$FILE" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo "fi" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +cat $DIRNAME/../migrate_to_kodi_ios.sh >> $DIRNAME/$PACKAGE/DEBIAN/postinst chmod +x $DIRNAME/$PACKAGE/DEBIAN/postinst -# prep XBMC.frappliance +# prep @APP_NAME@.frappliance mkdir -p $DIRNAME/$PACKAGE/Applications -cp -r $XBMC $DIRNAME/$PACKAGE/Applications/ +cp -r $APP $DIRNAME/$PACKAGE/Applications/ find $DIRNAME/$PACKAGE/Applications/ -name '.svn' -exec rm -rf {} \; find $DIRNAME/$PACKAGE/Applications/ -name '.git*' -exec rm -rf {} \; find $DIRNAME/$PACKAGE/Applications/ -name '.DS_Store' -exec rm -rf {} \; diff --git a/tools/darwin/packaging/xbmc-ios/mkdeb-xbmc-ios.sh.in b/tools/darwin/packaging/ios/mkdeb-ios.sh.in index c1a10eddfc..0ec4e2e848 100644 --- a/tools/darwin/packaging/xbmc-ios/mkdeb-xbmc-ios.sh.in +++ b/tools/darwin/packaging/ios/mkdeb-ios.sh.in @@ -1,20 +1,20 @@ #!/bin/sh -# usage: ./mkdeb-xbmc-ios.sh release/debug (case insensitive) -# Allows us to run mkdeb-xbmc-ios.sh from anywhere in the three, rather than the tools/darwin/packaging/xbmc-ios folder only +# usage: ./mkdeb-ios.sh release/debug (case insensitive) +# Allows us to run mkdeb-ios.sh from anywhere in the three, rather than the tools/darwin/packaging/ios folder only XBMC_DEPENDS_ROOT=@DEPENDS_ROOT_FOR_XCODE@ SWITCH=`echo $1 | tr [A-Z] [a-z]` DIRNAME=`dirname $0` DSYM_TARGET_DIR=${XBMC_DEPENDS_ROOT}/dSyms -DSYM_FILENAME=XBMC.app.dSYM +DSYM_FILENAME=@APP_NAME@.app.dSYM if [ ${SWITCH:-""} = "debug" ]; then echo "Packaging Debug target for iOS" - XBMC="$DIRNAME/../../../../build/Debug-iphoneos/XBMC.app" + APP="$DIRNAME/../../../../build/Debug-iphoneos/@APP_NAME@.app" DSYM="$DIRNAME/../../../../build/Debug-iphoneos/$DSYM_FILENAME" elif [ ${SWITCH:-""} = "release" ]; then echo "Packaging Release target for iOS" - XBMC="$DIRNAME/../../../../build/Release-iphoneos/XBMC.app" + APP="$DIRNAME/../../../../build/Release-iphoneos/@APP_NAME@.app" DSYM="$DIRNAME/../../../../build/Release-iphoneos/$DSYM_FILENAME" else echo "You need to specify the build target" @@ -29,8 +29,8 @@ if [ -d $DSYM ]; then fi -if [ ! -d $XBMC ]; then - echo "XBMC.app not found! are you sure you built $1 target?" +if [ ! -d $APP ]; then + echo "@APP_NAME@.app not found! are you sure you built $1 target?" exit 1 fi if [ -f "${XBMC_DEPENDS_ROOT}/buildtools-native/bin/fakeroot" ]; then @@ -46,12 +46,12 @@ if [ -f "${XBMC_DEPENDS_ROOT}/buildtools-native/bin/dpkg-deb" ]; then export PATH=${bin_path}:${PATH} fi -PACKAGE=org.xbmc.xbmc-ios +PACKAGE=org.xbmc.@APP_NAME_LC@-ios VERSION=@APP_VERSION_MAJOR@.@APP_VERSION_MINOR@ REVISION=0~@APP_VERSION_TAG_LC@ ARCHIVE=${PACKAGE}_${VERSION}-${REVISION}_iphoneos-arm.deb -XBMCSIZE="$(du -s -k ${XBMC} | awk '{print $1}')" +SIZE="$(du -s -k ${APP} | awk '{print $1}')" echo Creating $PACKAGE package version $VERSION revision $REVISION ${SUDO} rm -rf $DIRNAME/$PACKAGE @@ -61,31 +61,32 @@ ${SUDO} rm -rf $DIRNAME/$ARCHIVE mkdir -p $DIRNAME/$PACKAGE/DEBIAN echo "Package: $PACKAGE" > $DIRNAME/$PACKAGE/DEBIAN/control echo "Priority: Extra" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Name: XBMC-iOS" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Name: @APP_NAME@-iOS" >> $DIRNAME/$PACKAGE/DEBIAN/control echo "Depends: firmware (>= 4.1)" >> $DIRNAME/$PACKAGE/DEBIAN/control echo "Version: $VERSION-$REVISION" >> $DIRNAME/$PACKAGE/DEBIAN/control echo "Architecture: iphoneos-arm" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Installed-Size: $XBMCSIZE" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Description: XBMC Multimedia Center for 4.x iOS" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Homepage: http://xbmc.org/" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Maintainer: Scott Davilla, Edgar Hucek" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Author: TeamXBMC" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Installed-Size: $SIZE" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Description: @APP_NAME@ Entertainment Center for 4.x iOS" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Homepage: http://kodi.tv/" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Maintainer: Memphiz" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Author: Team-@APP_NAME@" >> $DIRNAME/$PACKAGE/DEBIAN/control echo "Section: Multimedia" >> $DIRNAME/$PACKAGE/DEBIAN/control -echo "Icon: file:///Applications/XBMC.app/AppIcon57x57.png" >> $DIRNAME/$PACKAGE/DEBIAN/control +echo "Icon: file:///Applications/@APP_NAME@.app/AppIcon57x57.png" >> $DIRNAME/$PACKAGE/DEBIAN/control # prerm: called on remove and upgrade - get rid of existing bits. echo "#!/bin/sh" > $DIRNAME/$PACKAGE/DEBIAN/prerm -echo "find /Applications/XBMC.app -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm +echo "find /Applications/@APP_NAME@.app -delete" >> $DIRNAME/$PACKAGE/DEBIAN/prerm chmod +x $DIRNAME/$PACKAGE/DEBIAN/prerm # postinst: nothing for now. echo "#!/bin/sh" > $DIRNAME/$PACKAGE/DEBIAN/postinst -echo "chown -R mobile:mobile /Applications/XBMC.app" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +echo "chown -R mobile:mobile /Applications/@APP_NAME@.app" >> $DIRNAME/$PACKAGE/DEBIAN/postinst +cat $DIRNAME/../migrate_to_kodi_ios.sh >> $DIRNAME/$PACKAGE/DEBIAN/postinst chmod +x $DIRNAME/$PACKAGE/DEBIAN/postinst -# prep XBMC.app +# prep @APP_NAME@.app mkdir -p $DIRNAME/$PACKAGE/Applications -cp -r $XBMC $DIRNAME/$PACKAGE/Applications/ +cp -r $APP $DIRNAME/$PACKAGE/Applications/ find $DIRNAME/$PACKAGE/Applications/ -name '.svn' -exec rm -rf {} \; find $DIRNAME/$PACKAGE/Applications/ -name '.git*' -exec rm -rf {} \; find $DIRNAME/$PACKAGE/Applications/ -name '.DS_Store' -exec rm -rf {} \; diff --git a/tools/darwin/packaging/media/atv2/XBMC.png b/tools/darwin/packaging/media/atv2/TopShelf.png Binary files differindex fb7f58fac6..fb7f58fac6 100644 --- a/tools/darwin/packaging/media/atv2/XBMC.png +++ b/tools/darwin/packaging/media/atv2/TopShelf.png diff --git a/tools/darwin/packaging/migrate_to_kodi_ios.sh.in b/tools/darwin/packaging/migrate_to_kodi_ios.sh.in new file mode 100644 index 0000000000..be9155fa8c --- /dev/null +++ b/tools/darwin/packaging/migrate_to_kodi_ios.sh.in @@ -0,0 +1,30 @@ +APP_NAME=@APP_NAME@ +XBMC_HOME="/var/mobile/Library/Preferences/XBMC" +APP_HOME="/var/mobile/Library/Preferences/@APP_NAME@" + + +function needs_kodi_migration () { + #check if there is an old XBMC folder to migrate + if test -d "$XBMC_HOME" && test ! -d "$APP_HOME" + then + return "1"; + else + return "0"; + fi +} + +function migrate_to_kodi () { + echo "moving settings from $XBMC_HOME to $APP_HOME" + mv $XBMC_HOME $APP_HOME + chown -R mobile.mobile $APP_HOME + echo "Migration complete" + touch $APP_HOME/.kodi_data_was_migrated +} + +needs_kodi_migration +NEEDS_MIGRATION=$? +if [ "$NEEDS_MIGRATION" == "1" ] +then + echo "This is the first time you install @APP_NAME@ and we detected that you have an old XBMC configuration. Your XBMC configuration will now be migrated to @APP_NAME@ by moving the settings folder. If you ever want to go back to XBMC please backup /var/mobile/Library/Preferences/@APP_NAME@ after this installation has finished and rename it to XBMC in case you downgrade to XBMC." + migrate_to_kodi +fi diff --git a/tools/darwin/packaging/xbmc-osx/VolumeDSStore b/tools/darwin/packaging/osx/VolumeDSStore Binary files differindex 387b6e21eb..387b6e21eb 100644 --- a/tools/darwin/packaging/xbmc-osx/VolumeDSStore +++ b/tools/darwin/packaging/osx/VolumeDSStore diff --git a/tools/darwin/packaging/xbmc-osx/VolumeDSStoreApp b/tools/darwin/packaging/osx/VolumeDSStoreApp Binary files differindex f1a82a4bbb..f1a82a4bbb 100644 --- a/tools/darwin/packaging/xbmc-osx/VolumeDSStoreApp +++ b/tools/darwin/packaging/osx/VolumeDSStoreApp diff --git a/tools/darwin/packaging/xbmc-osx/VolumeIcon.icns b/tools/darwin/packaging/osx/VolumeIcon.icns Binary files differindex 75215701b6..75215701b6 100644 --- a/tools/darwin/packaging/xbmc-osx/VolumeIcon.icns +++ b/tools/darwin/packaging/osx/VolumeIcon.icns diff --git a/tools/darwin/packaging/xbmc-osx/background/DiskImageBackground.png b/tools/darwin/packaging/osx/background/DiskImageBackground.png Binary files differindex 2299a1ac75..2299a1ac75 100644 --- a/tools/darwin/packaging/xbmc-osx/background/DiskImageBackground.png +++ b/tools/darwin/packaging/osx/background/DiskImageBackground.png diff --git a/tools/darwin/packaging/xbmc-osx/background/DiskImageBackgroundDebug.png b/tools/darwin/packaging/osx/background/DiskImageBackgroundDebug.png Binary files differindex 2299a1ac75..2299a1ac75 100644 --- a/tools/darwin/packaging/xbmc-osx/background/DiskImageBackgroundDebug.png +++ b/tools/darwin/packaging/osx/background/DiskImageBackgroundDebug.png diff --git a/tools/darwin/packaging/xbmc-osx/dmgmaker.pl b/tools/darwin/packaging/osx/dmgmaker.pl index 1047d0a848..4720bf047a 100755 --- a/tools/darwin/packaging/xbmc-osx/dmgmaker.pl +++ b/tools/darwin/packaging/osx/dmgmaker.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Copyright (C) 2008-2013 Team XBMC +# Copyright (C) 2008-2013 Team Kodi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -74,8 +74,8 @@ if (! defined $ARGV[0]) { if ( $ARGV[0] eq "-c" ) { die("TODO: -c\n"); - #make_dmg(make_mpkg(), "XBMC Atlantis - 8.10", "XBMC Media Center"); + #make_dmg(make_mpkg(), "Kodi Atlantis - 8.10", "Kodi Media Center"); exit; } -make_dmg($ARGV[0], $ARGV[1], "XBMC"); +make_dmg($ARGV[0], $ARGV[1], "Kodi"); diff --git a/tools/darwin/packaging/xbmc-osx/mkdmg-xbmc-osx.sh.in b/tools/darwin/packaging/osx/mkdmg-osx.sh.in index 60764d2f28..8a4dfe6a7b 100755 --- a/tools/darwin/packaging/xbmc-osx/mkdmg-xbmc-osx.sh.in +++ b/tools/darwin/packaging/osx/mkdmg-osx.sh.in @@ -1,28 +1,28 @@ #!/bin/sh -# usage: ./mkdmg-xbmc-osx.sh release/debug (case insensitive) -# Allows us to run mkdmg-xbmc-osx.sh from anywhere in the three, rather than the tools/darwin/packaging/xbmc-osx folder only +# usage: ./mkdmg-osx.sh release/debug (case insensitive) +# Allows us to run mkdmg-osx.sh from anywhere in the three, rather than the tools/darwin/packaging/osx folder only SWITCH=`echo $1 | tr [A-Z] [a-z]` DIRNAME=`dirname $0` if [ ${SWITCH:-""} = "debug" ]; then echo "Packaging Debug target for OSX" - XBMC="$DIRNAME/../../../../build/Debug/XBMC.app" + APP="$DIRNAME/../../../../build/Debug/@APP_NAME@.app" elif [ ${SWITCH:-""} = "release" ]; then echo "Packaging Release target for OSX" - XBMC="$DIRNAME/../../../../build/Release/XBMC.app" + APP="$DIRNAME/../../../../build/Release/@APP_NAME@.app" else echo "You need to specify the build target" exit 1 fi -if [ ! -d $XBMC ]; then - echo "XBMC.app not found! are you sure you built $1 target?" +if [ ! -d $APP ]; then + echo "@APP_NAME@.app not found! are you sure you built $1 target?" exit 1 fi -ARCHITECTURE=`file $XBMC/Contents/MacOS/XBMC | awk '{print $NF}'` +ARCHITECTURE=`file $APP/Contents/MacOS/@APP_NAME@ | awk '{print $NF}'` -PACKAGE=org.xbmc.xbmc-osx +PACKAGE=org.xbmc.@APP_NAME_LC@-osx VERSION=@APP_VERSION_MAJOR@.@APP_VERSION_MINOR@ REVISION=0~@APP_VERSION_TAG_LC@ @@ -36,6 +36,6 @@ then umount /Volumes/$ARCHIVE fi -$DIRNAME/dmgmaker.pl $XBMC $ARCHIVE +$DIRNAME/dmgmaker.pl $APP $ARCHIVE echo "done" diff --git a/tools/darwin/packaging/xbmc-seatbeltunlock/03e48c66a9cae1ff768eb3fe7981c499.patch b/tools/darwin/packaging/seatbeltunlock/03e48c66a9cae1ff768eb3fe7981c499.patch Binary files differindex b58f5bd838..b58f5bd838 100644 --- a/tools/darwin/packaging/xbmc-seatbeltunlock/03e48c66a9cae1ff768eb3fe7981c499.patch +++ b/tools/darwin/packaging/seatbeltunlock/03e48c66a9cae1ff768eb3fe7981c499.patch diff --git a/tools/darwin/packaging/xbmc-seatbeltunlock/12313417e3afeba6531255af58cb5283.patch b/tools/darwin/packaging/seatbeltunlock/12313417e3afeba6531255af58cb5283.patch Binary files differindex 960edae2d2..960edae2d2 100644 --- a/tools/darwin/packaging/xbmc-seatbeltunlock/12313417e3afeba6531255af58cb5283.patch +++ b/tools/darwin/packaging/seatbeltunlock/12313417e3afeba6531255af58cb5283.patch diff --git a/tools/darwin/packaging/xbmc-seatbeltunlock/42d00865f281bb662b6ce447c9815e59.patch b/tools/darwin/packaging/seatbeltunlock/42d00865f281bb662b6ce447c9815e59.patch Binary files differindex f10a1b3571..f10a1b3571 100644 --- a/tools/darwin/packaging/xbmc-seatbeltunlock/42d00865f281bb662b6ce447c9815e59.patch +++ b/tools/darwin/packaging/seatbeltunlock/42d00865f281bb662b6ce447c9815e59.patch diff --git a/tools/darwin/packaging/xbmc-seatbeltunlock/5a28620a15c15d41e1ae836dd1f95f8d.patch b/tools/darwin/packaging/seatbeltunlock/5a28620a15c15d41e1ae836dd1f95f8d.patch Binary files differindex 12ea6fc9b1..12ea6fc9b1 100644 --- a/tools/darwin/packaging/xbmc-seatbeltunlock/5a28620a15c15d41e1ae836dd1f95f8d.patch +++ b/tools/darwin/packaging/seatbeltunlock/5a28620a15c15d41e1ae836dd1f95f8d.patch diff --git a/tools/darwin/packaging/xbmc-seatbeltunlock/f387cee7d7d302ec9e740632f44f1352.patch b/tools/darwin/packaging/seatbeltunlock/f387cee7d7d302ec9e740632f44f1352.patch Binary files differindex a990cd9f94..a990cd9f94 100644 --- a/tools/darwin/packaging/xbmc-seatbeltunlock/f387cee7d7d302ec9e740632f44f1352.patch +++ b/tools/darwin/packaging/seatbeltunlock/f387cee7d7d302ec9e740632f44f1352.patch diff --git a/tools/darwin/packaging/xbmc-seatbeltunlock/mkdeb-xbmc-seatbeltunlock.sh b/tools/darwin/packaging/seatbeltunlock/mkdeb-seatbeltunlock.sh.in index d9d422a845..a17741cf89 100755 --- a/tools/darwin/packaging/xbmc-seatbeltunlock/mkdeb-xbmc-seatbeltunlock.sh +++ b/tools/darwin/packaging/seatbeltunlock/mkdeb-seatbeltunlock.sh.in @@ -1,15 +1,20 @@ #!/bin/sh +XBMC_DEPENDS_ROOT=@DEPENDS_ROOT_FOR_XCODE@ +DIRNAME=`dirname $0` if [ -f "/usr/bin/sudo" ]; then SUDO="/usr/bin/sudo" fi -if [ -f "../../ios-depends/build/bin/dpkg-deb" ]; then - DPKGDEB="../../ios-depends/build/bin/dpkg-deb" -else - DPKGDEB="dpkg-deb" + +if [ -f "${XBMC_DEPENDS_ROOT}/buildtools-native/bin/dpkg-deb" ]; then + # make sure we pickup our tar, gnutar will fail when dpkg -i + bin_path=$(cd ${XBMC_DEPENDS_ROOT}/buildtools-native/bin; pwd) + export PATH=${bin_path}:${PATH} fi -PACKAGE=org.xbmc.xbmc-seatbeltunlock +DPKGDEB="dpkg-deb" + +PACKAGE=org.xbmc.@APP_NAME_LC@-seatbeltunlock VERSION=1.0 REVISION=5 @@ -24,13 +29,13 @@ mkdir -p $PACKAGE/DEBIAN echo "Package: $PACKAGE" > $PACKAGE/DEBIAN/control echo "Priority: Extra" >> $PACKAGE/DEBIAN/control echo "Depends: coreutils, bsdiff, gawk" >> $PACKAGE/DEBIAN/control -echo "Name: XBMC seatbelt unlock for AppleTV 2" >> $PACKAGE/DEBIAN/control +echo "Name: @APP_NAME@ seatbelt unlock for AppleTV 2" >> $PACKAGE/DEBIAN/control echo "Version: $VERSION-$REVISION" >> $PACKAGE/DEBIAN/control echo "Architecture: iphoneos-arm" >> $PACKAGE/DEBIAN/control -echo "Description: XBMC tweeks, removes seatbelt" >> $PACKAGE/DEBIAN/control -echo "Homepage: http://xbmc.org/" >> $PACKAGE/DEBIAN/control +echo "Description: @APP_NAME@ tweeks, removes seatbelt" >> $PACKAGE/DEBIAN/control +echo "Homepage: http://kodi.tv/" >> $PACKAGE/DEBIAN/control echo "Maintainer: Scott Davilla" >> $PACKAGE/DEBIAN/control -echo "Author: TeamXBMC" >> $PACKAGE/DEBIAN/control +echo "Author: Team-@APP_NAME@" >> $PACKAGE/DEBIAN/control echo "Section: Tweaks" >> $PACKAGE/DEBIAN/control # postinst: find lowtide/appletv, binary patch out seatbelt-profile key, @@ -47,40 +52,40 @@ echo "fi" >> $PACKAGE/DEBIAN/posti echo "case \`md5sum \$BINPATH | awk '{print \$1}'\` in" >> $PACKAGE/DEBIAN/postinst echo " 12313417e3afeba6531255af58cb5283 )" >> $PACKAGE/DEBIAN/postinst echo " echo \"Found 4.1 (8M89):Removing seatbelt profile key from Lowtide\"" >> $PACKAGE/DEBIAN/postinst -echo " bspatch /Applications/Lowtide.app/Lowtide /var/tmp/Lowtide-nosb /var/tmp/12313417e3afeba6531255af58cb5283.patch" >> $PACKAGE/DEBIAN/postinst -echo " rm /var/tmp/12313417e3afeba6531255af58cb5283.patch" >> $PACKAGE/DEBIAN/postinst +echo " bspatch /Applications/Lowtide.app/Lowtide /var/tmp/Lowtide-nosb /var/tmp/k12313417e3afeba6531255af58cb5283.patch" >> $PACKAGE/DEBIAN/postinst +echo " rm /var/tmp/k12313417e3afeba6531255af58cb5283.patch" >> $PACKAGE/DEBIAN/postinst echo " chmod 755 /var/tmp/Lowtide-nosb" >> $PACKAGE/DEBIAN/postinst echo " mv -f /Applications/Lowtide.app/Lowtide /Applications/Lowtide.app/Lowtide_org" >> $PACKAGE/DEBIAN/postinst echo " mv /var/tmp/Lowtide-nosb /Applications/Lowtide.app/Lowtide" >> $PACKAGE/DEBIAN/postinst echo " killall Lowtide ;;" >> $PACKAGE/DEBIAN/postinst echo " 5a28620a15c15d41e1ae836dd1f95f8d )" >> $PACKAGE/DEBIAN/postinst echo " echo \"Found 4.2.1 (8C154):Removing seatbelt profile key from AppleTV\"" >> $PACKAGE/DEBIAN/postinst -echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/5a28620a15c15d41e1ae836dd1f95f8d.patch" >> $PACKAGE/DEBIAN/postinst -echo " rm /var/tmp/5a28620a15c15d41e1ae836dd1f95f8d.patch" >> $PACKAGE/DEBIAN/postinst +echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/k5a28620a15c15d41e1ae836dd1f95f8d.patch" >> $PACKAGE/DEBIAN/postinst +echo " rm /var/tmp/k5a28620a15c15d41e1ae836dd1f95f8d.patch" >> $PACKAGE/DEBIAN/postinst echo " chmod 755 /var/tmp/AppleTV-nosb" >> $PACKAGE/DEBIAN/postinst echo " mv -f /Applications/AppleTV.app/AppleTV /Applications/AppleTV.app/AppleTV_org" >> $PACKAGE/DEBIAN/postinst echo " mv /var/tmp/AppleTV-nosb /Applications/AppleTV.app/AppleTV" >> $PACKAGE/DEBIAN/postinst echo " killall AppleTV ;;" >> $PACKAGE/DEBIAN/postinst echo " 03e48c66a9cae1ff768eb3fe7981c499 )" >> $PACKAGE/DEBIAN/postinst echo " echo \"Found 4.3 (8F202):Removing seatbelt profile key from AppleTV\"" >> $PACKAGE/DEBIAN/postinst -echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/03e48c66a9cae1ff768eb3fe7981c499.patch" >> $PACKAGE/DEBIAN/postinst -echo " rm /var/tmp/03e48c66a9cae1ff768eb3fe7981c499.patch" >> $PACKAGE/DEBIAN/postinst +echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/k03e48c66a9cae1ff768eb3fe7981c499.patch" >> $PACKAGE/DEBIAN/postinst +echo " rm /var/tmp/k03e48c66a9cae1ff768eb3fe7981c499.patch" >> $PACKAGE/DEBIAN/postinst echo " chmod 755 /var/tmp/AppleTV-nosb" >> $PACKAGE/DEBIAN/postinst echo " mv -f /Applications/AppleTV.app/AppleTV /Applications/AppleTV.app/AppleTV_org" >> $PACKAGE/DEBIAN/postinst echo " mv /var/tmp/AppleTV-nosb /Applications/AppleTV.app/AppleTV" >> $PACKAGE/DEBIAN/postinst echo " killall AppleTV ;;" >> $PACKAGE/DEBIAN/postinst echo " 42d00865f281bb662b6ce447c9815e59 )" >> $PACKAGE/DEBIAN/postinst echo " echo \"Found 4.3.2 (8F305):Removing seatbelt profile key from AppleTV\"" >> $PACKAGE/DEBIAN/postinst -echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/42d00865f281bb662b6ce447c9815e59.patch" >> $PACKAGE/DEBIAN/postinst -echo " rm /var/tmp/42d00865f281bb662b6ce447c9815e59.patch" >> $PACKAGE/DEBIAN/postinst +echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/k42d00865f281bb662b6ce447c9815e59.patch" >> $PACKAGE/DEBIAN/postinst +echo " rm /var/tmp/k42d00865f281bb662b6ce447c9815e59.patch" >> $PACKAGE/DEBIAN/postinst echo " chmod 755 /var/tmp/AppleTV-nosb" >> $PACKAGE/DEBIAN/postinst echo " mv -f /Applications/AppleTV.app/AppleTV /Applications/AppleTV.app/AppleTV_org" >> $PACKAGE/DEBIAN/postinst echo " mv /var/tmp/AppleTV-nosb /Applications/AppleTV.app/AppleTV" >> $PACKAGE/DEBIAN/postinst echo " killall AppleTV ;;" >> $PACKAGE/DEBIAN/postinst echo " f387cee7d7d302ec9e740632f44f1352 )" >> $PACKAGE/DEBIAN/postinst echo " echo \"Found 6.1 (10B144b):Removing seatbelt profile key from AppleTV\"" >> $PACKAGE/DEBIAN/postinst -echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/f387cee7d7d302ec9e740632f44f1352.patch" >> $PACKAGE/DEBIAN/postinst -echo " rm /var/tmp/f387cee7d7d302ec9e740632f44f1352.patch" >> $PACKAGE/DEBIAN/postinst +echo " bspatch /Applications/AppleTV.app/AppleTV /var/tmp/AppleTV-nosb /var/tmp/kf387cee7d7d302ec9e740632f44f1352.patch" >> $PACKAGE/DEBIAN/postinst +echo " rm /var/tmp/kf387cee7d7d302ec9e740632f44f1352.patch" >> $PACKAGE/DEBIAN/postinst echo " chmod 755 /var/tmp/AppleTV-nosb" >> $PACKAGE/DEBIAN/postinst echo " mv -f /Applications/AppleTV.app/AppleTV /Applications/AppleTV.app/AppleTV_org" >> $PACKAGE/DEBIAN/postinst echo " mv /var/tmp/AppleTV-nosb /Applications/AppleTV.app/AppleTV" >> $PACKAGE/DEBIAN/postinst @@ -93,11 +98,11 @@ chmod +x $PACKAGE/DEBIAN/postinst # create the patch directory and copy in patch mkdir -p $PACKAGE/var/tmp -cp 12313417e3afeba6531255af58cb5283.patch $PACKAGE/var/tmp/ -cp 5a28620a15c15d41e1ae836dd1f95f8d.patch $PACKAGE/var/tmp/ -cp 03e48c66a9cae1ff768eb3fe7981c499.patch $PACKAGE/var/tmp/ -cp 42d00865f281bb662b6ce447c9815e59.patch $PACKAGE/var/tmp/ -cp f387cee7d7d302ec9e740632f44f1352.patch $PACKAGE/var/tmp/ +cp 12313417e3afeba6531255af58cb5283.patch $PACKAGE/var/tmp/k12313417e3afeba6531255af58cb5283.patch +cp 5a28620a15c15d41e1ae836dd1f95f8d.patch $PACKAGE/var/tmp/k5a28620a15c15d41e1ae836dd1f95f8d.patch +cp 03e48c66a9cae1ff768eb3fe7981c499.patch $PACKAGE/var/tmp/k03e48c66a9cae1ff768eb3fe7981c499.patch +cp 42d00865f281bb662b6ce447c9815e59.patch $PACKAGE/var/tmp/k42d00865f281bb662b6ce447c9815e59.patch +cp f387cee7d7d302ec9e740632f44f1352.patch $PACKAGE/var/tmp/kf387cee7d7d302ec9e740632f44f1352.patch # set ownership to root:root ${SUDO} chown -R 0:0 $PACKAGE diff --git a/tools/darwin/runtime/preflight b/tools/darwin/runtime/preflight index e1fa21081c..06a7164d0a 100755 --- a/tools/darwin/runtime/preflight +++ b/tools/darwin/runtime/preflight @@ -1,18 +1,18 @@ #!/usr/bin/perl die("No HOME set, cannot install defaults.\n") - if !$ENV{HOME}; + if !$ENV{'HOME'}; -die("No XBMC_HOME set, cannot install defaults.\n") - if !$ENV{'XBMC_HOME'}; +die("No APP_HOME set, cannot install defaults.\n") + if !$ENV{'APP_HOME'}; sub get_home { return $ENV{'HOME'} if defined $ENV{'HOME'}; } sub get_extras { - # XBMC_HOME is assumed to be always setup - return $ENV{'XBMC_HOME'}."/extras/" if get_os() eq "osx"; + # APP_HOME is assumed to be always setup + return $ENV{'APP_HOME'}."/extras/" if get_os() eq "osx"; return; } @@ -29,6 +29,19 @@ sub get_xbmc_home { return; } +sub get_app_home { + my $os = get_os(); + my $home = get_home(); + return if !defined $home; + if ( $os eq "osx" ) { + return $home."/Library/Application Support/Kodi"; + } + elsif ( $os eq "linux" ) { + return $home."/.kodi"; + } + return; +} + sub get_os { if ( defined $ENV{'OSTYPE'} && $ENV{'OSTYPE'} =~ /linux/ ) { return "linux"; @@ -37,13 +50,13 @@ sub get_os { } sub get_userdata_path { - my $xhome = get_xbmc_home(); - return if !defined $xhome; - return "$xhome/userdata"; + my $apphome = get_app_home(); + return if !defined $apphome; + return "$apphome/userdata"; } sub setup_sources { - my $xbmchome = get_xbmc_home(); + my $apphome = get_app_home(); my $userdata = get_userdata_path(); my $sources = $userdata."/sources.xml"; @@ -77,13 +90,19 @@ sub get_sources_xml { while ( ($name, $path) = each( %{ $source } ) ) { $xml .= (" " x 8)."<source>\n"; $xml .= (" " x 12)."<name>$name</name>\n"; - if ( $path =~ /(.*)\^\^(.*)/ ) { - $xml .= (" " x 12)."<path>".$1."</path>\n"; - $xml .= (" " x 12)."<thumbnail>".$2."</thumbnail>\n"; - } - else { - $xml .= (" " x 12)."<path>".$path."</path>\n"; - } + + if ( $path =~ /(.*)\^\^(.*)/ ) { + $xml .= (" " x 12)."<path>".$1."</path>\n"; + $xml .= (" " x 12)."<thumbnail>".$2."</thumbnail>\n"; + } + else { + $xml .= (" " x 12)."<path>".$path."</path>\n"; + } + + if ($path ne "/" ) { + $xml .= (" " x 12)."<allowsharing>true</allowsharing>\n"; + } + $xml .= (" " x 8)."</source>\n"; } $xml .= (" " x 4)."</$sourcetype>\n"; @@ -95,8 +114,8 @@ sub get_sources_xml { sub get_default_sources { my $sources = {}; my $home = get_home(); - my $xbmchome = get_xbmc_home(); - return if !defined $xbmchome; + my $apphome = get_app_home(); + return if !defined $apphome; $sources->{'programs'} = {}; $sources->{'video'} = {}; @@ -126,31 +145,41 @@ sub get_default_sources { return $sources; } -sub first_xbmc_run() { - my $home = get_xbmc_home(); +sub first_app_run() { + my $home = get_app_home(); if ( ! -f "$home/.setup_complete" ) { return 1; } return; } -sub first_xbmc_version_run() { - my $home = get_xbmc_home(); +sub first_app_version_run() { + my $home = get_app_home(); if ( ! -f "$home/.setup_complete" ) { return 1; } return; } -sub setup_default_xbmc() { +sub needs_kodi_migration() { + my $xbmchome = get_xbmc_home(); + my $apphome = get_app_home(); + #check if there is an old XBMC folder to migrate + if ( -d "$xbmchome" && ! -d "$apphome" ) { + return 1; + } + return; +} + +sub setup_default_app() { my $extras = get_extras(); - my $xhome = get_xbmc_home(); + my $apphome = get_app_home(); my $userdata = get_userdata_path(); die("No extras :(\n") if !defined $extras; die("No XBMC home folder :(\n") - if !defined $xhome; + if !defined $apphome; die ("No userdata folder :(\n") if !defined $userdata; @@ -160,17 +189,30 @@ sub setup_default_xbmc() { `cp -fRv "$extras/user/" "$userdata"`; setup_sources(); - `touch -f "$xhome/.setup_complete"`; + `touch -f "$apphome/.setup_complete"`; } -sub setup_version_xbmc() { +sub setup_version_app() { #TODO } -if (first_xbmc_run()) { - setup_default_xbmc(); +#migration from XBMC to Kodi +sub migrate_to_kodi() { + my $xbmchome = get_xbmc_home(); + my $apphome = get_app_home(); + print "mv $xbmchome $apphome"; + `mv "$xbmchome" "$apphome"`; + `touch -f "$apphome/.kodi_data_was_migrated"`; +} + +if (needs_kodi_migration()) { + migrate_to_kodi(); +} + +if (first_app_run()) { + setup_default_app(); } -if (first_xbmc_version_run()) { - setup_version_xbmc(); +if (first_app_version_run()) { + setup_version_app(); } diff --git a/tools/depends/configure.in b/tools/depends/configure.in index a6a5a031ad..9c4ef7ac97 100644 --- a/tools/depends/configure.in +++ b/tools/depends/configure.in @@ -209,6 +209,7 @@ case $host in 10.7);; 10.8);; 10.9);; + 10.10);; *) AC_MSG_ERROR(error in configure of --with-sdk=$use_sdk) esac @@ -245,11 +246,11 @@ case $host in use_sdk="${use_sdk:-$found_sdk_version}" sdk_name=iphoneos$use_sdk case $use_xcode in - 5.* | 5.*.* ) - use_toolchain="${use_xcodepath}/Toolchains/XcodeDefault.xctoolchain" + 3.*.* | 4.* | 4.*.*) + use_toolchain="${use_toolchain:-`$use_xcodebuild -version -sdk $sdk_name PlatformPath`/Developer}" ;; *) - use_toolchain="${use_toolchain:-`$use_xcodebuild -version -sdk $sdk_name PlatformPath`/Developer}" + use_toolchain="${use_xcodepath}/Toolchains/XcodeDefault.xctoolchain" ;; esac @@ -258,6 +259,7 @@ case $host in 5.*);; 6.*);; 7.*);; + 8.*);; *) AC_MSG_ERROR(error in configure of --with-sdk=$use_sdk) ;; diff --git a/tools/depends/native/fakeroot-native/01-darwin14-openat.patch b/tools/depends/native/fakeroot-native/01-darwin14-openat.patch new file mode 100644 index 0000000000..599f1b42d0 --- /dev/null +++ b/tools/depends/native/fakeroot-native/01-darwin14-openat.patch @@ -0,0 +1,26 @@ +diff --git a/configure b/configure +index 0766dbb..5d3ecb2 100755 +--- a/configure ++++ b/configure +@@ -12523,7 +12523,7 @@ $as_echo "no" >&6; } + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +-for ac_func in fchmodat fchownat fstatat mkdirat mknodat openat renameat unlinkat lchmod fgetattrlist ++for ac_func in fchmodat fchownat fstatat mkdirat mknodat renameat unlinkat lchmod fgetattrlist + do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` + ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +diff --git a/configure.ac b/configure.ac +index 43a0984..1b10130 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -286,7 +286,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + ],[ AC_MSG_RESULT([no]) + ]) + +-AC_CHECK_FUNCS(fchmodat fchownat fstatat mkdirat mknodat openat renameat unlinkat lchmod fgetattrlist) ++AC_CHECK_FUNCS(fchmodat fchownat fstatat mkdirat mknodat renameat unlinkat lchmod fgetattrlist) + + dnl find out how stat() etc are called. On linux systems, we really + dnl need to wrap (IIRC): diff --git a/tools/depends/native/fakeroot-native/Makefile b/tools/depends/native/fakeroot-native/Makefile index 43ac4055fe..ed3e813be4 100644 --- a/tools/depends/native/fakeroot-native/Makefile +++ b/tools/depends/native/fakeroot-native/Makefile @@ -24,6 +24,7 @@ $(TARBALLS_LOCATION)/$(ARCHIVE): $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) -rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM) cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + cd $(PLATFORM); patch -p1 < ../01-darwin14-openat.patch cd $(PLATFORM); $(CONFIGURE) $(APP): $(PLATFORM) diff --git a/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl b/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl index 9cc3610509..fbf08539fb 100755 --- a/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl +++ b/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl @@ -86,7 +86,7 @@ if (grep /\.c$/, @gcc_cmd) { } elsif (grep /\.[sS]$/, @gcc_cmd) { # asm file, just do C preprocessor @preprocess_c_cmd = (@gcc_cmd, "-E"); -} elsif (grep /-(v|-version|dumpversion)/, @gcc_cmd) { +} elsif (grep /-(v|h|-version|dumpversion)/, @gcc_cmd) { # pass -v/--version along, used during probing. Matching '-v' might have # uninteded results but it doesn't matter much if gas-preprocessor or # the compiler fails. @@ -97,6 +97,8 @@ if (grep /\.c$/, @gcc_cmd) { if ($as_type eq "armasm") { $preprocess_c_cmd[0] = "cpp"; + push(@preprocess_c_cmd, "-U__ELF__"); + push(@preprocess_c_cmd, "-U__MACH__"); @preprocess_c_cmd = grep ! /^-nologo$/, @preprocess_c_cmd; # Remove -ignore XX parameter pairs from preprocess_c_cmd @@ -264,15 +266,22 @@ if ($force_thumb) { # note that the handling of arguments is probably overly permissive vs. gas # but it should be the same for valid cases while (<INPUT>) { + # remove lines starting with '#', preprocessing is done, '#' at start of + # the line indicates a comment for all supported archs (aarch64, arm, ppc + # and x86). Also strips line number comments but since they are off anyway + # it is no loss. + s/^#.*$//; # remove all comments (to avoid interfering with evaluating directives) s/(?<!\\)$inputcomm.*//x; # Strip out windows linefeeds s/\r$//; - # Strip out line number comments - armasm can handle them in a separate - # syntax, but since the line numbers are off they are only misleading. - s/^#\s+(\d+).*// if $as_type =~ /armasm/; - parse_line($_); + foreach my $subline (split(";", $_)) { + # Add newlines at the end of lines that don't already have one + chomp $subline; + $subline .= "\n"; + parse_line($subline); + } } sub eval_expr { @@ -393,7 +402,7 @@ sub parse_line { } elsif ($macro_level == 0) { expand_macros($line); } else { - if ($line =~ /\.macro\s+([\d\w\.]+)\s*(.*)/) { + if ($line =~ /\.macro\s+([\d\w\.]+)\s*,?\s*(.*)/) { $current_macro = $1; # commas in the argument list are optional, so only use whitespace as the separator @@ -824,7 +833,7 @@ sub handle_serialized_line { $labels_seen{$1} = 1; } - if ($line =~ s/^(\d+)://) { + if ($line =~ s/^\s*(\d+)://) { # Convert local labels into unique labels. armasm (at least in # RVCT) has something similar, but still different enough. # By converting to unique labels we avoid any possible @@ -985,7 +994,7 @@ sub handle_serialized_line { $line =~ s/fmxr/vmsr/; $line =~ s/fmrx/vmrs/; - $line =~ s/fadds/vadd/; + $line =~ s/fadds/vadd.f32/; } # catch unknown section names that aren't mach-o style (with a comma) diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile index 73a939cde8..3598d1968e 100644 --- a/tools/depends/target/Makefile +++ b/tools/depends/target/Makefile @@ -58,7 +58,7 @@ LINUX_SYSTEM_LIBS= ifeq ($(OS),linux) #not for raspberry pi ifneq ($(TARGET_PLATFORM),raspberry-pi) - DEPENDS += libsdl linux-system-libs + DEPENDS += libsdl2 linux-system-libs LINUX_SYSTEM_LIBS = linux-system-libs endif DEPENDS += alsa-lib @@ -98,7 +98,7 @@ openssl: $(ZLIB) gnutls: nettle $(ZLIB) nettle: gmp pythonmodule-pil: $(ZLIB) libjpeg-turbo libpng freetype2 python26 -libsdl: $(LINUX_SYSTEM_LIBS) +libsdl2: $(LINUX_SYSTEM_LIBS) libxslt: libgcrypt ffmpeg: $(ICONV) $(ZLIB) bzip2 libvorbis $(FFMPEG_DEPENDS) @@ -139,3 +139,4 @@ linux-system-libs: [ -f $(PREFIX)/lib/pkgconfig/ice.pc ] || ln -s /usr/lib/$(HOST)/pkgconfig/ice.pc $(PREFIX)/lib/pkgconfig/ice.pc [ -f $(PREFIX)/lib/pkgconfig/sm.pc ] || ln -s /usr/lib/$(HOST)/pkgconfig/sm.pc $(PREFIX)/lib/pkgconfig/sm.pc [ -f $(PREFIX)/lib/pkgconfig/xmu.pc ] || ln -s /usr/lib/$(HOST)/pkgconfig/xmu.pc $(PREFIX)/lib/pkgconfig/xmu.pc + [ -f $(PREFIX)/lib/pkgconfig/libdrm.pc ] || ln -s /usr/lib/$(HOST)/pkgconfig/libdrm.pc $(PREFIX)/lib/pkgconfig/libdrm.pc diff --git a/tools/depends/target/config.site.in b/tools/depends/target/config.site.in index bc5d2787b0..252a4dcd04 100644 --- a/tools/depends/target/config.site.in +++ b/tools/depends/target/config.site.in @@ -139,14 +139,14 @@ if test "@platform_os@" = "ios"; then # tweaks for libffi (ios must use llvm-gcc-4.2) if test "${PACKAGE_NAME}" = "libffi" ; then case "@use_xcode@" in - 5.* | 5.*.* ) - export CC="@use_toolchain@/usr/bin/clang" - export CPP="@use_toolchain@/usr/bin/clang -E" - ;; - *) + 3.*.* | 4.* | 4.*.*) export CC="@use_toolchain@/usr/bin/llvm-gcc-4.2" export CPP="@use_toolchain@/usr/bin/llvm-gcc-4.2 -E" ;; + *) + export CC="@use_toolchain@/usr/bin/clang" + export CPP="@use_toolchain@/usr/bin/clang -E" + ;; esac unset AS unset CCAS diff --git a/tools/depends/target/dummy-libxbmc/Makefile b/tools/depends/target/dummy-libxbmc/Makefile index 203dfa1477..d65537aad6 100644 --- a/tools/depends/target/dummy-libxbmc/Makefile +++ b/tools/depends/target/dummy-libxbmc/Makefile @@ -1,7 +1,9 @@ include ../../Makefile.include -DEPS= ../../Makefile.include Makefile dummy-libxbmc.c +VERSION.TXT := $(XBMCROOT)/version.txt +DEPS= ../../Makefile.include Makefile dummy-libxbmc.c $(VERSION.TXT) +APP_NAME=$(shell awk '/APP_NAME/ {print tolower($$2)}' $(VERSION.TXT)) -LIBDYLIB=libxbmc.so +LIBDYLIB=lib$(APP_NAME).so all: $(PLATFORM)/$(LIBDYLIB) .installed-$(PLATFORM) @@ -9,11 +11,11 @@ $(PLATFORM): mkdir -p $(PLATFORM) $(PLATFORM)/$(LIBDYLIB): $(PLATFORM) $(DEPS) - $(CC) -shared -o $(PLATFORM)/libxbmc.so dummy-libxbmc.c + $(CC) -shared -o $(PLATFORM)/lib$(APP_NAME).so dummy-libxbmc.c .installed-$(PLATFORM): $(PLATFORM)/$(LIBDYLIB) - mkdir -p $(PREFIX)/lib/dummy-libxbmc - cp $(PLATFORM)/libxbmc.so $(PREFIX)/lib/dummy-libxbmc + mkdir -p $(PREFIX)/lib/dummy-lib$(APP_NAME) + cp $(PLATFORM)/lib$(APP_NAME).so $(PREFIX)/lib/dummy-lib$(APP_NAME) touch $@ clean: diff --git a/tools/depends/target/libcec/Makefile b/tools/depends/target/libcec/Makefile index 16fec1beb9..6c72240242 100644 --- a/tools/depends/target/libcec/Makefile +++ b/tools/depends/target/libcec/Makefile @@ -3,9 +3,9 @@ DEPS= ../../Makefile.include Makefile # lib name, version LIBNAME=libcec -VERSION=2.1.4 -SOURCE=$(LIBNAME)-$(VERSION)-2 -ARCHIVE=$(SOURCE).tar.gz +VERSION=2.2.0 +SOURCE=$(LIBNAME)-$(VERSION) +ARCHIVE=$(SOURCE)-3.tar.gz # configuration settings CONFIGURE=./configure --prefix=$(PREFIX) --disable-rpi \ diff --git a/tools/depends/target/libmpeg2/06-dont-asm-motion-comp.patch b/tools/depends/target/libmpeg2/06-dont-asm-motion-comp.patch deleted file mode 100644 index 80a76443f7..0000000000 --- a/tools/depends/target/libmpeg2/06-dont-asm-motion-comp.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff --git a/libmpeg2/Makefile.am b/libmpeg2/Makefile.am -index a4dd944..c113bf9 100644 ---- a/libmpeg2/Makefile.am -+++ b/libmpeg2/Makefile.am -@@ -14,7 +14,7 @@ - motion_comp_vis.c motion_comp_arm.c \ - cpu_accel.c cpu_state.c - if ARCH_ARM --libmpeg2arch_la_SOURCES += motion_comp_arm_s.S motion_comp_neon.c -+libmpeg2arch_la_SOURCES += motion_comp_neon.c - endif - libmpeg2arch_la_CFLAGS = $(OPT_CFLAGS) $(ARCH_OPT_CFLAGS) $(LIBMPEG2_CFLAGS) - ---- a/libmpeg2/motion_comp_arm.c -+++ b/libmpeg2/motion_comp_arm.c -@@ -93,14 +93,21 @@ MC_FUNC (put,y) - MC_FUNC (avg,y) - MC_FUNC (put,xy) - MC_FUNC (avg,xy) -+MC_FUNC (put,o) -+MC_FUNC (put,x) - - --extern void MC_put_o_16_arm (uint8_t * dest, const uint8_t * ref, -- int stride, int height); -- --extern void MC_put_x_16_arm (uint8_t * dest, const uint8_t * ref, -- int stride, int height); -+static void MC_put_o_16_arm (uint8_t * dest, const uint8_t * ref, -+ int stride, int height) -+{ -+ MC_put_o_16_c(dest, ref, stride, height); -+} - -+static void MC_put_x_16_arm (uint8_t * dest, const uint8_t * ref, -+ int stride, int height) -+{ -+ MC_put_x_16_c(dest, ref, stride, height); -+} - - static void MC_put_y_16_arm (uint8_t * dest, const uint8_t * ref, - int stride, int height) -@@ -114,11 +121,17 @@ static void MC_put_xy_16_arm (uint8_t * dest, const uint8_t * ref, - MC_put_xy_16_c(dest, ref, stride, height); - } - --extern void MC_put_o_8_arm (uint8_t * dest, const uint8_t * ref, -- int stride, int height); -+static void MC_put_o_8_arm (uint8_t * dest, const uint8_t * ref, -+ int stride, int height) -+{ -+ MC_put_o_8_c(dest, ref, stride, height); -+} - --extern void MC_put_x_8_arm (uint8_t * dest, const uint8_t * ref, -- int stride, int height); -+static void MC_put_x_8_arm (uint8_t * dest, const uint8_t * ref, -+ int stride, int height) -+{ -+ MC_put_x_8_c(dest, ref, stride, height); -+} - - static void MC_put_y_8_arm (uint8_t * dest, const uint8_t * ref, - int stride, int height) diff --git a/tools/depends/target/libmpeg2/06-motion_comp_arm_s.S-even_more_pic.patch b/tools/depends/target/libmpeg2/06-motion_comp_arm_s.S-even_more_pic.patch new file mode 100644 index 0000000000..5b71828942 --- /dev/null +++ b/tools/depends/target/libmpeg2/06-motion_comp_arm_s.S-even_more_pic.patch @@ -0,0 +1,98 @@ +--- libmpeg2/motion_comp_arm_s.S 2014-09-24 23:27:41.000000000 +0200 ++++ libmpeg2/motion_comp_arm_s.S 2014-09-24 23:01:06.000000000 +0200 +@@ -22,7 +22,7 @@ + .text + + @ ---------------------------------------------------------------- +- .align ++ .align 2 + #if defined(__APPLE__) && defined(__arm__) + .global _MC_put_o_16_arm + _MC_put_o_16_arm: +@@ -36,10 +36,10 @@ + and r4, r1, #3 + ldrb r4, [pc, r4] + add pc, pc, r4, lsl #2 +- .byte (MC_put_o_16_arm_align0 - 0f)>>2 +- .byte (MC_put_o_16_arm_align1 - 0f)>>2 +- .byte (MC_put_o_16_arm_align2 - 0f)>>2 +- .byte (MC_put_o_16_arm_align3 - 0f)>>2 ++ .byte (MC_put_o_16_arm_align0 - MC_put_o_16_arm_align0)>>2 ++ .byte (MC_put_o_16_arm_align1 - MC_put_o_16_arm_align1)>>2 ++ .byte (MC_put_o_16_arm_align2 - MC_put_o_16_arm_align2)>>2 ++ .byte (MC_put_o_16_arm_align3 - MC_put_o_16_arm_align3)>>2 + 0: + + MC_put_o_16_arm_align0: +@@ -86,7 +86,7 @@ + ldmfd sp!, {r4-r11, pc} @@ update PC with LR content. + + @ ---------------------------------------------------------------- +- .align ++ .align 2 + #if defined(__APPLE__) && defined(__arm__) + .global _MC_put_o_8_arm + _MC_put_o_8_arm: +@@ -100,10 +100,10 @@ + and r4, r1, #3 + ldrb r4, [pc, r4] + add pc, pc, r4, lsl #2 +- .byte (MC_put_o_8_arm_align0 - 0f)>>2 +- .byte (MC_put_o_8_arm_align1 - 0f)>>2 +- .byte (MC_put_o_8_arm_align2 - 0f)>>2 +- .byte (MC_put_o_8_arm_align3 - 0f)>>2 ++ .byte (MC_put_o_8_arm_align0 - MC_put_o_8_arm_align0)>>2 ++ .byte (MC_put_o_8_arm_align1 - MC_put_o_8_arm_align1)>>2 ++ .byte (MC_put_o_8_arm_align2 - MC_put_o_8_arm_align2)>>2 ++ .byte (MC_put_o_8_arm_align3 - MC_put_o_8_arm_align3)>>2 + 0: + + MC_put_o_8_arm_align0: +@@ -159,7 +159,7 @@ + add \rW2, \rW2, r10 + .endm + +- .align ++ .align 2 + #if defined(__APPLE__) && defined(__arm__) + .global _MC_put_x_16_arm + _MC_put_x_16_arm: +@@ -175,10 +175,10 @@ + mvn r12, r11 + ldrb r4, [pc, r4] + add pc, pc, r4, lsl #2 +- .byte (MC_put_x_16_arm_align0 - 0f)>>2 +- .byte (MC_put_x_16_arm_align1 - 0f)>>2 +- .byte (MC_put_x_16_arm_align2 - 0f)>>2 +- .byte (MC_put_x_16_arm_align3 - 0f)>>2 ++ .byte (MC_put_x_16_arm_align0 - MC_put_x_16_arm_align0)>>2 ++ .byte (MC_put_x_16_arm_align1 - MC_put_x_16_arm_align1)>>2 ++ .byte (MC_put_x_16_arm_align2 - MC_put_x_16_arm_align2)>>2 ++ .byte (MC_put_x_16_arm_align3 - MC_put_x_16_arm_align3)>>2 + 0: + .word 0x01010101 + +@@ -255,7 +255,7 @@ + ldmfd sp!, {r4-r11,pc} @@ update PC with LR content. + + @ ---------------------------------------------------------------- +- .align ++ .align 2 + #if defined(__APPLE__) && defined(__arm__) + .global _MC_put_x_8_arm + _MC_put_x_8_arm: +@@ -271,10 +271,10 @@ + mvn r12, r11 + ldrb r4, [pc, r4] + add pc, pc, r4, lsl #2 +- .byte (MC_put_x_8_arm_align0 - 0f)>>2 +- .byte (MC_put_x_8_arm_align1 - 0f)>>2 +- .byte (MC_put_x_8_arm_align2 - 0f)>>2 +- .byte (MC_put_x_8_arm_align3 - 0f)>>2 ++ .byte (MC_put_x_8_arm_align0 - MC_put_x_8_arm_align0)>>2 ++ .byte (MC_put_x_8_arm_align1 - MC_put_x_8_arm_align1)>>2 ++ .byte (MC_put_x_8_arm_align2 - MC_put_x_8_arm_align2)>>2 ++ .byte (MC_put_x_8_arm_align3 - MC_put_x_8_arm_align3)>>2 + 0: + .word 0x01010101 + diff --git a/tools/depends/target/libmpeg2/Makefile b/tools/depends/target/libmpeg2/Makefile index 8916495d98..0f4fe5b018 100644 --- a/tools/depends/target/libmpeg2/Makefile +++ b/tools/depends/target/libmpeg2/Makefile @@ -32,8 +32,10 @@ endif cd $(PLATFORM); patch -p0 < ../05-upstream-motion_comp_arm_s.S-is-not-PIC-enough.patch ifeq ($(OS),ios) case $(XCODE_VERSION) in \ - 5.* | 5.*.*) \ - cd $(PLATFORM); patch -p1 < ../06-dont-asm-motion-comp.patch \ + 4.* | 4.*.*) \ + ;;\ + *) \ + cd $(PLATFORM); patch -p0 < ../06-motion_comp_arm_s.S-even_more_pic.patch \ ;;\ esac endif diff --git a/tools/depends/target/libsdl2/Makefile b/tools/depends/target/libsdl2/Makefile new file mode 100644 index 0000000000..6c6eb5a26a --- /dev/null +++ b/tools/depends/target/libsdl2/Makefile @@ -0,0 +1,41 @@ +include ../../Makefile.include +DEPS= ../../Makefile.include Makefile + +# lib name, version +LIBNAME=SDL2 +VERSION=2.0.3 +SOURCE=$(LIBNAME)-$(VERSION) +ARCHIVE=$(SOURCE).tar.gz + +# configuration settings +CONFIGURE=./configure --prefix=$(PREFIX) --disable-video-directfb +ifneq ($(OS),linux) +CONFIGURE += --without-x --disable-video-x11 +endif + +LIBDYLIB=$(PLATFORM)/build/.libs/lib$(LIBNAME).a + +all: .installed-$(PLATFORM) + +$(TARBALLS_LOCATION)/$(ARCHIVE): + cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE) + +$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) + rm -rf $(PLATFORM); mkdir -p $(PLATFORM) + cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + cd $(PLATFORM); ./autogen.sh + cd $(PLATFORM); $(CONFIGURE) + +$(LIBDYLIB): $(PLATFORM) + $(MAKE) -C $(PLATFORM) + +.installed-$(PLATFORM): $(LIBDYLIB) + $(MAKE) -C $(PLATFORM) install + touch $@ + +clean: + $(MAKE) -C $(PLATFORM) clean + rm -f .installed-$(PLATFORM) + +distclean:: + rm -rf $(PLATFORM) .installed-$(PLATFORM) diff --git a/tools/depends/target/libssh/Makefile b/tools/depends/target/libssh/Makefile index 930fe6a667..ae9d3f0f7e 100644 --- a/tools/depends/target/libssh/Makefile +++ b/tools/depends/target/libssh/Makefile @@ -21,6 +21,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) cd $(PLATFORM); patch -p0 < ../removelegacy.patch cd $(PLATFORM); patch -p0 < ../android.patch cd $(PLATFORM); patch -p0 < ../md5.patch + cd $(PLATFORM); patch -p1 < ../darwin.patch sed -ie "s|-fstack-protector|-fnostack-protector|" "$(PLATFORM)/cmake/Modules/DefineCompilerFlags.cmake" sed -ie "s|add_subdirectory(examples)||" "$(PLATFORM)/CMakeLists.txt" cd $(PLATFORM)/build; $(CMAKE) -DWITH_STATIC_LIB=1 -DTHREADS_PTHREAD_ARG=0 VERBOSE=1 .. diff --git a/tools/depends/target/libssh/darwin.patch b/tools/depends/target/libssh/darwin.patch new file mode 100644 index 0000000000..3288d295f7 --- /dev/null +++ b/tools/depends/target/libssh/darwin.patch @@ -0,0 +1,37 @@ +diff --git a/include/libssh/misc.h b/include/libssh/misc.h +index 9897c4e..fe4f602 100644 +--- a/include/libssh/misc.h ++++ b/include/libssh/misc.h +@@ -35,8 +35,12 @@ int ssh_is_ipaddr_v4(const char *str); + int ssh_is_ipaddr(const char *str); + + /* macro for byte ordering */ ++#if !defined(ntohll) + uint64_t ntohll(uint64_t); ++#endif ++#if !defined(htonll) + #define htonll(x) ntohll(x) ++#endif + + /* list processing */ + +diff --git a/src/misc.c b/src/misc.c +index 008be1b..3c2d8bb 100644 +--- a/src/misc.c ++++ b/src/misc.c +@@ -286,6 +286,7 @@ int ssh_is_ipaddr(const char *str) { + + #endif /* _WIN32 */ + ++#if !defined(ntohll) + uint64_t ntohll(uint64_t a) { + #ifdef WORDS_BIGENDIAN + return a; +@@ -298,6 +299,7 @@ uint64_t ntohll(uint64_t a) { + return ((((uint64_t) low) << 32) | ( high)); + #endif + } ++#endif + + char *ssh_lowercase(const char* str) { + char *new, *p; diff --git a/tools/depends/target/pythonmodule-pil/Imaging-1.1.7-bz2-link.patch b/tools/depends/target/pythonmodule-pil/Imaging-1.1.7-bz2-link.patch new file mode 100644 index 0000000000..de284045a5 --- /dev/null +++ b/tools/depends/target/pythonmodule-pil/Imaging-1.1.7-bz2-link.patch @@ -0,0 +1,13 @@ +diff --git a/setup.py b/setup.py +index 5872f72..372eeaa 100644 +--- a/setup.py ++++ b/setup.py +@@ -293,7 +293,7 @@ class pil_build_ext(build_ext): + if feature.freetype_version == 20: + defs.append(("USE_FREETYPE_2_0", None)) + exts.append(Extension( +- "_imagingft", ["_imagingft.c"], libraries=["freetype"], ++ "_imagingft", ["_imagingft.c"], libraries=["freetype", "bz2", "z"], + define_macros=defs + )) + diff --git a/tools/depends/target/pythonmodule-pil/Makefile b/tools/depends/target/pythonmodule-pil/Makefile index 18fbc24087..c242df92fc 100644 --- a/tools/depends/target/pythonmodule-pil/Makefile +++ b/tools/depends/target/pythonmodule-pil/Makefile @@ -25,6 +25,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) cd $(PLATFORM); patch -p1 < ../Imaging-1.1.7-access.patch cd $(PLATFORM); patch -p0 < ../Imaging-1.1.7-zip-include.patch cd $(PLATFORM); patch -p0 < ../Imaging-1.1.7-remove-zlib-check.patch + cd $(PLATFORM); patch -p1 < ../Imaging-1.1.7-bz2-link.patch cd $(PLATFORM); sed -ie "s|"darwin"|"darwinNot"|g" "setup.py" $(LIBDYLIB): $(PLATFORM) diff --git a/tools/depends/target/xbmc-pvr-addons/Makefile b/tools/depends/target/xbmc-pvr-addons/Makefile index 8d1aed646a..76c73a012a 100644 --- a/tools/depends/target/xbmc-pvr-addons/Makefile +++ b/tools/depends/target/xbmc-pvr-addons/Makefile @@ -2,7 +2,7 @@ include ../../Makefile.include #DEPS= ../../Makefile.include Makefile LIBNAME=xbmc-pvr-addons -VERSION=3949502043d520e4707bc3109abf3c6edb23cf67 +VERSION=067befe6b8da81e29abca8cd394d08c84233677b GIT_DIR=$(TARBALLS_LOCATION)/$(LIBNAME).git BASE_URL=git://github.com/opdenkamp/$(LIBNAME).git DYLIB=$(PLATFORM)/addons/pvr.demo/.libs/libpvrdemo-addon.so @@ -16,7 +16,9 @@ export GIT_WORK_TREE=$(PLATFORM) export MYSQL_CONFIG=$(PREFIX)/bin/mysql_config # configuration settings -CONFIGURE=./configure --prefix=$(PREFIX) --enable-addons-with-dependencies +VERSION.TXT := $(XBMCROOT)/version.txt +APP_NAME=$(shell awk '/APP_NAME/ {print tolower($$2)}' $(VERSION.TXT)) +CONFIGURE=./configure --prefix=$(PREFIX) --libdir=$(PREFIX)/lib/$(APP_NAME)/addons --datadir=$(PREFIX)/share/$(APP_NAME)/addons --enable-addons-with-dependencies all: .installed-$(PLATFORM) diff --git a/tools/depends/target/xbmc/Makefile b/tools/depends/target/xbmc/Makefile index fb65398013..ad531a0980 100644 --- a/tools/depends/target/xbmc/Makefile +++ b/tools/depends/target/xbmc/Makefile @@ -1,5 +1,8 @@ -include ../../Makefile.include +VERSION.TXT := $(XBMCROOT)/version.txt +APP_NAME=$(shell awk '/APP_NAME/ {print tolower($$2)}' $(VERSION.TXT)) + SOURCE=../../../../ export CXXFLAGS+=-O3 @@ -15,10 +18,10 @@ endif CONFIGURE += $(CONFIG_EXTRA) -all: $(SOURCE)/libxbmc.so +all: $(SOURCE)/lib$(APP_NAME).so -$(SOURCE)/libxbmc.so: +$(SOURCE)/lib$(APP_NAME).so: cd $(SOURCE); BOOTSTRAP_FROM_DEPENDS=yes ./bootstrap cd $(SOURCE); $(CONFIGURE) diff --git a/tools/mk-release-source b/tools/mk-release-source index 68bdfa13c5..68b3854d14 100755 --- a/tools/mk-release-source +++ b/tools/mk-release-source @@ -1,7 +1,7 @@ #!/bin/bash REVISION="${1}" COMPRESS="gzip" -WORKDIR="xbmc-${REVISION}" +WORKDIR="kodi-${REVISION}" if [[ -z "${REVISION}" ]]; then echo "Usage: ${0} tag|branch|commit [gzip|xz|...]" && exit 1; fi if [[ -d "${WORKDIR}" ]]; then echo "${WORKDIR} dir exists, refusing to overwrite" && exit 1; fi diff --git a/xbmc-xrandr.c b/xbmc-xrandr.c index 3c686e2059..7d164d0a31 100644 --- a/xbmc-xrandr.c +++ b/xbmc-xrandr.c @@ -3005,9 +3005,9 @@ main (int argc, char **argv) if (mode) { if (crtc_info) { - printf (" w=\"%d\" h=\"%d\" x=\"%d\" y=\"%d\"", + printf (" w=\"%d\" h=\"%d\" x=\"%d\" y=\"%d\" crtc=\"%d\"", crtc_info->width, crtc_info->height, - crtc_info->x, crtc_info->y); + crtc_info->x, crtc_info->y, crtc->crtc.index); } else { printf (" w=\"%d\" h=\"%d\" x=\"%d\" y=\"%d\"", mode->width, mode->height, output->x, output->y); diff --git a/xbmc/AppParamParser.cpp b/xbmc/AppParamParser.cpp index 877914aa0f..10e8540785 100644 --- a/xbmc/AppParamParser.cpp +++ b/xbmc/AppParamParser.cpp @@ -25,6 +25,7 @@ #include "ApplicationMessenger.h" #include "settings/AdvancedSettings.h" #include "utils/log.h" +#include "utils/StringUtils.h" #ifdef TARGET_WINDOWS #include "WIN32Util.h" #endif @@ -81,21 +82,23 @@ void CAppParamParser::Parse(const char* argv[], int nArgs) void CAppParamParser::DisplayVersion() { - printf("XBMC Media Center %s\n", g_infoManager.GetVersion().c_str()); - printf("Copyright (C) 2005-2013 Team XBMC - http://xbmc.org\n"); + printf("%s Media Center %s\n", g_infoManager.GetVersion().c_str(), g_infoManager.GetAppName().c_str()); + printf("Copyright (C) 2005-2013 Team %s - http://kodi.tv\n", g_infoManager.GetAppName().c_str()); exit(0); } void CAppParamParser::DisplayHelp() { - printf("Usage: xbmc [OPTION]... [FILE]...\n\n"); + std::string lcAppName = g_infoManager.GetAppName(); + StringUtils::ToLower(lcAppName); + printf("Usage: %s [OPTION]... [FILE]...\n\n", lcAppName.c_str()); printf("Arguments:\n"); printf(" -d <n>\t\tdelay <n> seconds before starting\n"); - printf(" -fs\t\t\tRuns XBMC in full screen\n"); - printf(" --standalone\t\tXBMC runs in a stand alone environment without a window \n"); + printf(" -fs\t\t\tRuns %s in full screen\n", g_infoManager.GetAppName().c_str()); + printf(" --standalone\t\t%s runs in a stand alone environment without a window \n", g_infoManager.GetAppName().c_str()); printf("\t\t\tmanager and supporting applications. For example, that\n"); printf("\t\t\tenables network settings.\n"); - printf(" -p or --portable\tXBMC will look for configurations in install folder instead of ~/.xbmc\n"); + printf(" -p or --portable\t%s will look for configurations in install folder instead of ~/.%s\n", g_infoManager.GetAppName().c_str(), lcAppName.c_str()); printf(" --legacy-res\t\tEnables screen resolutions such as PAL, NTSC, etc.\n"); #ifdef HAS_LIRC printf(" -l or --lircdev\tLircDevice to use default is " LIRC_DEVICE " .\n"); diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index e28f93a3d5..4d261830eb 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -103,8 +103,10 @@ #include "input/XBMC_vkeys.h" #include "input/MouseStat.h" -#ifdef HAS_SDL +#if SDL_VERSION == 1 #include <SDL/SDL.h> +#elif SDL_VERSION == 2 +#include <SDL2/SDL.h> #endif #if defined(FILESYSTEM) && !defined(TARGET_POSIX) @@ -278,6 +280,7 @@ #include "video/dialogs/GUIDialogSubtitles.h" #include "utils/XMLUtils.h" #include "addons/AddonInstaller.h" +#include "CompileInfo.h" #ifdef HAS_PERFORMANCE_SAMPLE #include "utils/PerformanceSample.h" @@ -560,7 +563,7 @@ extern "C" void __stdcall cleanup_emu_environ(); // // Utility function used to copy files from the application bundle -// over to the user data directory in Application Support/XBMC. +// over to the user data directory in Application Support/Kodi. // static void CopyUserDataIfNeeded(const CStdString &strPath, const CStdString &file) { @@ -586,7 +589,7 @@ void CApplication::Preflight() CStdString install_path; CUtil::GetHomePath(install_path); - setenv("XBMC_HOME", install_path.c_str(), 0); + setenv("APP_HOME", install_path.c_str(), 0); install_path += "/tools/darwin/runtime/preflight"; system(install_path.c_str()); #endif @@ -642,7 +645,9 @@ bool CApplication::Create() if (!CLog::Init(CSpecialProtocol::TranslatePath(g_advancedSettings.m_logFolder).c_str())) { - fprintf(stderr,"Could not init logging classes. Permission errors on ~/.xbmc (%s)\n", + std::string lcAppName = CCompileInfo::GetAppName(); + StringUtils::ToLower(lcAppName); + fprintf(stderr,"Could not init logging classes. Permission errors on ~/.%s (%s)\n", lcAppName.c_str(), CSpecialProtocol::TranslatePath(g_advancedSettings.m_logFolder).c_str()); return false; } @@ -730,7 +735,9 @@ bool CApplication::Create() CStdString executable = CUtil::ResolveExecutablePath(); CLog::Log(LOGNOTICE, "The executable running is: %s", executable.c_str()); CLog::Log(LOGNOTICE, "Local hostname: %s", m_network->GetHostName().c_str()); - CLog::Log(LOGNOTICE, "Log File is located: %sxbmc.log", g_advancedSettings.m_logFolder.c_str()); + std::string lowerAppName = CCompileInfo::GetAppName(); + StringUtils::ToLower(lowerAppName); + CLog::Log(LOGNOTICE, "Log File is located: %s%s.log", g_advancedSettings.m_logFolder.c_str(), lowerAppName.c_str()); CRegExp::LogCheckUtf8Support(); CLog::Log(LOGNOTICE, "-----------------------------------------------------------------------"); @@ -991,6 +998,11 @@ bool CApplication::CreateGUI() if (!CButtonTranslator::GetInstance().Load()) return false; +#ifdef HAS_SDL_JOYSTICK + // Pass the mapping of axis to triggers to g_Joystick + g_Joystick.LoadAxesConfigs(CButtonTranslator::GetInstance().GetAxesConfigs()); +#endif + RESOLUTION_INFO info = g_graphicsContext.GetResInfo(); CLog::Log(LOGINFO, "GUI format %ix%i, Display %s", info.iWidth, @@ -1041,13 +1053,13 @@ bool CApplication::InitDirectoriesLinux() /* The following is the directory mapping for Platform Specific Mode: - special://xbmc/ => [read-only] system directory (/usr/share/xbmc) - special://home/ => [read-write] user's directory that will override special://xbmc/ system-wide + special://xbmc/ => [read-only] system directory (/usr/share/kodi) + special://home/ => [read-write] user's directory that will override special://kodi/ system-wide installations like skins, screensavers, etc. - ($HOME/.xbmc) + ($HOME/.kodi) NOTE: XBMC will look in both special://xbmc/addons and special://home/addons for addons. special://masterprofile/ => [read-write] userdata of master profile. It will by default be - mapped to special://home/userdata ($HOME/.xbmc/userdata) + mapped to special://home/userdata ($HOME/.kodi/userdata) special://profile/ => [read-write] current profile's userdata directory. Generally special://masterprofile for the master profile or special://masterprofile/profiles/<profile_name> for other profiles. @@ -1057,55 +1069,63 @@ bool CApplication::InitDirectoriesLinux() */ #if defined(TARGET_POSIX) && !defined(TARGET_DARWIN) - CStdString userName; + std::string userName; if (getenv("USER")) userName = getenv("USER"); else userName = "root"; - CStdString userHome; + std::string userHome; if (getenv("HOME")) userHome = getenv("HOME"); else userHome = "/root"; - CStdString xbmcBinPath, xbmcPath; - CUtil::GetHomePath(xbmcBinPath, "XBMC_BIN_HOME"); - xbmcPath = getenv("XBMC_HOME"); + std::string appBinPath, appPath; + std::string appName = CCompileInfo::GetAppName(); + std::string dotLowerAppName = "." + appName; + StringUtils::ToLower(dotLowerAppName); + const char* envAppHome = "APP_HOME"; + const char* envAppBinHome = "APP_BIN_HOME"; + const char* envAppTemp = "APP_TEMP"; - if (xbmcPath.empty()) + + CUtil::GetHomePath(appBinPath, envAppBinHome); + if (getenv(envAppHome)) + appPath = getenv(envAppHome); + else { - xbmcPath = xbmcBinPath; - /* Check if xbmc binaries and arch independent data files are being kept in + appPath = appBinPath; + /* Check if binaries and arch independent data files are being kept in * separate locations. */ - if (!CDirectory::Exists(URIUtils::AddFileToFolder(xbmcPath, "language"))) + if (!CDirectory::Exists(URIUtils::AddFileToFolder(appPath, "language"))) { /* Attempt to locate arch independent data files. */ - CUtil::GetHomePath(xbmcPath); - if (!CDirectory::Exists(URIUtils::AddFileToFolder(xbmcPath, "language"))) + CUtil::GetHomePath(appPath); + if (!CDirectory::Exists(URIUtils::AddFileToFolder(appPath, "language"))) { - fprintf(stderr, "Unable to find path to XBMC data files!\n"); + fprintf(stderr, "Unable to find path to %s data files!\n", appName.c_str()); exit(1); } } } /* Set some environment variables */ - setenv("XBMC_BIN_HOME", xbmcBinPath.c_str(), 0); - setenv("XBMC_HOME", xbmcPath.c_str(), 0); + setenv(envAppBinHome, appBinPath.c_str(), 0); + setenv(envAppHome, appPath.c_str(), 0); if (m_bPlatformDirectories) { // map our special drives - CSpecialProtocol::SetXBMCBinPath(xbmcBinPath); - CSpecialProtocol::SetXBMCPath(xbmcPath); - CSpecialProtocol::SetHomePath(userHome + "/.xbmc"); - CSpecialProtocol::SetMasterProfilePath(userHome + "/.xbmc/userdata"); + CSpecialProtocol::SetXBMCBinPath(appBinPath); + CSpecialProtocol::SetXBMCPath(appPath); + CSpecialProtocol::SetHomePath(userHome + "/" + dotLowerAppName); + CSpecialProtocol::SetMasterProfilePath(userHome + "/" + dotLowerAppName + "/userdata"); CStdString strTempPath = userHome; - strTempPath = URIUtils::AddFileToFolder(strTempPath, ".xbmc/temp"); - if (getenv("XBMC_TEMP")) - strTempPath = getenv("XBMC_TEMP"); + strTempPath = URIUtils::AddFileToFolder(strTempPath, dotLowerAppName + "/temp"); + if (getenv(envAppTemp)) + strTempPath = getenv(envAppTemp); CSpecialProtocol::SetTempPath(strTempPath); URIUtils::AddSlashAtEnd(strTempPath); @@ -1116,18 +1136,18 @@ bool CApplication::InitDirectoriesLinux() } else { - URIUtils::AddSlashAtEnd(xbmcPath); - g_advancedSettings.m_logFolder = xbmcPath; + URIUtils::AddSlashAtEnd(appPath); + g_advancedSettings.m_logFolder = appPath; - CSpecialProtocol::SetXBMCBinPath(xbmcBinPath); - CSpecialProtocol::SetXBMCPath(xbmcPath); - CSpecialProtocol::SetHomePath(URIUtils::AddFileToFolder(xbmcPath, "portable_data")); - CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(xbmcPath, "portable_data/userdata")); + CSpecialProtocol::SetXBMCBinPath(appBinPath); + CSpecialProtocol::SetXBMCPath(appPath); + CSpecialProtocol::SetHomePath(URIUtils::AddFileToFolder(appPath, "portable_data")); + CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(appPath, "portable_data/userdata")); - CStdString strTempPath = xbmcPath; + CStdString strTempPath = appPath; strTempPath = URIUtils::AddFileToFolder(strTempPath, "portable_data/temp"); - if (getenv("XBMC_TEMP")) - strTempPath = getenv("XBMC_TEMP"); + if (getenv(envAppTemp)) + strTempPath = getenv(envAppTemp); CSpecialProtocol::SetTempPath(strTempPath); CreateUserDirs(); @@ -1150,19 +1170,19 @@ bool CApplication::InitDirectoriesOSX() else userName = "root"; - CStdString userHome; + std::string userHome; if (getenv("HOME")) userHome = getenv("HOME"); else userHome = "/root"; - CStdString xbmcPath; - CUtil::GetHomePath(xbmcPath); - setenv("XBMC_HOME", xbmcPath.c_str(), 0); + std::string appPath; + CUtil::GetHomePath(appPath); + setenv("APP_HOME", appPath.c_str(), 0); #if defined(TARGET_DARWIN_IOS) CStdString fontconfigPath; - fontconfigPath = xbmcPath + "/system/players/dvdplayer/etc/fonts/fonts.conf"; + fontconfigPath = appPath + "/system/players/dvdplayer/etc/fonts/fonts.conf"; setenv("FONTCONFIG_FILE", fontconfigPath.c_str(), 0); #endif @@ -1174,29 +1194,33 @@ bool CApplication::InitDirectoriesOSX() if (m_bPlatformDirectories) { // map our special drives - CSpecialProtocol::SetXBMCBinPath(xbmcPath); - CSpecialProtocol::SetXBMCPath(xbmcPath); + CSpecialProtocol::SetXBMCBinPath(appPath); + CSpecialProtocol::SetXBMCPath(appPath); #if defined(TARGET_DARWIN_IOS) - CSpecialProtocol::SetHomePath(userHome + "/" + CStdString(CDarwinUtils::GetAppRootFolder()) + "/XBMC"); - CSpecialProtocol::SetMasterProfilePath(userHome + "/" + CStdString(CDarwinUtils::GetAppRootFolder()) + "/XBMC/userdata"); + std::string appName = CCompileInfo::GetAppName(); + CSpecialProtocol::SetHomePath(userHome + "/" + CDarwinUtils::GetAppRootFolder() + "/" + appName); + CSpecialProtocol::SetMasterProfilePath(userHome + "/" + CDarwinUtils::GetAppRootFolder() + "/" + appName + "/userdata"); #else - CSpecialProtocol::SetHomePath(userHome + "/Library/Application Support/XBMC"); - CSpecialProtocol::SetMasterProfilePath(userHome + "/Library/Application Support/XBMC/userdata"); + std::string appName = CCompileInfo::GetAppName(); + CSpecialProtocol::SetHomePath(userHome + "/Library/Application Support/" + appName); + CSpecialProtocol::SetMasterProfilePath(userHome + "/Library/Application Support/" + appName + "/userdata"); #endif + std::string dotLowerAppName = "." + appName; + StringUtils::ToLower(dotLowerAppName); // location for temp files #if defined(TARGET_DARWIN_IOS) - CStdString strTempPath = URIUtils::AddFileToFolder(userHome, CStdString(CDarwinUtils::GetAppRootFolder()) + "/XBMC/temp"); + std::string strTempPath = URIUtils::AddFileToFolder(userHome, std::string(CDarwinUtils::GetAppRootFolder()) + "/" + appName + "/temp"); #else - CStdString strTempPath = URIUtils::AddFileToFolder(userHome, ".xbmc/"); + std::string strTempPath = URIUtils::AddFileToFolder(userHome, dotLowerAppName + "/"); CDirectory::Create(strTempPath); - strTempPath = URIUtils::AddFileToFolder(userHome, ".xbmc/temp"); + strTempPath = URIUtils::AddFileToFolder(userHome, dotLowerAppName + "/temp"); #endif CSpecialProtocol::SetTempPath(strTempPath); // xbmc.log file location #if defined(TARGET_DARWIN_IOS) - strTempPath = userHome + "/" + CStdString(CDarwinUtils::GetAppRootFolder()); + strTempPath = userHome + "/" + std::string(CDarwinUtils::GetAppRootFolder()); #else strTempPath = userHome + "/Library/Logs"; #endif @@ -1207,15 +1231,15 @@ bool CApplication::InitDirectoriesOSX() } else { - URIUtils::AddSlashAtEnd(xbmcPath); - g_advancedSettings.m_logFolder = xbmcPath; + URIUtils::AddSlashAtEnd(appPath); + g_advancedSettings.m_logFolder = appPath; - CSpecialProtocol::SetXBMCBinPath(xbmcPath); - CSpecialProtocol::SetXBMCPath(xbmcPath); - CSpecialProtocol::SetHomePath(URIUtils::AddFileToFolder(xbmcPath, "portable_data")); - CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(xbmcPath, "portable_data/userdata")); + CSpecialProtocol::SetXBMCBinPath(appPath); + CSpecialProtocol::SetXBMCPath(appPath); + CSpecialProtocol::SetHomePath(URIUtils::AddFileToFolder(appPath, "portable_data")); + CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(appPath, "portable_data/userdata")); - CStdString strTempPath = URIUtils::AddFileToFolder(xbmcPath, "portable_data/temp"); + CStdString strTempPath = URIUtils::AddFileToFolder(appPath, "portable_data/temp"); CSpecialProtocol::SetTempPath(strTempPath); URIUtils::AddSlashAtEnd(strTempPath); @@ -1234,7 +1258,7 @@ bool CApplication::InitDirectoriesWin32() CStdString xbmcPath; CUtil::GetHomePath(xbmcPath); - CEnvironment::setenv("XBMC_HOME", xbmcPath); + CEnvironment::setenv("APP_HOME", xbmcPath); CSpecialProtocol::SetXBMCBinPath(xbmcPath); CSpecialProtocol::SetXBMCPath(xbmcPath); @@ -1245,7 +1269,7 @@ bool CApplication::InitDirectoriesWin32() CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(strWin32UserFolder, "userdata")); CSpecialProtocol::SetTempPath(URIUtils::AddFileToFolder(strWin32UserFolder,"cache")); - CEnvironment::setenv("XBMC_PROFILE_USERDATA", CSpecialProtocol::TranslatePath("special://masterprofile/")); + CEnvironment::setenv("APP_PROFILE_USERDATA", CSpecialProtocol::TranslatePath("special://masterprofile/")); CreateUserDirs(); @@ -1508,6 +1532,9 @@ bool CApplication::Initialize() CPeripheralImon::GetCountOfImonsConflictWithDInput() == 0 ); #endif + // show info dialog about moved configuration files if needed + ShowAppMigrationMessage(); + return true; } @@ -2339,16 +2366,18 @@ bool CApplication::OnKey(const CKey& key) if (StringUtils::StartsWithNoCase(action.GetName(),"CECToggleState") || StringUtils::StartsWithNoCase(action.GetName(),"CECStandby")) { - bool ret = true; - - CLog::LogF(LOGDEBUG, "action %s [%d], toggling state of playing device", action.GetName().c_str(), action.GetID()); // do not wake up the screensaver right after switching off the playing device if (StringUtils::StartsWithNoCase(action.GetName(),"CECToggleState")) - ret = CApplicationMessenger::Get().CECToggleState(); + { + CLog::LogF(LOGDEBUG, "action %s [%d], toggling state of playing device", action.GetName().c_str(), action.GetID()); + if (!CApplicationMessenger::Get().CECToggleState()) + return true; + } else - ret = CApplicationMessenger::Get().CECStandby(); - if (!ret) /* display is switched off */ + { + CApplicationMessenger::Get().CECStandby(); return true; + } } ResetScreenSaver(); @@ -2923,9 +2952,10 @@ bool CApplication::ProcessGamepad(float frameTime) return false; int iWin = GetActiveWindowID(); - int bid = 0; + int keymapId, joyId; g_Joystick.Update(); - if (g_Joystick.GetButton(bid)) + std::string joyName; + if (g_Joystick.GetButton(joyName, joyId)) { // reset Idle Timer m_idleTimer.StartZero(); @@ -2933,36 +2963,33 @@ bool CApplication::ProcessGamepad(float frameTime) ResetScreenSaver(); if (WakeUpScreenSaverAndDPMS()) { - g_Joystick.Reset(true); + g_Joystick.Reset(); return true; } int actionID; CStdString actionName; bool fullrange; - if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, g_Joystick.GetJoystick().c_str(), bid, JACTIVE_BUTTON, actionID, actionName, fullrange)) + keymapId = joyId + 1; + if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, joyName, keymapId, JACTIVE_BUTTON, actionID, actionName, fullrange)) { CAction action(actionID, 1.0f, 0.0f, actionName); - g_Joystick.Reset(); g_Mouse.SetActive(false); return ExecuteInputAction(action); } - else - { - g_Joystick.Reset(); - } } - if (g_Joystick.GetAxis(bid)) + if (g_Joystick.GetAxis(joyName, joyId)) { - if (g_Joystick.GetAmount() < 0) + keymapId = joyId + 1; + if (g_Joystick.GetAmount(joyName, joyId) < 0) { - bid = -bid; + keymapId = -keymapId; } int actionID; CStdString actionName; bool fullrange; - if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, g_Joystick.GetJoystick().c_str(), bid, JACTIVE_AXIS, actionID, actionName, fullrange)) + if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, joyName, keymapId, JACTIVE_AXIS, actionID, actionName, fullrange)) { ResetScreenSaver(); if (WakeUpScreenSaverAndDPMS()) @@ -2970,19 +2997,16 @@ bool CApplication::ProcessGamepad(float frameTime) return true; } - CAction action(actionID, fullrange ? (g_Joystick.GetAmount() + 1.0f)/2.0f : fabs(g_Joystick.GetAmount()), 0.0f, actionName); - g_Joystick.Reset(); + float amount = g_Joystick.GetAmount(joyName, joyId); + CAction action(actionID, fullrange ? (amount + 1.0f)/2.0f : fabs(amount), 0.0f, actionName); g_Mouse.SetActive(false); return ExecuteInputAction(action); } - else - { - g_Joystick.ResetAxis(abs(bid)); - } } int position = 0; - if (g_Joystick.GetHat(bid, position)) + if (g_Joystick.GetHat(joyName, joyId, position)) { + keymapId = joyId + 1; // reset Idle Timer m_idleTimer.StartZero(); @@ -2997,12 +3021,11 @@ bool CApplication::ProcessGamepad(float frameTime) CStdString actionName; bool fullrange; - bid = position<<16|bid; + keymapId = position << 16 | keymapId; - if (bid && CButtonTranslator::GetInstance().TranslateJoystickString(iWin, g_Joystick.GetJoystick().c_str(), bid, JACTIVE_HAT, actionID, actionName, fullrange)) + if (keymapId && CButtonTranslator::GetInstance().TranslateJoystickString(iWin, joyName, keymapId, JACTIVE_HAT, actionID, actionName, fullrange)) { CAction action(actionID, 1.0f, 0.0f, actionName); - g_Joystick.Reset(); g_Mouse.SetActive(false); return ExecuteInputAction(action); } @@ -3211,9 +3234,6 @@ bool CApplication::ProcessJoystickEvent(const std::string& joystickName, int wKe if (WakeUpScreenSaverAndDPMS()) return true; -#ifdef HAS_SDL_JOYSTICK - g_Joystick.Reset(); -#endif g_Mouse.SetActive(false); int iWin = GetActiveWindowID(); @@ -3222,7 +3242,7 @@ bool CApplication::ProcessJoystickEvent(const std::string& joystickName, int wKe bool fullRange = false; // Translate using regular joystick translator. - if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, joystickName.c_str(), wKeyID, inputType, actionID, actionName, fullRange)) + if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, joystickName, wKeyID, inputType, actionID, actionName, fullRange)) return ExecuteInputAction( CAction(actionID, fAmount, 0.0f, actionName, holdTime) ); else CLog::Log(LOGDEBUG, "ERROR mapping joystick action. Joystick: %s %i",joystickName.c_str(), wKeyID); @@ -3574,9 +3594,7 @@ void CApplication::Stop(int exitCode) // so we may never get to Destroy() in CXBApplicationEx::Run(), we call it here. Destroy(); cleanup_emu_environ(); - CTimeUtils::Close(); - // Sleep(200); } @@ -4990,6 +5008,26 @@ bool CApplication::ExecuteXBMCAction(std::string actionStr) return true; } +// inform the user that the configuration data has moved from old XBMC location +// to new Kodi location - if applicable +void CApplication::ShowAppMigrationMessage() +{ + // .kodi_migration_complete will be created from the installer/packaging + // once an old XBMC configuration was moved to the new Kodi location + // if this is the case show the migration info to the user once which + // tells him to have a look into the wiki where the move of configuration + // is further explained. + if (CFile::Exists("special://home/.kodi_data_was_migrated") && + !CFile::Exists("special://home/.kodi_migration_info_shown")) + { + CGUIDialogOK::ShowAndGetInput(24128, 0, 24129, 0); + CFile tmpFile; + // create the file which will prevent this dialog from appearing in the future + tmpFile.OpenForWrite("special://home/.kodi_migration_info_shown"); + tmpFile.Close(); + } +} + void CApplication::Process() { MEASURE_FUNCTION; diff --git a/xbmc/Application.h b/xbmc/Application.h index 41578918b7..23fd4cfe17 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -198,6 +198,7 @@ public: void ActivateScreenSaver(bool forceType = false); void CloseNetworkShares(); + void ShowAppMigrationMessage(); virtual void Process(); void ProcessSlow(); void ResetScreenSaver(); diff --git a/xbmc/ApplicationMessenger.cpp b/xbmc/ApplicationMessenger.cpp index 5551f7a597..d22827378b 100644 --- a/xbmc/ApplicationMessenger.cpp +++ b/xbmc/ApplicationMessenger.cpp @@ -39,6 +39,7 @@ #include "guilib/GUIDialog.h" #include "guilib/Key.h" #include "guilib/GUIKeyboardFactory.h" +#include "guilib/Resolution.h" #include "GUIInfoManager.h" #include "utils/Splash.h" #include "cores/IPlayer.h" @@ -536,6 +537,14 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) g_application.SwitchToFullScreen(); break; + case TMSG_SETVIDEORESOLUTION: + { + RESOLUTION res = (RESOLUTION)pMsg->param1; + bool forceUpdate = pMsg->param2 == 1 ? true : false; + g_graphicsContext.SetVideoResolution(res, forceUpdate); + } + break; + case TMSG_TOGGLEFULLSCREEN: g_graphicsContext.Lock(); g_graphicsContext.ToggleFullScreenRoot(); @@ -834,12 +843,12 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) } case TMSG_CECACTIVATESOURCE: { - *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_ACTIVATE_SOURCE); + g_peripherals.ToggleDeviceState(STATE_ACTIVATE_SOURCE); break; } case TMSG_CECSTANDBY: { - *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_STANDBY); + g_peripherals.ToggleDeviceState(STATE_STANDBY); break; } case TMSG_START_ANDROID_ACTIVITY: @@ -1387,29 +1396,19 @@ bool CApplicationMessenger::CECToggleState() ThreadMessage tMsg = {TMSG_CECTOGGLESTATE}; tMsg.lpVoid = (void*)&result; - SendMessage(tMsg, false); + SendMessage(tMsg, true); return result; } -bool CApplicationMessenger::CECActivateSource() +void CApplicationMessenger::CECActivateSource() { - bool result; - ThreadMessage tMsg = {TMSG_CECACTIVATESOURCE}; - tMsg.lpVoid = (void*)&result; SendMessage(tMsg, false); - - return result; } -bool CApplicationMessenger::CECStandby() +void CApplicationMessenger::CECStandby() { - bool result; - ThreadMessage tMsg = {TMSG_CECSTANDBY}; - tMsg.lpVoid = (void*)&result; SendMessage(tMsg, false); - - return result; } diff --git a/xbmc/ApplicationMessenger.h b/xbmc/ApplicationMessenger.h index c4d4f38c6a..543e0654c8 100644 --- a/xbmc/ApplicationMessenger.h +++ b/xbmc/ApplicationMessenger.h @@ -91,6 +91,7 @@ namespace MUSIC_INFO #define TMSG_CECTOGGLESTATE 316 #define TMSG_CECACTIVATESOURCE 317 #define TMSG_CECSTANDBY 318 +#define TMSG_SETVIDEORESOLUTION 319 #define TMSG_NETWORKMESSAGE 500 @@ -218,8 +219,8 @@ public: void LoadProfile(unsigned int idx); bool CECToggleState(); - bool CECActivateSource(); - bool CECStandby(); + void CECActivateSource(); + void CECStandby(); CStdString GetResponse(); int SetResponse(CStdString response); diff --git a/xbmc/Autorun.cpp b/xbmc/Autorun.cpp index 533de8e0a9..dfe4cc0d23 100644 --- a/xbmc/Autorun.cpp +++ b/xbmc/Autorun.cpp @@ -351,7 +351,7 @@ bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAdded && (bypassSettings)) { bPlaying = true; - CStdString strExec = StringUtils::Format("XBMC.RecursiveSlideShow(%s)", pItem->GetPath().c_str()); + CStdString strExec = StringUtils::Format("RecursiveSlideShow(%s)", pItem->GetPath().c_str()); CBuiltins::Execute(strExec); return true; } @@ -428,7 +428,7 @@ bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAdded if (!pItem->m_bIsFolder && pItem->IsPicture()) { bPlaying = true; - CStdString strExec = StringUtils::Format("XBMC.RecursiveSlideShow(%s)", strDrive.c_str()); + CStdString strExec = StringUtils::Format("RecursiveSlideShow(%s)", strDrive.c_str()); CBuiltins::Execute(strExec); break; } diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index dcb31e7baf..30f95cefb5 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -1930,7 +1930,7 @@ CStdString CGUIInfoManager::GetLabel(int info, int contextWindow, std::string *f case SYSTEM_FRIENDLY_NAME: { CStdString friendlyName = CSettings::Get().GetString("services.devicename"); - if (friendlyName.Equals("XBMC")) + if (friendlyName.Equals(CCompileInfo::GetAppName())) strLabel = StringUtils::Format("%s (%s)", friendlyName.c_str(), g_application.getNetwork().GetHostName().c_str()); else strLabel = friendlyName; @@ -3723,37 +3723,31 @@ CStdString CGUIInfoManager::GetMusicTagLabel(int info, const CFileItem *item) return GetItemLabel(item, LISTITEM_DURATION); case MUSICPLAYER_CHANNEL_NAME: { - CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag(); - if (channeltag) - return channeltag->ChannelName(); + if (m_currentFile->HasPVRChannelInfoTag()) + return m_currentFile->GetPVRChannelInfoTag()->ChannelName(); } break; case MUSICPLAYER_CHANNEL_NUMBER: { - CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag(); - if (channeltag) - { - return StringUtils::Format("%i", channeltag->ChannelNumber()); - } + if (m_currentFile->HasPVRChannelInfoTag()) + return StringUtils::Format("%i", m_currentFile->GetPVRChannelInfoTag()->ChannelNumber()); } break; case MUSICPLAYER_SUB_CHANNEL_NUMBER: { - CPVRChannel* channel = m_currentFile->GetPVRChannelInfoTag(); - if (channel) - return StringUtils::Format("%i", channel->SubChannelNumber()); + if (m_currentFile->HasPVRChannelInfoTag()) + return StringUtils::Format("%i", m_currentFile->GetPVRChannelInfoTag()->SubChannelNumber()); } break; case MUSICPLAYER_CHANNEL_NUMBER_LBL: { - CPVRChannel* channel = m_currentFile->GetPVRChannelInfoTag(); - return channel ? channel->FormattedChannelNumber() : ""; + if (m_currentFile->HasPVRChannelInfoTag()) + return m_currentFile->GetPVRChannelInfoTag()->FormattedChannelNumber(); } break; case MUSICPLAYER_CHANNEL_GROUP: { - CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag(); - if (channeltag && channeltag->IsRadio()) + if (m_currentFile->HasPVRChannelInfoTag() && m_currentFile->GetPVRChannelInfoTag()->IsRadio()) return g_PVRManager.GetPlayingGroup(true)->GroupName(); } break; diff --git a/xbmc/PlayListPlayer.cpp b/xbmc/PlayListPlayer.cpp index dd635351ef..5f5955eeac 100644 --- a/xbmc/PlayListPlayer.cpp +++ b/xbmc/PlayListPlayer.cpp @@ -36,6 +36,7 @@ #include "guilib/LocalizeStrings.h" #include "interfaces/AnnouncementManager.h" #include "guilib/Key.h" +#include "URL.h" using namespace PLAYLIST; @@ -287,7 +288,7 @@ bool CPlayListPlayer::Play(int iSong, bool bAutoPlay /* = false */, bool bPlayPr return false; if (ret == PLAYBACK_FAIL) { - CLog::Log(LOGERROR,"Playlist Player: skipping unplayable item: %i, path [%s]", m_iCurrentSong, item->GetPath().c_str()); + CLog::Log(LOGERROR,"Playlist Player: skipping unplayable item: %i, path [%s]", m_iCurrentSong, CURL::GetRedacted(item->GetPath()).c_str()); playlist.SetUnPlayable(m_iCurrentSong); // abort on 100 failed CONSECTUTIVE songs diff --git a/xbmc/TextureCacheJob.cpp b/xbmc/TextureCacheJob.cpp index 2fdeef7b3a..fe0904d673 100644 --- a/xbmc/TextureCacheJob.cpp +++ b/xbmc/TextureCacheJob.cpp @@ -97,7 +97,7 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture) m_details.height = height; m_details.file = m_cachePath + ".jpg"; if (out_texture) - *out_texture = LoadImage(CTextureCache::GetCachedPath(m_details.file), width, height, additional_info); + *out_texture = LoadImage(CTextureCache::GetCachedPath(m_details.file), width, height, "" /* already flipped */); CLog::Log(LOGDEBUG, "Fast %s image '%s' to '%s': %p", m_oldHash.empty() ? "Caching" : "Recaching", image.c_str(), m_details.file.c_str(), out_texture); return true; } diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp index 0dcae79cc8..c35b4c1623 100644 --- a/xbmc/Util.cpp +++ b/xbmc/Util.cpp @@ -20,6 +20,7 @@ #include "network/Network.h" #include "threads/SystemClock.h" #include "system.h" +#include "CompileInfo.h" #if defined(TARGET_DARWIN) #include <sys/param.h> #include <mach-o/dyld.h> @@ -445,10 +446,12 @@ void CUtil::GetHomePath(std::string& strPath, const std::string& strTarget) given_path[n] = '\0'; #if defined(TARGET_DARWIN_IOS) - strcat(given_path, "/XBMCData/XBMCHome/"); + strcat(given_path, "/AppData/AppHome/"); #else // Assume local path inside application bundle. - strcat(given_path, "../Resources/XBMC/"); + strcat(given_path, "../Resources/"); + strcat(given_path, CCompileInfo::GetAppName()); + strcat(given_path, "/"); #endif // Convert to real path. @@ -468,12 +471,13 @@ void CUtil::GetHomePath(std::string& strPath, const std::string& strTarget) } #if defined(TARGET_POSIX) && !defined(TARGET_DARWIN) - /* Change strPath accordingly when target is XBMC_HOME and when INSTALL_PATH + /* Change strPath accordingly when target is APP_HOME and when INSTALL_PATH * and BIN_INSTALL_PATH differ */ std::string installPath = INSTALL_PATH; std::string binInstallPath = BIN_INSTALL_PATH; - if (!strTarget.compare("XBMC_HOME") && installPath.compare(binInstallPath)) + + if (!strTarget.compare("APP_HOME") && installPath.compare(binInstallPath)) { int pos = strPath.length() - binInstallPath.length(); CStdString tmp = strPath; @@ -575,12 +579,11 @@ CStdString CUtil::GetFileMD5(const CStdString& strPath) { XBMC::XBMC_MD5 md5; char temp[1024]; - int pos=0; - int read=1; - while (read > 0) + while (true) { - read = file.Read(temp,1024); - pos += read; + ssize_t read = file.Read(temp,1024); + if (read <= 0) + break; md5.append(temp,read); } result = md5.getDigest(); @@ -2020,7 +2023,7 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st if (URIUtils::HasExtension(strItem, sub_exts[i])) { vecSubtitles.push_back( items[j]->GetPath() ); - CLog::Log(LOGINFO, "%s: found subtitle file %s\n", __FUNCTION__, items[j]->GetPath().c_str() ); + CLog::Log(LOGINFO, "%s: found subtitle file %s\n", __FUNCTION__, CURL::GetRedacted(items[j]->GetPath()).c_str() ); } } } @@ -2056,7 +2059,7 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st strDest = StringUtils::Format("special://temp/subtitle.%s.%d.smi", TagConv.m_Langclass[k].Name.c_str(), i); if (CFile::Copy(vecSubtitles[i], strDest)) { - CLog::Log(LOGINFO, " cached subtitle %s->%s\n", vecSubtitles[i].c_str(), strDest.c_str()); + CLog::Log(LOGINFO, " cached subtitle %s->%s\n", CURL::GetRedacted(vecSubtitles[i]).c_str(), strDest.c_str()); vecSubtitles.push_back(strDest); } } @@ -2155,7 +2158,7 @@ void CUtil::GetExternalStreamDetailsFromFilename(const CStdString& strVideo, con else if (URIUtils::GetExtension(strStream) == ".sub" && URIUtils::IsInArchive(strStream)) { // exclude parsing of vobsub file names that embedded in an archive - CLog::Log(LOGDEBUG, "%s - skipping archived vobsub filename parsing: %s", __FUNCTION__, strStream.c_str()); + CLog::Log(LOGDEBUG, "%s - skipping archived vobsub filename parsing: %s", __FUNCTION__, CURL::GetRedacted(strStream).c_str()); toParse.clear(); } @@ -2213,7 +2216,8 @@ void CUtil::GetExternalStreamDetailsFromFilename(const CStdString& strVideo, con if (info.flag == 0) info.flag = CDemuxStream::FLAG_NONE; - CLog::Log(LOGDEBUG, "%s - Language = '%s' / Name = '%s' / Flag = '%u' from %s", __FUNCTION__, info.language.c_str(), info.name.c_str(), info.flag, strStream.c_str()); + CLog::Log(LOGDEBUG, "%s - Language = '%s' / Name = '%s' / Flag = '%u' from %s", + __FUNCTION__, info.language.c_str(), info.name.c_str(), info.flag, CURL::GetRedacted(strStream).c_str()); } /*! \brief in a vector of subtitles finds the corresponding .sub file for a given .idx file diff --git a/xbmc/Util.h b/xbmc/Util.h index 5e0226c860..9ca6f57701 100644 --- a/xbmc/Util.h +++ b/xbmc/Util.h @@ -73,7 +73,7 @@ public: static CStdString GetTitleFromPath(const CStdString& strFileNameAndPath, bool bIsFolder = false); static void GetQualifiedFilename(const std::string &strBasePath, std::string &strFilename); static void RunShortcut(const char* szPath); - static void GetHomePath(std::string& strPath, const std::string& strTarget = "XBMC_HOME"); + static void GetHomePath(std::string& strPath, const std::string& strTarget = "APP_HOME"); static bool IsPVR(const CStdString& strFile); static bool IsHTSP(const CStdString& strFile); static bool IsLiveTV(const CStdString& strFile); diff --git a/xbmc/addons/AddonCallbacks.h b/xbmc/addons/AddonCallbacks.h index 16b014707a..9ae3242a15 100644 --- a/xbmc/addons/AddonCallbacks.h +++ b/xbmc/addons/AddonCallbacks.h @@ -19,11 +19,19 @@ * */ +#include <stdint.h> #include "cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h" #include "addons/include/xbmc_pvr_types.h" #include "addons/include/xbmc_codec_types.h" #include "../../addons/library.xbmc.gui/libXBMC_gui.h" +#ifdef TARGET_WINDOWS +#ifndef _SSIZE_T_DEFINED +typedef intptr_t ssize_t; +#define _SSIZE_T_DEFINED +#endif // !_SSIZE_T_DEFINED +#endif // TARGET_WINDOWS + typedef void (*AddOnLogCallback)(void *addonData, const ADDON::addon_log_t loglevel, const char *msg); typedef void (*AddOnQueueNotification)(void *addonData, const ADDON::queue_msg_t type, const char *msg); typedef bool (*AddOnWakeOnLan)(const char* mac); @@ -35,9 +43,9 @@ typedef void (*AddOnFreeString)(const void* addonData, char* str); typedef void* (*AddOnOpenFile)(const void* addonData, const char* strFileName, unsigned int flags); typedef void* (*AddOnOpenFileForWrite)(const void* addonData, const char* strFileName, bool bOverWrite); -typedef unsigned int (*AddOnReadFile)(const void* addonData, void* file, void* lpBuf, int64_t uiBufSize); +typedef ssize_t (*AddOnReadFile)(const void* addonData, void* file, void* lpBuf, size_t uiBufSize); typedef bool (*AddOnReadFileString)(const void* addonData, void* file, char *szLine, int iLineLength); -typedef int (*AddOnWriteFile)(const void* addonData, void* file, const void* lpBuf, int64_t uiBufSize); +typedef ssize_t (*AddOnWriteFile)(const void* addonData, void* file, const void* lpBuf, size_t uiBufSize); typedef void (*AddOnFlushFile)(const void* addonData, void* file); typedef int64_t (*AddOnSeekFile)(const void* addonData, void* file, int64_t iFilePosition, int iWhence); typedef int (*AddOnTruncateFile)(const void* addonData, void* file, int64_t iSize); diff --git a/xbmc/addons/AddonCallbacksAddon.cpp b/xbmc/addons/AddonCallbacksAddon.cpp index 24450e9e9f..5824ce4201 100644 --- a/xbmc/addons/AddonCallbacksAddon.cpp +++ b/xbmc/addons/AddonCallbacksAddon.cpp @@ -328,7 +328,7 @@ void* CAddonCallbacksAddon::OpenFileForWrite(const void* addonData, const char* return NULL; } -unsigned int CAddonCallbacksAddon::ReadFile(const void* addonData, void* file, void* lpBuf, int64_t uiBufSize) +ssize_t CAddonCallbacksAddon::ReadFile(const void* addonData, void* file, void* lpBuf, size_t uiBufSize) { CAddonCallbacks* helper = (CAddonCallbacks*) addonData; if (!helper) @@ -354,7 +354,7 @@ bool CAddonCallbacksAddon::ReadFileString(const void* addonData, void* file, cha return cfile->ReadString(szLine, iLineLength); } -int CAddonCallbacksAddon::WriteFile(const void* addonData, void* file, const void* lpBuf, int64_t uiBufSize) +ssize_t CAddonCallbacksAddon::WriteFile(const void* addonData, void* file, const void* lpBuf, size_t uiBufSize) { CAddonCallbacks* helper = (CAddonCallbacks*) addonData; if (!helper) diff --git a/xbmc/addons/AddonCallbacksAddon.h b/xbmc/addons/AddonCallbacksAddon.h index 92022375af..6eed7cdbfd 100644 --- a/xbmc/addons/AddonCallbacksAddon.h +++ b/xbmc/addons/AddonCallbacksAddon.h @@ -47,9 +47,9 @@ public: // file operations static void* OpenFile(const void* addonData, const char* strFileName, unsigned int flags); static void* OpenFileForWrite(const void* addonData, const char* strFileName, bool bOverwrite); - static unsigned int ReadFile(const void* addonData, void* file, void* lpBuf, int64_t uiBufSize); + static ssize_t ReadFile(const void* addonData, void* file, void* lpBuf, size_t uiBufSize); static bool ReadFileString(const void* addonData, void* file, char *szLine, int iLineLength); - static int WriteFile(const void* addonData, void* file, const void* lpBuf, int64_t uiBufSize); + static ssize_t WriteFile(const void* addonData, void* file, const void* lpBuf, size_t uiBufSize); static void FlushFile(const void* addonData, void* file); static int64_t SeekFile(const void* addonData, void* file, int64_t iFilePosition, int iWhence); static int TruncateFile(const void* addonData, void* file, int64_t iSize); diff --git a/xbmc/addons/GUIWindowAddonBrowser.cpp b/xbmc/addons/GUIWindowAddonBrowser.cpp index df4b2b8186..547c871e48 100644 --- a/xbmc/addons/GUIWindowAddonBrowser.cpp +++ b/xbmc/addons/GUIWindowAddonBrowser.cpp @@ -148,9 +148,11 @@ bool CGUIWindowAddonBrowser::OnMessage(CGUIMessage& message) return CGUIMediaWindow::OnMessage(message); } -void CGUIWindowAddonBrowser::GetContextButtons(int itemNumber, - CContextButtons& buttons) +void CGUIWindowAddonBrowser::GetContextButtons(int itemNumber, CContextButtons& buttons) { + if (itemNumber < 0 || itemNumber >= m_vecItems->Size()) + return; + CFileItemPtr pItem = m_vecItems->Get(itemNumber); if (!pItem->IsPath("addons://enabled/")) buttons.Add(CONTEXT_BUTTON_SCAN,24034); diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp index 76d52487ad..4d22ce7a3c 100644 --- a/xbmc/addons/Scraper.cpp +++ b/xbmc/addons/Scraper.cpp @@ -388,7 +388,7 @@ bool CScraper::Load() } if (!result) - CLog::Log(LOGWARNING, "failed to load scraper XML"); + CLog::Log(LOGWARNING, "failed to load scraper XML from %s", LibPath().c_str()); return m_fLoaded = result; } diff --git a/xbmc/android/activity/XBMCApp.cpp b/xbmc/android/activity/XBMCApp.cpp index 6d4fb4ce0f..312620cae3 100644 --- a/xbmc/android/activity/XBMCApp.cpp +++ b/xbmc/android/activity/XBMCApp.cpp @@ -71,6 +71,7 @@ #include "android/jni/Cursor.h" #include "android/jni/ContentResolver.h" #include "android/jni/MediaStore.h" +#include "CompileInfo.h" #define GIGABYTES 1073741824 @@ -93,7 +94,7 @@ std::vector<androidPackage> CXBMCApp::m_applications; CXBMCApp::CXBMCApp(ANativeActivity* nativeActivity) : CJNIContext(nativeActivity) - , CJNIBroadcastReceiver("org/xbmc/xbmc/XBMCBroadcastReceiver") + , CJNIBroadcastReceiver("org/xbmc/kodi/XBMCBroadcastReceiver") , m_wakeLock(NULL) { m_activity = nativeActivity; @@ -251,7 +252,10 @@ bool CXBMCApp::getWakeLock() if (m_wakeLock) return true; - m_wakeLock = new CJNIWakeLock(CJNIPowerManager(getSystemService("power")).newWakeLock("org.xbmc.xbmc")); + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + std::string className = "org.xbmc." + appName; + m_wakeLock = new CJNIWakeLock(CJNIPowerManager(getSystemService("power")).newWakeLock(className.c_str())); return true; } @@ -266,7 +270,8 @@ void CXBMCApp::run() m_initialVolume = GetSystemVolume(); CJNIIntent startIntent = getIntent(); - android_printf("XBMC Started with action: %s\n",startIntent.getAction().c_str()); + + android_printf("%s Started with action: %s\n", CCompileInfo::GetAppName(), startIntent.getAction().c_str()); std::string filenameToPlay = GetFilenameFromIntent(startIntent); if (!filenameToPlay.empty()) @@ -274,7 +279,7 @@ void CXBMCApp::run() int argc = 2; const char** argv = (const char**) malloc(argc*sizeof(char*)); - std::string exe_name("XBMC"); + std::string exe_name(CCompileInfo::GetAppName()); argv[0] = exe_name.c_str(); argv[1] = filenameToPlay.c_str(); @@ -606,17 +611,21 @@ void CXBMCApp::SetupEnv() setenv("XBMC_ANDROID_LIBS", getApplicationInfo().nativeLibraryDir.c_str(), 0); setenv("XBMC_ANDROID_APK", getPackageResourcePath().c_str(), 0); + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + std::string className = "org.xbmc." + appName; + std::string xbmcHome = CJNISystem::getProperty("xbmc.home", ""); if (xbmcHome.empty()) { std::string cacheDir = getCacheDir().getAbsolutePath(); - setenv("XBMC_BIN_HOME", (cacheDir + "/apk/assets").c_str(), 0); - setenv("XBMC_HOME", (cacheDir + "/apk/assets").c_str(), 0); + setenv("APP_BIN_HOME", (cacheDir + "/apk/assets").c_str(), 0); + setenv("APP_HOME", (cacheDir + "/apk/assets").c_str(), 0); } else { - setenv("XBMC_BIN_HOME", (xbmcHome + "/assets").c_str(), 0); - setenv("XBMC_HOME", (xbmcHome + "/assets").c_str(), 0); + setenv("APP_BIN_HOME", (xbmcHome + "/assets").c_str(), 0); + setenv("APP_HOME", (xbmcHome + "/assets").c_str(), 0); } std::string externalDir = CJNISystem::getProperty("xbmc.data", ""); @@ -624,7 +633,7 @@ void CXBMCApp::SetupEnv() { CJNIFile androidPath = getExternalFilesDir(""); if (!androidPath) - androidPath = getDir("org.xbmc.xbmc", 1); + androidPath = getDir(className.c_str(), 1); if (androidPath) externalDir = androidPath.getAbsolutePath(); @@ -633,7 +642,7 @@ void CXBMCApp::SetupEnv() if (!externalDir.empty()) setenv("HOME", externalDir.c_str(), 0); else - setenv("HOME", getenv("XBMC_TEMP"), 0); + setenv("HOME", getenv("APP_TEMP"), 0); } std::string CXBMCApp::GetFilenameFromIntent(const CJNIIntent &intent) diff --git a/xbmc/android/activity/android_main.cpp b/xbmc/android/activity/android_main.cpp index 6ee97c2f7b..2db5916e0f 100644 --- a/xbmc/android/activity/android_main.cpp +++ b/xbmc/android/activity/android_main.cpp @@ -24,6 +24,8 @@ #include "EventLoop.h" #include "XBMCApp.h" #include "android/jni/SurfaceTexture.h" +#include "utils/StringUtils.h" +#include "CompileInfo.h" // copied from new android_native_app_glue.c static void process_input(struct android_app* app, struct android_poll_source* source) { @@ -82,7 +84,13 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) if (vm->GetEnv(reinterpret_cast<void**>(&env), version) != JNI_OK) return -1; - jclass cMain = env->FindClass("org/xbmc/xbmc/Main"); + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + std::string mainClass = "org/xbmc/" + appName + "/Main"; + std::string bcReceiver = "org/xbmc/" + appName + "/XBMCBroadcastReceiver"; + std::string frameListener = "org/xbmc/" + appName + "/XBMCOnFrameAvailableListener"; + + jclass cMain = env->FindClass(mainClass.c_str()); if(cMain) { JNINativeMethod mOnNewIntent = { @@ -93,7 +101,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) env->RegisterNatives(cMain, &mOnNewIntent, 1); } - jclass cBroadcastReceiver = env->FindClass("org/xbmc/xbmc/XBMCBroadcastReceiver"); + jclass cBroadcastReceiver = env->FindClass(bcReceiver.c_str()); if(cBroadcastReceiver) { JNINativeMethod mOnReceive = { @@ -104,7 +112,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) env->RegisterNatives(cBroadcastReceiver, &mOnReceive, 1); } - jclass cFrameAvailableListener = env->FindClass("org/xbmc/xbmc/XBMCOnFrameAvailableListener"); + jclass cFrameAvailableListener = env->FindClass(frameListener.c_str()); if(cFrameAvailableListener) { JNINativeMethod mOnFrameAvailable = { diff --git a/xbmc/android/jni/README b/xbmc/android/jni/README index 079af24ce8..8da8cddb1e 100644 --- a/xbmc/android/jni/README +++ b/xbmc/android/jni/README @@ -29,7 +29,7 @@ of one found in libcrystax. Thanks crystax! { // Find the launch intent for a package and start its activity CJNIPackageManager manager = getPackageManager(); - CJNIIntent intent = manager.getLaunchIntentForPackage("org.xbmc.xbmc"); + CJNIIntent intent = manager.getLaunchIntentForPackage("org.xbmc.kodi"); startActivity(sendIntent); } diff --git a/xbmc/android/jni/SurfaceTexture.cpp b/xbmc/android/jni/SurfaceTexture.cpp index a8c8e642d3..8a40597ea3 100644 --- a/xbmc/android/jni/SurfaceTexture.cpp +++ b/xbmc/android/jni/SurfaceTexture.cpp @@ -34,7 +34,7 @@ using namespace jni; CJNISurfaceTextureOnFrameAvailableListener* CJNISurfaceTextureOnFrameAvailableListener::m_listenerInstance(NULL); CJNISurfaceTextureOnFrameAvailableListener::CJNISurfaceTextureOnFrameAvailableListener() -: CJNIBase("org/xbmc/xbmc/XBMCOnFrameAvailableListener") +: CJNIBase("org/xbmc/kodi/XBMCOnFrameAvailableListener") { CJNIContext *appInstance = CJNIContext::GetAppInstance(); if (!appInstance) diff --git a/xbmc/android/loader/AndroidDyload.cpp b/xbmc/android/loader/AndroidDyload.cpp index 594562c22c..7e36d6fabe 100644 --- a/xbmc/android/loader/AndroidDyload.cpp +++ b/xbmc/android/loader/AndroidDyload.cpp @@ -8,6 +8,8 @@ #include <fcntl.h> #include "android/activity/XBMCApp.h" #include "AndroidDyload.h" +#include "utils/StringUtils.h" +#include "CompileInfo.h" using namespace std; //#define DEBUG_SPEW @@ -246,8 +248,11 @@ void* CAndroidDyload::Open_Internal(string filename, bool checkSystem) for (strings::iterator j = deps.begin(); j != deps.end(); ++j) { - // Don't traverse into libxbmc's deps, they're guaranteed to be loaded. - if (*j == "libxbmc.so") + std::string appName = CCompileInfo::GetAppName(); + std::string libName = "lib" + appName + ".so"; + StringUtils::ToLower(libName); + // Don't traverse into libkodi's deps, they're guaranteed to be loaded. + if (*j == libName.c_str()) continue; if (FindInDeps(*j)) diff --git a/xbmc/cdrip/CDDARipJob.cpp b/xbmc/cdrip/CDDARipJob.cpp index 87798ce377..8f404ee92e 100644 --- a/xbmc/cdrip/CDDARipJob.cpp +++ b/xbmc/cdrip/CDDARipJob.cpp @@ -23,6 +23,7 @@ #include "EncoderFFmpeg.h" #include "FileItem.h" #include "utils/log.h" +#include "utils/SystemInfo.h" #include "Util.h" #include "dialogs/GUIDialogExtendedProgressBar.h" #include "filesystem/File.h" @@ -161,7 +162,7 @@ int CCDDARipJob::RipChunk(CFile& reader, CEncoder* encoder, int& percent) int result = reader.Read(stream, 1024); // return if rip is done or on some kind of error - if (!result) + if (result <= 0) return 1; // encode data @@ -203,7 +204,7 @@ CEncoder* CCDDARipJob::SetupEncoder(CFile& reader) // we have to set the tags before we init the Encoder std::string strTrack = StringUtils::Format("%li", strtol(m_input.substr(13, m_input.size() - 13 - 5).c_str(),NULL,10)); - encoder->SetComment("Ripped with XBMC"); + encoder->SetComment(std::string("Ripped with ") + CSysInfo::GetAppName()); encoder->SetArtist(StringUtils::Join(m_tag.GetArtist(), g_advancedSettings.m_musicItemSeparator)); encoder->SetTitle(m_tag.GetTitle()); diff --git a/xbmc/cdrip/Encoder.cpp b/xbmc/cdrip/Encoder.cpp index dfb389aca0..c8bf472a6a 100644 --- a/xbmc/cdrip/Encoder.cpp +++ b/xbmc/cdrip/Encoder.cpp @@ -105,8 +105,8 @@ int CEncoder::FileWrite(const void *pBuffer, uint32_t iBytes) if (!m_file) return -1; - uint32_t dwBytesWritten = m_file->Write(pBuffer, iBytes); - if (!dwBytesWritten) + ssize_t dwBytesWritten = m_file->Write(pBuffer, iBytes); + if (dwBytesWritten <= 0) return -1; return dwBytesWritten; diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp index 911cd688fe..28508d7895 100644 --- a/xbmc/cdrip/EncoderFFmpeg.cpp +++ b/xbmc/cdrip/EncoderFFmpeg.cpp @@ -30,6 +30,7 @@ #include "filesystem/File.h" #include "utils/log.h" #include "settings/Settings.h" +#include "utils/SystemInfo.h" #include "utils/URIUtils.h" #include "addons/AddonManager.h" @@ -218,7 +219,7 @@ bool CEncoderFFmpeg::Init(audioenc_callbacks &callbacks) SetTag("genre" , m_strGenre); SetTag("title" , m_strTitle); SetTag("track" , m_strTrack); - SetTag("encoder" , "XBMC FFmpeg Encoder"); + SetTag("encoder" , CSysInfo::GetAppName() + " FFmpeg Encoder"); /* write the header */ if (avformat_write_header(m_Format, NULL) != 0) diff --git a/xbmc/cores/AudioEngine/AEFactory.cpp b/xbmc/cores/AudioEngine/AEFactory.cpp index ebc9c6e781..1ce8434349 100644 --- a/xbmc/cores/AudioEngine/AEFactory.cpp +++ b/xbmc/cores/AudioEngine/AEFactory.cpp @@ -328,6 +328,8 @@ void CAEFactory::SettingOptionsAudioQualityLevelsFiller(const CSetting *setting, list.push_back(std::make_pair(g_localizeStrings.Get(13508), AE_QUALITY_HIGH)); if(AE->SupportsQualityLevel(AE_QUALITY_REALLYHIGH)) list.push_back(std::make_pair(g_localizeStrings.Get(13509), AE_QUALITY_REALLYHIGH)); + if(AE->SupportsQualityLevel(AE_QUALITY_GPU)) + list.push_back(std::make_pair(g_localizeStrings.Get(38010), AE_QUALITY_GPU)); } void CAEFactory::SettingOptionsAudioStreamsilenceFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t, void *data) diff --git a/xbmc/cores/AudioEngine/AEResampleFactory.cpp b/xbmc/cores/AudioEngine/AEResampleFactory.cpp new file mode 100644 index 0000000000..c24d9b0a59 --- /dev/null +++ b/xbmc/cores/AudioEngine/AEResampleFactory.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "settings/Settings.h" +#include "AEResampleFactory.h" +#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h" +#if defined(TARGET_RASPBERRY_PI) + #include "cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h" +#endif + +namespace ActiveAE +{ + +IAEResample *CAEResampleFactory::Create() +{ +#if defined(TARGET_RASPBERRY_PI) + if (CSettings::Get().GetInt("audiooutput.processquality") == AE_QUALITY_GPU) + return new CActiveAEResamplePi(); +#endif + return new CActiveAEResampleFFMPEG(); +} + +} diff --git a/xbmc/cores/AudioEngine/AEResampleFactory.h b/xbmc/cores/AudioEngine/AEResampleFactory.h new file mode 100644 index 0000000000..10b551e126 --- /dev/null +++ b/xbmc/cores/AudioEngine/AEResampleFactory.h @@ -0,0 +1,35 @@ +#pragma once +/* + * Copyright (C) 2010-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "cores/AudioEngine/Interfaces/AEResample.h" + +class IAEResample; + +namespace ActiveAE +{ + +class CAEResampleFactory +{ +public: + static IAEResample *Create(); +}; + +} diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index 91da98587d..0e4d8dad6b 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -24,6 +24,7 @@ using namespace ActiveAE; #include "ActiveAESound.h" #include "ActiveAEStream.h" #include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/AudioEngine/AEResampleFactory.h" #include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" #include "settings/Settings.h" @@ -2269,6 +2270,10 @@ bool CActiveAE::SupportsQualityLevel(enum AEQuality level) { if (level == AE_QUALITY_LOW || level == AE_QUALITY_MID || level == AE_QUALITY_HIGH) return true; +#if defined(TARGET_RASPBERRY_PI) + if (level == AE_QUALITY_GPU) + return true; +#endif return false; } @@ -2671,14 +2676,14 @@ bool CActiveAE::ResampleSound(CActiveAESound *sound) orig_config = sound->GetSound(true)->config; - dst_config.channel_layout = CActiveAEResample::GetAVChannelLayout(m_internalFormat.m_channelLayout); + dst_config.channel_layout = CAEUtil::GetAVChannelLayout(m_internalFormat.m_channelLayout); dst_config.channels = m_internalFormat.m_channelLayout.Count(); dst_config.sample_rate = m_internalFormat.m_sampleRate; - dst_config.fmt = CActiveAEResample::GetAVSampleFormat(m_internalFormat.m_dataFormat); + dst_config.fmt = CAEUtil::GetAVSampleFormat(m_internalFormat.m_dataFormat); dst_config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_internalFormat.m_dataFormat); dst_config.dither_bits = CAEUtil::DataFormatToDitherBits(m_internalFormat.m_dataFormat); - CActiveAEResample *resampler = new CActiveAEResample(); + IAEResample *resampler = CAEResampleFactory::Create(); resampler->Init(dst_config.channel_layout, dst_config.channels, dst_config.sample_rate, diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h index de94850667..1d12c1b852 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h @@ -23,10 +23,12 @@ #include "threads/Thread.h" #include "ActiveAESink.h" -#include "ActiveAEResample.h" +#include "cores/AudioEngine/Interfaces/AEResample.h" #include "cores/AudioEngine/Interfaces/AEStream.h" #include "cores/AudioEngine/Interfaces/AESound.h" #include "cores/AudioEngine/AEFactory.h" +#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" + #include "guilib/DispResource.h" #include <queue> diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp index 9e834c6db1..e40ac2e206 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp @@ -22,6 +22,7 @@ #include "cores/AudioEngine/AEFactory.h" #include "cores/AudioEngine/Engines/ActiveAE/ActiveAE.h" #include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/AudioEngine/AEResampleFactory.h" using namespace ActiveAE; @@ -107,12 +108,12 @@ bool CActiveAEBufferPool::Create(unsigned int totaltime) { CSampleBuffer *buffer; SampleConfig config; - config.fmt = CActiveAEResample::GetAVSampleFormat(m_format.m_dataFormat); + config.fmt = CAEUtil::GetAVSampleFormat(m_format.m_dataFormat); config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat); config.dither_bits = CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat); config.channels = m_format.m_channelLayout.Count(); config.sample_rate = m_format.m_sampleRate; - config.channel_layout = CActiveAEResample::GetAVChannelLayout(m_format.m_channelLayout); + config.channel_layout = CAEUtil::GetAVChannelLayout(m_format.m_channelLayout); unsigned int time = 0; unsigned int buffertime = (m_format.m_frames*1000) / m_format.m_sampleRate; @@ -171,17 +172,17 @@ bool CActiveAEBufferPoolResample::Create(unsigned int totaltime, bool remap, boo m_inputFormat.m_dataFormat != m_format.m_dataFormat || m_changeResampler) { - m_resampler = new CActiveAEResample(); - m_resampler->Init(CActiveAEResample::GetAVChannelLayout(m_format.m_channelLayout), + m_resampler = CAEResampleFactory::Create(); + m_resampler->Init(CAEUtil::GetAVChannelLayout(m_format.m_channelLayout), m_format.m_channelLayout.Count(), m_format.m_sampleRate, - CActiveAEResample::GetAVSampleFormat(m_format.m_dataFormat), + CAEUtil::GetAVSampleFormat(m_format.m_dataFormat), CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat), CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat), - CActiveAEResample::GetAVChannelLayout(m_inputFormat.m_channelLayout), + CAEUtil::GetAVChannelLayout(m_inputFormat.m_channelLayout), m_inputFormat.m_channelLayout.Count(), m_inputFormat.m_sampleRate, - CActiveAEResample::GetAVSampleFormat(m_inputFormat.m_dataFormat), + CAEUtil::GetAVSampleFormat(m_inputFormat.m_dataFormat), CAEUtil::DataFormatToUsedBits(m_inputFormat.m_dataFormat), CAEUtil::DataFormatToDitherBits(m_inputFormat.m_dataFormat), upmix, @@ -199,17 +200,17 @@ void CActiveAEBufferPoolResample::ChangeResampler() { delete m_resampler; - m_resampler = new CActiveAEResample(); - m_resampler->Init(CActiveAEResample::GetAVChannelLayout(m_format.m_channelLayout), + m_resampler = CAEResampleFactory::Create(); + m_resampler->Init(CAEUtil::GetAVChannelLayout(m_format.m_channelLayout), m_format.m_channelLayout.Count(), m_format.m_sampleRate, - CActiveAEResample::GetAVSampleFormat(m_format.m_dataFormat), + CAEUtil::GetAVSampleFormat(m_format.m_dataFormat), CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat), CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat), - CActiveAEResample::GetAVChannelLayout(m_inputFormat.m_channelLayout), + CAEUtil::GetAVChannelLayout(m_inputFormat.m_channelLayout), m_inputFormat.m_channelLayout.Count(), m_inputFormat.m_sampleRate, - CActiveAEResample::GetAVSampleFormat(m_inputFormat.m_dataFormat), + CAEUtil::GetAVSampleFormat(m_inputFormat.m_dataFormat), CAEUtil::DataFormatToUsedBits(m_inputFormat.m_dataFormat), CAEUtil::DataFormatToDitherBits(m_inputFormat.m_dataFormat), m_stereoUpmix, diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h index b0912beea1..961db98dea 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h @@ -89,7 +89,7 @@ public: std::deque<CSampleBuffer*> m_freeSamples; }; -class CActiveAEResample; +class IAEResample; class CActiveAEBufferPoolResample : public CActiveAEBufferPool { @@ -105,7 +105,7 @@ public: std::deque<CSampleBuffer*> m_inputSamples; std::deque<CSampleBuffer*> m_outputSamples; CSampleBuffer *m_procSample; - CActiveAEResample *m_resampler; + IAEResample *m_resampler; uint8_t *m_planes[16]; bool m_fillPackets; bool m_drain; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp index d7e0e0fed8..26f0140440 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp @@ -18,7 +18,8 @@ * */ -#include "ActiveAEResample.h" +#include "cores/AudioEngine/Utils/AEUtil.h" +#include "ActiveAEResampleFFMPEG.h" #include "utils/log.h" extern "C" { @@ -29,19 +30,19 @@ extern "C" { using namespace ActiveAE; -CActiveAEResample::CActiveAEResample() +CActiveAEResampleFFMPEG::CActiveAEResampleFFMPEG() { m_pContext = NULL; m_loaded = true; } -CActiveAEResample::~CActiveAEResample() +CActiveAEResampleFFMPEG::~CActiveAEResampleFFMPEG() { if (m_pContext) swr_free(&m_pContext); } -bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) +bool CActiveAEResampleFFMPEG::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) { if (!m_loaded) return false; @@ -70,7 +71,7 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst if(!m_pContext) { - CLog::Log(LOGERROR, "CActiveAEResample::Init - create context failed"); + CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - create context failed"); return false; } @@ -115,7 +116,7 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst for (unsigned int out=0; out<remapLayout->Count(); out++) { m_dst_chan_layout += (uint64_t) (1 << out); - int idx = GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout); + int idx = CAEUtil::GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout); if (idx >= 0) { m_rematrix[out][idx] = 1.0; @@ -127,7 +128,7 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) { - CLog::Log(LOGERROR, "CActiveAEResample::Init - setting channel matrix failed"); + CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - setting channel matrix failed"); return false; } } @@ -165,20 +166,20 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) { - CLog::Log(LOGERROR, "CActiveAEResample::Init - setting channel matrix failed"); + CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - setting channel matrix failed"); return false; } } if(swr_init(m_pContext) < 0) { - CLog::Log(LOGERROR, "CActiveAEResample::Init - init resampler failed"); + CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - init resampler failed"); return false; } return true; } -int CActiveAEResample::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio) +int CActiveAEResampleFFMPEG::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio) { if (ratio != 1.0) { @@ -186,7 +187,7 @@ int CActiveAEResample::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t * (dst_samples*ratio-dst_samples)*m_dst_rate/m_src_rate, dst_samples*m_dst_rate/m_src_rate) < 0) { - CLog::Log(LOGERROR, "CActiveAEResample::Resample - set compensation failed"); + CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Resample - set compensation failed"); return 0; } } @@ -194,7 +195,7 @@ int CActiveAEResample::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t * int ret = swr_convert(m_pContext, dst_buffer, dst_samples, (const uint8_t**)src_buffer, src_samples); if (ret < 0) { - CLog::Log(LOGERROR, "CActiveAEResample::Resample - resample failed"); + CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Resample - resample failed"); return 0; } @@ -251,138 +252,28 @@ int CActiveAEResample::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t * return ret; } -int64_t CActiveAEResample::GetDelay(int64_t base) +int64_t CActiveAEResampleFFMPEG::GetDelay(int64_t base) { return swr_get_delay(m_pContext, base); } -int CActiveAEResample::GetBufferedSamples() +int CActiveAEResampleFFMPEG::GetBufferedSamples() { return av_rescale_rnd(swr_get_delay(m_pContext, m_src_rate), m_dst_rate, m_src_rate, AV_ROUND_UP); } -int CActiveAEResample::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) +int CActiveAEResampleFFMPEG::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) { return av_rescale_rnd(src_samples, dst_rate, src_rate, AV_ROUND_UP); } -int CActiveAEResample::GetSrcBufferSize(int samples) +int CActiveAEResampleFFMPEG::GetSrcBufferSize(int samples) { return av_samples_get_buffer_size(NULL, m_src_channels, samples, m_src_fmt, 1); } -int CActiveAEResample::GetDstBufferSize(int samples) +int CActiveAEResampleFFMPEG::GetDstBufferSize(int samples) { return av_samples_get_buffer_size(NULL, m_dst_channels, samples, m_dst_fmt, 1); } - -uint64_t CActiveAEResample::GetAVChannelLayout(CAEChannelInfo &info) -{ - uint64_t channelLayout = 0; - if (info.HasChannel(AE_CH_FL)) channelLayout |= AV_CH_FRONT_LEFT; - if (info.HasChannel(AE_CH_FR)) channelLayout |= AV_CH_FRONT_RIGHT; - if (info.HasChannel(AE_CH_FC)) channelLayout |= AV_CH_FRONT_CENTER; - if (info.HasChannel(AE_CH_LFE)) channelLayout |= AV_CH_LOW_FREQUENCY; - if (info.HasChannel(AE_CH_BL)) channelLayout |= AV_CH_BACK_LEFT; - if (info.HasChannel(AE_CH_BR)) channelLayout |= AV_CH_BACK_RIGHT; - if (info.HasChannel(AE_CH_FLOC)) channelLayout |= AV_CH_FRONT_LEFT_OF_CENTER; - if (info.HasChannel(AE_CH_FROC)) channelLayout |= AV_CH_FRONT_RIGHT_OF_CENTER; - if (info.HasChannel(AE_CH_BC)) channelLayout |= AV_CH_BACK_CENTER; - if (info.HasChannel(AE_CH_SL)) channelLayout |= AV_CH_SIDE_LEFT; - if (info.HasChannel(AE_CH_SR)) channelLayout |= AV_CH_SIDE_RIGHT; - if (info.HasChannel(AE_CH_TC)) channelLayout |= AV_CH_TOP_CENTER; - if (info.HasChannel(AE_CH_TFL)) channelLayout |= AV_CH_TOP_FRONT_LEFT; - if (info.HasChannel(AE_CH_TFC)) channelLayout |= AV_CH_TOP_FRONT_CENTER; - if (info.HasChannel(AE_CH_TFR)) channelLayout |= AV_CH_TOP_FRONT_RIGHT; - if (info.HasChannel(AE_CH_TBL)) channelLayout |= AV_CH_TOP_BACK_LEFT; - if (info.HasChannel(AE_CH_TBC)) channelLayout |= AV_CH_TOP_BACK_CENTER; - if (info.HasChannel(AE_CH_TBR)) channelLayout |= AV_CH_TOP_BACK_RIGHT; - - return channelLayout; -} - -//CAEChannelInfo CActiveAEResample::GetAEChannelLayout(uint64_t layout) -//{ -// CAEChannelInfo channelLayout; -// channelLayout.Reset(); -// -// if (layout & AV_CH_FRONT_LEFT ) channelLayout += AE_CH_FL ; -// if (layout & AV_CH_FRONT_RIGHT ) channelLayout += AE_CH_FR ; -// if (layout & AV_CH_FRONT_CENTER ) channelLayout += AE_CH_FC ; -// if (layout & AV_CH_LOW_FREQUENCY ) channelLayout += AE_CH_LFE ; -// if (layout & AV_CH_BACK_LEFT ) channelLayout += AE_CH_BL ; -// if (layout & AV_CH_BACK_RIGHT ) channelLayout += AE_CH_BR ; -// if (layout & AV_CH_FRONT_LEFT_OF_CENTER ) channelLayout += AE_CH_FLOC; -// if (layout & AV_CH_FRONT_RIGHT_OF_CENTER) channelLayout += AE_CH_FROC; -// if (layout & AV_CH_BACK_CENTER ) channelLayout += AE_CH_BC ; -// if (layout & AV_CH_SIDE_LEFT ) channelLayout += AE_CH_SL ; -// if (layout & AV_CH_SIDE_RIGHT ) channelLayout += AE_CH_SR ; -// if (layout & AV_CH_TOP_CENTER ) channelLayout += AE_CH_TC ; -// if (layout & AV_CH_TOP_FRONT_LEFT ) channelLayout += AE_CH_TFL ; -// if (layout & AV_CH_TOP_FRONT_CENTER ) channelLayout += AE_CH_TFC ; -// if (layout & AV_CH_TOP_FRONT_RIGHT ) channelLayout += AE_CH_TFR ; -// if (layout & AV_CH_TOP_BACK_LEFT ) channelLayout += AE_CH_BL ; -// if (layout & AV_CH_TOP_BACK_CENTER ) channelLayout += AE_CH_BC ; -// if (layout & AV_CH_TOP_BACK_RIGHT ) channelLayout += AE_CH_BR ; -// -// return channelLayout; -//} - -AVSampleFormat CActiveAEResample::GetAVSampleFormat(AEDataFormat format) -{ - if (format == AE_FMT_U8) return AV_SAMPLE_FMT_U8; - else if (format == AE_FMT_S16NE) return AV_SAMPLE_FMT_S16; - else if (format == AE_FMT_S32NE) return AV_SAMPLE_FMT_S32; - else if (format == AE_FMT_S24NE4) return AV_SAMPLE_FMT_S32; - else if (format == AE_FMT_S24NE4MSB)return AV_SAMPLE_FMT_S32; - else if (format == AE_FMT_S24NE3) return AV_SAMPLE_FMT_S32; - else if (format == AE_FMT_FLOAT) return AV_SAMPLE_FMT_FLT; - else if (format == AE_FMT_DOUBLE) return AV_SAMPLE_FMT_DBL; - - else if (format == AE_FMT_U8P) return AV_SAMPLE_FMT_U8P; - else if (format == AE_FMT_S16NEP) return AV_SAMPLE_FMT_S16P; - else if (format == AE_FMT_S32NEP) return AV_SAMPLE_FMT_S32P; - else if (format == AE_FMT_S24NE4P) return AV_SAMPLE_FMT_S32P; - else if (format == AE_FMT_S24NE4MSBP)return AV_SAMPLE_FMT_S32P; - else if (format == AE_FMT_S24NE3P) return AV_SAMPLE_FMT_S32P; - else if (format == AE_FMT_FLOATP) return AV_SAMPLE_FMT_FLTP; - else if (format == AE_FMT_DOUBLEP) return AV_SAMPLE_FMT_DBLP; - - if (AE_IS_PLANAR(format)) - return AV_SAMPLE_FMT_FLTP; - else - return AV_SAMPLE_FMT_FLT; -} - -uint64_t CActiveAEResample::GetAVChannel(enum AEChannel aechannel) -{ - switch (aechannel) - { - case AE_CH_FL: return AV_CH_FRONT_LEFT; - case AE_CH_FR: return AV_CH_FRONT_RIGHT; - case AE_CH_FC: return AV_CH_FRONT_CENTER; - case AE_CH_LFE: return AV_CH_LOW_FREQUENCY; - case AE_CH_BL: return AV_CH_BACK_LEFT; - case AE_CH_BR: return AV_CH_BACK_RIGHT; - case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER; - case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER; - case AE_CH_BC: return AV_CH_BACK_CENTER; - case AE_CH_SL: return AV_CH_SIDE_LEFT; - case AE_CH_SR: return AV_CH_SIDE_RIGHT; - case AE_CH_TC: return AV_CH_TOP_CENTER; - case AE_CH_TFL: return AV_CH_TOP_FRONT_LEFT; - case AE_CH_TFC: return AV_CH_TOP_FRONT_CENTER; - case AE_CH_TFR: return AV_CH_TOP_FRONT_RIGHT; - case AE_CH_TBL: return AV_CH_TOP_BACK_LEFT; - case AE_CH_TBC: return AV_CH_TOP_BACK_CENTER; - case AE_CH_TBR: return AV_CH_TOP_BACK_RIGHT; - default: - return 0; - } -} - -int CActiveAEResample::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout) -{ - return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); -} diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h index a471e02011..1b35f591d0 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h @@ -19,24 +19,24 @@ * */ -#include "cores/AudioEngine/Utils/AEChannelInfo.h" -#include "cores/AudioEngine/Utils/AEAudioFormat.h" -#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" #include "cores/AudioEngine/Interfaces/AE.h" +#include "cores/AudioEngine/Interfaces/AEResample.h" extern "C" { -#include "libavutil/avutil.h" -#include "libswresample/swresample.h" +#include "libavutil/samplefmt.h" } +struct SwrContext; + namespace ActiveAE { -class CActiveAEResample +class CActiveAEResampleFFMPEG : public IAEResample { public: - CActiveAEResample(); - virtual ~CActiveAEResample(); + const char *GetName() { return "ActiveAEResampleFFMPEG"; } + CActiveAEResampleFFMPEG(); + virtual ~CActiveAEResampleFFMPEG(); bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality); int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio); int64_t GetDelay(int64_t base); @@ -44,11 +44,6 @@ public: int CalcDstSampleCount(int src_samples, int dst_rate, int src_rate); int GetSrcBufferSize(int samples); int GetDstBufferSize(int samples); - static uint64_t GetAVChannelLayout(CAEChannelInfo &info); -// static CAEChannelInfo GetAEChannelLayout(uint64_t layout); - static AVSampleFormat GetAVSampleFormat(AEDataFormat format); - static uint64_t GetAVChannel(enum AEChannel aechannel); - int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout); protected: bool m_loaded; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp new file mode 100644 index 0000000000..6565cdb2fc --- /dev/null +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp @@ -0,0 +1,583 @@ +/* + * Copyright (C) 2010-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" + +#if defined(TARGET_RASPBERRY_PI) + +#include "cores/AudioEngine/Utils/AEUtil.h" +#include "ActiveAEResamplePi.h" +#include "settings/Settings.h" +#include "utils/log.h" +#include "linux/RBP.h" + +extern "C" { +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "libswresample/swresample.h" +} + +//#define DEBUG_VERBOSE + +#define CLASSNAME "CActiveAEResamplePi" + +#define BUFFERSIZE (32*1024*2*8) + +//#define BENCHMARKING +#ifdef BENCHMARKING +#define LOGTIMEINIT(f) \ + struct timespec now; \ + uint64_t Start, End; \ + clock_gettime(CLOCK_MONOTONIC, &now); \ + Start = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \ + const char *_filename = f; + +#define LOGTIME(n) \ + clock_gettime(CLOCK_MONOTONIC, &now); \ + End = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \ + CLog::Log(LOGNOTICE, "ActiveAE::%s %d - resample %s took %.0fms", __FUNCTION__, n, _filename, (End-Start)*1e-6); \ + Start=End; +#else +#define LOGTIMEINIT(f) +#define LOGTIME(n) +#endif + +using namespace ActiveAE; + +CActiveAEResamplePi::CActiveAEResamplePi() +{ + CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); + + m_Initialized = false; + m_encoded_buffer = NULL; + m_offset = 0; + m_ratio = 0.0; +} + +CActiveAEResamplePi::~CActiveAEResamplePi() +{ + CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); + DeInit(); +} + +void CActiveAEResamplePi::DeInit() +{ + CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__); + if (m_Initialized) + { + m_omx_mixer.FlushAll(); + m_omx_mixer.Deinitialize(); + m_Initialized = false; + } +} + +static int format_to_bits(AVSampleFormat fmt) +{ + switch (fmt) + { + case AV_SAMPLE_FMT_U8: + case AV_SAMPLE_FMT_U8P: + return 8; + case AV_SAMPLE_FMT_S16: + case AV_SAMPLE_FMT_S16P: + return 16; + case AV_SAMPLE_FMT_S32: + case AV_SAMPLE_FMT_S32P: + case AV_SAMPLE_FMT_FLT: + case AV_SAMPLE_FMT_FLTP: + return 32; + default: + assert(0); + } + return 0; +} + +bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) +{ + LOGTIMEINIT("x"); + + CLog::Log(LOGINFO, "%s::%s remap:%p chan:%d->%d rate:%d->%d format:%d->%d bits:%d->%d dither:%d->%d norm:%d upmix:%d", CLASSNAME, __func__, remapLayout, src_channels, dst_channels, src_rate, dst_rate, src_fmt, dst_fmt, src_bits, dst_bits, src_dither, dst_dither, normalize, upmix); + + if (!src_bits) + src_bits = format_to_bits(src_fmt); + if (!dst_bits) + dst_bits = format_to_bits(dst_fmt); + m_dst_chan_layout = dst_chan_layout; + m_dst_channels = dst_channels; + m_dst_rate = dst_rate; + m_dst_fmt = dst_fmt; + m_dst_bits = dst_bits; + m_dst_dither_bits = dst_dither; + m_src_chan_layout = src_chan_layout; + m_src_channels = src_channels; + m_src_rate = src_rate; + m_src_fmt = src_fmt; + m_src_bits = src_bits; + m_src_dither_bits = src_dither; + m_offset = 0; + + if (m_dst_chan_layout == 0) + m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); + if (m_src_chan_layout == 0) + m_src_chan_layout = av_get_default_channel_layout(m_src_channels); + + OMX_CONFIG_BRCMAUDIODOWNMIXCOEFFICIENTS8x8 mix; + OMX_INIT_STRUCTURE(mix); + + assert(sizeof(mix.coeff)/sizeof(mix.coeff[0]) == 64); + + LOGTIME(1); +// this code is just uses ffmpeg to produce the 8x8 mixing matrix +{ + // dummy sample rate and format, as we only care about channel mapping + SwrContext *m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, AV_SAMPLE_FMT_FLT, 48000, + m_src_chan_layout, AV_SAMPLE_FMT_FLT, 48000, 0, NULL); + if (!m_pContext) + { + CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - create context failed"); + return false; + } + // tell resampler to clamp float values + // not required for sink stage (remapLayout == true) + if (!remapLayout && normalize) + { + av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); + } + + if (remapLayout) + { + // one-to-one mapping of channels + // remapLayout is the layout of the sink, if the channel is in our src layout + // the channel is mapped by setting coef 1.0 + double m_rematrix[AE_CH_MAX][AE_CH_MAX]; + memset(m_rematrix, 0, sizeof(m_rematrix)); + m_dst_chan_layout = 0; + for (unsigned int out=0; out<remapLayout->Count(); out++) + { + m_dst_chan_layout += (uint64_t) (1 << out); + int idx = CAEUtil::GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout); + if (idx >= 0) + { + m_rematrix[out][idx] = 1.0; + } + } + + av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0); + av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0); + + if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) + { + CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - setting channel matrix failed"); + return false; + } + } + // stereo upmix + else if (upmix && m_src_channels == 2 && m_dst_channels > 2) + { + double m_rematrix[AE_CH_MAX][AE_CH_MAX]; + memset(m_rematrix, 0, sizeof(m_rematrix)); + for (int out=0; out<m_dst_channels; out++) + { + uint64_t out_chan = av_channel_layout_extract_channel(m_dst_chan_layout, out); + switch(out_chan) + { + case AV_CH_FRONT_LEFT: + case AV_CH_BACK_LEFT: + case AV_CH_SIDE_LEFT: + m_rematrix[out][0] = 1.0; + break; + case AV_CH_FRONT_RIGHT: + case AV_CH_BACK_RIGHT: + case AV_CH_SIDE_RIGHT: + m_rematrix[out][1] = 1.0; + break; + case AV_CH_FRONT_CENTER: + m_rematrix[out][0] = 0.5; + m_rematrix[out][1] = 0.5; + break; + case AV_CH_LOW_FREQUENCY: + m_rematrix[out][0] = 0.5; + m_rematrix[out][1] = 0.5; + break; + default: + break; + } + } + + if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) + { + CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - setting channel matrix failed"); + return false; + } + } + + if (swr_init(m_pContext) < 0) + { + CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - init resampler failed"); + return false; + } + + const int samples = 8; + uint8_t *output, *input; + av_samples_alloc(&output, NULL, m_dst_channels, samples, AV_SAMPLE_FMT_FLT, 1); + av_samples_alloc(&input , NULL, m_src_channels, samples, AV_SAMPLE_FMT_FLT, 1); + + // Produce "identity" samples + float *f = (float *)input; + for (int j=0; j < samples; j++) + for (int i=0; i < m_src_channels; i++) + *f++ = i == j ? 1.0f : 0.0f; + + int ret = swr_convert(m_pContext, &output, samples, (const uint8_t **)&input, samples); + if (ret < 0) + CLog::Log(LOGERROR, "CActiveAEResamplePi::Resample - resample failed"); + + f = (float *)output; + for (int j=0; j < samples; j++) + for (int i=0; i < m_dst_channels; i++) + mix.coeff[8*i+j] = *f++ * (1<<16); + + for (int j=0; j < 8; j++) + { + char s[128] = {}, *t=s; + for (int i=0; i < 8; i++) + t += sprintf(t, "% 6.2f ", mix.coeff[j*8+i] * (1.0/0x10000)); + CLog::Log(LOGINFO, "%s::%s %s", CLASSNAME, __func__, s); + } + av_freep(&input); + av_freep(&output); + swr_free(&m_pContext); +} + LOGTIME(2); + + // This may be called before Application calls g_RBP.Initialise, so call it here too + g_RBP.Initialize(); + + OMX_ERRORTYPE omx_err = OMX_ErrorNone; + + if (!m_omx_mixer.Initialize("OMX.broadcom.audio_mixer", OMX_IndexParamAudioInit)) + CLog::Log(LOGERROR, "%s::%s - m_omx_mixer.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + LOGTIME(3); + + if (CSettings::Get().GetBool("videoplayer.usedisplayasclock") && CSettings::Get().GetInt("videoplayer.synctype") == SYNC_RESAMPLE) + { + OMX_PARAM_U32TYPE scaleType; + OMX_INIT_STRUCTURE(scaleType); + + scaleType.nPortIndex = m_omx_mixer.GetInputPort(); + scaleType.nU32 = (1 << 16); + omx_err = m_omx_mixer.SetConfig(OMX_IndexParamBrcmTimeScale, &scaleType); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer Failed to set OMX_IndexParamBrcmTimeScale omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + m_ratio = 1.0; + } + // audio_mixer only supports up to 192kHz, however as long as ratio of samplerates remains the same we can lie + while (src_rate > 192000 || dst_rate > 192000) + src_rate >>= 1, dst_rate >>= 1; + + OMX_INIT_STRUCTURE(m_pcm_input); + m_pcm_input.nPortIndex = m_omx_mixer.GetInputPort(); + m_pcm_input.eNumData = OMX_NumericalDataSigned; + m_pcm_input.eEndian = OMX_EndianLittle; + m_pcm_input.bInterleaved = OMX_TRUE; + m_pcm_input.nBitPerSample = m_src_bits; + // 0x8000 = float, 0x10000 = planar + uint32_t flags = 0; + if (m_src_fmt == AV_SAMPLE_FMT_FLT || m_src_fmt == AV_SAMPLE_FMT_FLTP) + flags |= 0x8000; + if (m_src_fmt >= AV_SAMPLE_FMT_U8P) + flags |= 0x10000; + m_pcm_input.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags; + m_pcm_input.nChannels = src_channels; + m_pcm_input.nSamplingRate = src_rate; + + omx_err = m_omx_mixer.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer in SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + OMX_INIT_STRUCTURE(m_pcm_output); + m_pcm_output.nPortIndex = m_omx_mixer.GetOutputPort(); + m_pcm_output.eNumData = OMX_NumericalDataSigned; + m_pcm_output.eEndian = OMX_EndianLittle; + m_pcm_output.bInterleaved = OMX_TRUE; + m_pcm_output.nBitPerSample = m_dst_bits; + flags = 0; + if (m_dst_fmt == AV_SAMPLE_FMT_FLT || m_dst_fmt == AV_SAMPLE_FMT_FLTP) + flags |= 0x8000; + if (m_dst_fmt >= AV_SAMPLE_FMT_U8P) + flags |= 0x10000; + m_pcm_output.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags; + m_pcm_output.nChannels = dst_channels; + m_pcm_output.nSamplingRate = dst_rate; + + omx_err = m_omx_mixer.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer out SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + LOGTIME(4); + + mix.nPortIndex = m_omx_mixer.GetInputPort(); + omx_err = m_omx_mixer.SetConfig(OMX_IndexConfigBrcmAudioDownmixCoefficients8x8, &mix); + if (omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "%s::%s - error setting mixer OMX_IndexConfigBrcmAudioDownmixCoefficients, error 0x%08x\n", + CLASSNAME, __func__, omx_err); + return false; + } + + // set up the number/size of buffers for decoder input + OMX_PARAM_PORTDEFINITIONTYPE port_param; + OMX_INIT_STRUCTURE(port_param); + port_param.nPortIndex = m_omx_mixer.GetInputPort(); + + omx_err = m_omx_mixer.GetParameter(OMX_IndexParamPortDefinition, &port_param); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)1); + port_param.nBufferSize = BUFFERSIZE; + + omx_err = m_omx_mixer.SetParameter(OMX_IndexParamPortDefinition, &port_param); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + LOGTIME(5); + + omx_err = m_omx_mixer.AllocInputBuffers(); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err); + + LOGTIME(6); + + // set up the number/size of buffers for decoder output + OMX_INIT_STRUCTURE(port_param); + port_param.nPortIndex = m_omx_mixer.GetOutputPort(); + + omx_err = m_omx_mixer.GetParameter(OMX_IndexParamPortDefinition, &port_param); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)1); + port_param.nBufferSize = BUFFERSIZE; + + omx_err = m_omx_mixer.SetParameter(OMX_IndexParamPortDefinition, &port_param); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + LOGTIME(7); + + omx_err = m_omx_mixer.AllocOutputBuffers(); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err); + + LOGTIME(8); + + omx_err = m_omx_mixer.SetStateForComponent(OMX_StateExecuting); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - m_omx_mixer OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + LOGTIME(9); + + m_Initialized = true; + + return true; +} + + +static void copy_planes(uint8_t **dst_buffer, int d_pitch, int d_planes, int d_samplesize, int offset, uint8_t *src_buffer, int src_samples, int planesize) +{ + for (int i=0; i < d_planes; i++) + memcpy(dst_buffer[i] + offset * d_pitch, src_buffer + i * planesize, src_samples * d_samplesize / d_planes); +} + +int CActiveAEResamplePi::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio) +{ + #ifdef DEBUG_VERBOSE + CLog::Log(LOGINFO, "%s::%s samples:%d->%d (%.2f)", CLASSNAME, __func__, src_samples, dst_samples, ratio); + #endif + if (!m_Initialized) + return 0; + OMX_ERRORTYPE omx_err = OMX_ErrorNone; + + if (m_ratio != 0.0 && ratio != m_ratio) + { + OMX_PARAM_U32TYPE scaleType; + OMX_INIT_STRUCTURE(scaleType); + + scaleType.nPortIndex = m_omx_mixer.GetInputPort(); + scaleType.nU32 = (1 << 16) / ratio; + omx_err = m_omx_mixer.SetConfig(OMX_IndexParamBrcmTimeScale, &scaleType); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer Failed to set OMX_IndexParamBrcmTimeScale omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + m_ratio = ratio; + } + + const int s_planes = m_src_fmt >= AV_SAMPLE_FMT_U8P ? m_src_channels : 1; + const int d_planes = m_dst_fmt >= AV_SAMPLE_FMT_U8P ? m_dst_channels : 1; + const int s_chans = m_src_fmt >= AV_SAMPLE_FMT_U8P ? 1 : m_src_channels; + const int d_chans = m_dst_fmt >= AV_SAMPLE_FMT_U8P ? 1 : m_dst_channels; + const int s_pitch = s_chans * m_src_bits >> 3; + const int d_pitch = d_chans * m_dst_bits >> 3; + + const int s_samplesize = m_src_channels * m_src_bits >> 3; + const int d_samplesize = m_dst_channels * m_dst_bits >> 3; + const int max_src_samples = BUFFERSIZE / s_samplesize; + const int max_dst_samples = (long long)(BUFFERSIZE / d_samplesize) * m_src_rate / (m_dst_rate + m_src_rate-1); + + int sent = 0; + int received = 0; + + while (1) + { + if (m_encoded_buffer && m_encoded_buffer->nFilledLen) + { + int samples_available = m_encoded_buffer->nFilledLen / d_samplesize - m_offset; + int samples = std::min(samples_available, dst_samples - received); + copy_planes(dst_buffer, d_pitch, d_planes, d_samplesize, received, (uint8_t *)m_encoded_buffer->pBuffer + m_offset * d_pitch, samples, m_encoded_buffer->nFilledLen / d_planes); + received += samples; + m_offset += samples; + if (m_offset == m_encoded_buffer->nFilledLen / d_samplesize) + { + m_offset = 0; + m_encoded_buffer = NULL; + } + else if (m_offset > m_encoded_buffer->nFilledLen / d_samplesize) assert(0); + else assert(sent == src_samples); + } + + if (sent >= src_samples) + break; + + OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_mixer.GetInputBuffer(1000); + if (omx_buffer == NULL) + { + CLog::Log(LOGERROR, "%s::%s m_omx_mixer.GetInputBuffer failed to get buffer", CLASSNAME, __func__); + return false; + } + int send = std::min(std::min(max_dst_samples, max_src_samples), src_samples - sent); + + omx_buffer->nOffset = 0; + omx_buffer->nFlags = OMX_BUFFERFLAG_EOS; + omx_buffer->nFilledLen = send * s_samplesize; + + assert(omx_buffer->nFilledLen > 0 && omx_buffer->nFilledLen <= omx_buffer->nAllocLen); + + if (omx_buffer->nFilledLen) + { + int planesize = omx_buffer->nFilledLen / s_planes; + for (int i=0; i < s_planes; i++) + memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, src_buffer[i] + sent * s_pitch, planesize); + sent += send; + } + + omx_err = m_omx_mixer.EmptyThisBuffer(omx_buffer); + if (omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "%s::%s OMX_EmptyThisBuffer() failed with result(0x%x)", CLASSNAME, __func__, omx_err); + return false; + } + + m_encoded_buffer = m_omx_mixer.GetOutputBuffer(); + + if (!m_encoded_buffer) + { + CLog::Log(LOGERROR, "%s::%s no output buffer", CLASSNAME, __func__); + return false; + } + omx_err = m_omx_mixer.FillThisBuffer(m_encoded_buffer); + if (omx_err != OMX_ErrorNone) + return false; + + omx_err = m_omx_mixer.WaitForOutputDone(1000); + if (omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "%s::%s m_omx_mixer.WaitForOutputDone result(0x%x)", CLASSNAME, __func__, omx_err); + return false; + } + assert(m_encoded_buffer->nFilledLen > 0 && m_encoded_buffer->nFilledLen <= m_encoded_buffer->nAllocLen); + + if (m_omx_mixer.BadState()) + { + CLog::Log(LOGERROR, "%s::%s m_omx_mixer.BadState", CLASSNAME, __func__); + return false; + } + if (sent < src_samples) + CLog::Log(LOGERROR, "%s::%s More data to send %d/%d", CLASSNAME, __func__, sent, src_samples); + } + #ifdef DEBUG_VERBOSE + CLog::Log(LOGINFO, "%s::%s format:%d->%d rate:%d->%d chan:%d->%d samples %d->%d (%f) %d", CLASSNAME, __func__, + (int)m_src_fmt, (int)m_dst_fmt, m_src_rate, m_dst_rate, m_src_channels, m_dst_channels, src_samples, dst_samples, ratio, m_Initialized, received); + #endif + assert(received <= dst_samples); + return received; +} + +int64_t CActiveAEResamplePi::GetDelay(int64_t base) +{ + int ret = m_dst_rate ? 1000 * GetBufferedSamples() / m_dst_rate : 0; + #ifdef DEBUG_VERBOSE + CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); + #endif + return ret; +} + +int CActiveAEResamplePi::GetBufferedSamples() +{ + int samples = 0; + if (m_encoded_buffer) + { + const int d_samplesize = m_dst_channels * m_dst_bits >> 3; + samples = m_encoded_buffer->nFilledLen / d_samplesize - m_offset; + } + #ifdef DEBUG_VERBOSE + CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, samples); + #endif + return samples; +} + +int CActiveAEResamplePi::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) +{ + int ret = ((long long)src_samples * dst_rate + src_rate-1) / src_rate; + #ifdef DEBUG_VERBOSE + CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); + #endif + return ret; +} + +int CActiveAEResamplePi::GetSrcBufferSize(int samples) +{ + int ret = 0; + #ifdef DEBUG_VERBOSE + CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); + #endif + return ret; +} + +int CActiveAEResamplePi::GetDstBufferSize(int samples) +{ + int ret = CalcDstSampleCount(samples, m_dst_rate, m_src_rate); + #ifdef DEBUG_VERBOSE + CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); + #endif + return ret; +} + +#endif diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h new file mode 100644 index 0000000000..5c5f9ce1bd --- /dev/null +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h @@ -0,0 +1,60 @@ +#pragma once +/* + * Copyright (C) 2010-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "cores/AudioEngine/Interfaces/AEResample.h" +#include "linux/OMXCore.h" + +namespace ActiveAE +{ + +class CActiveAEResamplePi : public IAEResample +{ +public: + const char *GetName() { return "ActiveAEResamplePi"; } + CActiveAEResamplePi(); + virtual ~CActiveAEResamplePi(); + bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality); + int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio); + int64_t GetDelay(int64_t base); + int GetBufferedSamples(); + int CalcDstSampleCount(int src_samples, int dst_rate, int src_rate); + int GetSrcBufferSize(int samples); + int GetDstBufferSize(int samples); + +protected: + void DeInit(); + uint64_t m_src_chan_layout, m_dst_chan_layout; + int m_src_rate, m_dst_rate; + int m_src_channels, m_dst_channels; + AVSampleFormat m_src_fmt, m_dst_fmt; + int m_src_bits, m_dst_bits; + int m_src_dither_bits, m_dst_dither_bits; + + OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_input; + OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_output; + COMXCoreComponent m_omx_mixer; + bool m_Initialized; + OMX_BUFFERHEADERTYPE *m_encoded_buffer; + unsigned int m_offset; + double m_ratio; +}; + +} diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp index 488a0df38f..c6272cceab 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp @@ -24,6 +24,7 @@ #include "cores/AudioEngine/Utils/AEUtil.h" #include "utils/EndianSwap.h" #include "ActiveAE.h" +#include "cores/AudioEngine/AEResampleFactory.h" #include "settings/Settings.h" @@ -754,10 +755,10 @@ void CActiveAESink::OpenSink() // init sample of silence SampleConfig config; - config.fmt = CActiveAEResample::GetAVSampleFormat(m_sinkFormat.m_dataFormat); + config.fmt = CAEUtil::GetAVSampleFormat(m_sinkFormat.m_dataFormat); config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_sinkFormat.m_dataFormat); config.dither_bits = CAEUtil::DataFormatToDitherBits(m_sinkFormat.m_dataFormat); - config.channel_layout = CActiveAEResample::GetAVChannelLayout(m_sinkFormat.m_channelLayout); + config.channel_layout = CAEUtil::GetAVChannelLayout(m_sinkFormat.m_channelLayout); config.channels = m_sinkFormat.m_channelLayout.Count(); config.sample_rate = m_sinkFormat.m_sampleRate; @@ -889,8 +890,8 @@ void CActiveAESink::GenerateNoise() } SampleConfig config = m_sampleOfSilence.pkt->config; - CActiveAEResample resampler; - resampler.Init(config.channel_layout, + IAEResample *resampler = CAEResampleFactory::Create(); + resampler->Init(config.channel_layout, config.channels, config.sample_rate, config.fmt, @@ -903,10 +904,11 @@ void CActiveAESink::GenerateNoise() CAEUtil::DataFormatToUsedBits(m_sinkFormat.m_dataFormat), CAEUtil::DataFormatToDitherBits(m_sinkFormat.m_dataFormat), false, false, NULL, AE_QUALITY_UNKNOWN); - resampler.Resample(m_sampleOfSilence.pkt->data, m_sampleOfSilence.pkt->max_nb_samples, + resampler->Resample(m_sampleOfSilence.pkt->data, m_sampleOfSilence.pkt->max_nb_samples, (uint8_t**)&noise, m_sampleOfSilence.pkt->max_nb_samples, 1.0); _aligned_free(noise); + delete resampler; } void CActiveAESink::SetSilenceTimer() diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h index 0650a70611..6edfe111b4 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h @@ -25,7 +25,8 @@ #include "cores/AudioEngine/Interfaces/AE.h" #include "cores/AudioEngine/Interfaces/AESink.h" #include "cores/AudioEngine/AESinkFactory.h" -#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h" +#include "cores/AudioEngine/Interfaces/AEResample.h" +#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" namespace ActiveAE { diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h index 01aafe36c4..53823feec3 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h @@ -20,7 +20,6 @@ */ #include "cores/AudioEngine/Interfaces/AESound.h" -#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h" #include "filesystem/File.h" class DllAvUtil; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp index 7acc0d0b69..96bce120f6 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp @@ -25,6 +25,7 @@ #include "cores/AudioEngine/AEFactory.h" #include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/AudioEngine/AEResampleFactory.h" #include "ActiveAE.h" #include "ActiveAEStream.h" @@ -94,7 +95,7 @@ void CActiveAEStream::InitRemapper() for(unsigned int i=0; i<m_format.m_channelLayout.Count(); i++) { avLast = avCur; - avCur = CActiveAEResample::GetAVChannel(m_format.m_channelLayout[i]); + avCur = CAEUtil::GetAVChannel(m_format.m_channelLayout[i]); if(avCur < avLast) { needRemap = true; @@ -106,8 +107,8 @@ void CActiveAEStream::InitRemapper() { CLog::Log(LOGDEBUG, "CActiveAEStream::%s - initialize remapper", __FUNCTION__); - m_remapper = new CActiveAEResample(); - uint64_t avLayout = CActiveAEResample::GetAVChannelLayout(m_format.m_channelLayout); + m_remapper = CAEResampleFactory::Create(); + uint64_t avLayout = CAEUtil::GetAVChannelLayout(m_format.m_channelLayout); // build layout according to ffmpeg channel order // we need this for reference @@ -118,7 +119,7 @@ void CActiveAEStream::InitRemapper() { for(unsigned int j=0; j<m_format.m_channelLayout.Count(); j++) { - idx = m_remapper->GetAVChannelIndex(m_format.m_channelLayout[j], avLayout); + idx = CAEUtil::GetAVChannelIndex(m_format.m_channelLayout[j], avLayout); if (idx == (int)i) { ffmpegLayout += m_format.m_channelLayout[j]; @@ -134,7 +135,7 @@ void CActiveAEStream::InitRemapper() { for(unsigned int j=0; j<m_format.m_channelLayout.Count(); j++) { - idx = m_remapper->GetAVChannelIndex(m_format.m_channelLayout[j], avLayout); + idx = CAEUtil::GetAVChannelIndex(m_format.m_channelLayout[j], avLayout); if (idx == (int)i) { remapLayout += ffmpegLayout[j]; @@ -147,13 +148,13 @@ void CActiveAEStream::InitRemapper() m_remapper->Init(avLayout, m_format.m_channelLayout.Count(), m_format.m_sampleRate, - CActiveAEResample::GetAVSampleFormat(m_format.m_dataFormat), + CAEUtil::GetAVSampleFormat(m_format.m_dataFormat), CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat), CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat), avLayout, m_format.m_channelLayout.Count(), m_format.m_sampleRate, - CActiveAEResample::GetAVSampleFormat(m_format.m_dataFormat), + CAEUtil::GetAVSampleFormat(m_format.m_dataFormat), CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat), CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat), false, diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h index 70e8107ffd..09fda0fadc 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h @@ -98,7 +98,7 @@ protected: int m_leftoverBytes; CSampleBuffer *m_currentBuffer; CSoundPacket *m_remapBuffer; - CActiveAEResample *m_remapper; + IAEResample *m_remapper; int m_clockId; // only accessed by engine diff --git a/xbmc/cores/AudioEngine/Interfaces/AE.h b/xbmc/cores/AudioEngine/Interfaces/AE.h index 353fcaa543..c66fa616a0 100644 --- a/xbmc/cores/AudioEngine/Interfaces/AE.h +++ b/xbmc/cores/AudioEngine/Interfaces/AE.h @@ -58,8 +58,9 @@ enum AEQuality AE_QUALITY_HIGH = 50, /* Best sound processing quality */ /* Optional quality levels */ - AE_QUALITY_REALLYHIGH = 100 /* Uncompromised optional quality level, + AE_QUALITY_REALLYHIGH = 100, /* Uncompromised optional quality level, usually with unmeasurable and unnoticeable improvement */ + AE_QUALITY_GPU = 101, /* GPU acceleration */ }; /** diff --git a/xbmc/cores/AudioEngine/Interfaces/AEResample.h b/xbmc/cores/AudioEngine/Interfaces/AEResample.h new file mode 100644 index 0000000000..cef43dee17 --- /dev/null +++ b/xbmc/cores/AudioEngine/Interfaces/AEResample.h @@ -0,0 +1,47 @@ +#pragma once +/* + * Copyright (C) 2010-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "cores/AudioEngine/Interfaces/AE.h" + +extern "C" { +#include "libavutil/samplefmt.h" +} + +namespace ActiveAE +{ + +class IAEResample +{ +public: + /* return the name of this sync for logging */ + virtual const char *GetName() = 0; + IAEResample() {} + virtual ~IAEResample() {} + virtual bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) = 0; + virtual int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio) = 0; + virtual int64_t GetDelay(int64_t base) = 0; + virtual int GetBufferedSamples() = 0; + virtual int CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) = 0; + virtual int GetSrcBufferSize(int samples) = 0; + virtual int GetDstBufferSize(int samples) = 0; +}; + +} diff --git a/xbmc/cores/AudioEngine/Makefile.in b/xbmc/cores/AudioEngine/Makefile.in index 581249ee59..efb44cc387 100644 --- a/xbmc/cores/AudioEngine/Makefile.in +++ b/xbmc/cores/AudioEngine/Makefile.in @@ -26,11 +26,14 @@ SRCS += Sinks/AESinkProfiler.cpp SRCS += Sinks/AESinkPi.cpp +SRCS += AEResampleFactory.cpp + SRCS += Engines/ActiveAE/ActiveAE.cpp SRCS += Engines/ActiveAE/ActiveAESink.cpp SRCS += Engines/ActiveAE/ActiveAEStream.cpp SRCS += Engines/ActiveAE/ActiveAESound.cpp -SRCS += Engines/ActiveAE/ActiveAEResample.cpp +SRCS += Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp +SRCS += Engines/ActiveAE/ActiveAEResamplePi.cpp SRCS += Engines/ActiveAE/ActiveAEBuffer.cpp ifeq (@USE_ANDROID@,1) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp index 7af20787de..89684e4074 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp @@ -43,7 +43,8 @@ CAEDeviceInfo CAESinkPi::m_info; CAESinkPi::CAESinkPi() : m_sinkbuffer_sec_per_byte(0), m_Initialized(false), - m_submitted(0) + m_submitted(0), + m_omx_output(NULL) { } @@ -56,13 +57,26 @@ void CAESinkPi::SetAudioDest() OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest; OMX_INIT_STRUCTURE(audioDest); - if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") - strncpy((char *)audioDest.sName, "local", strlen("local")); - else - strncpy((char *)audioDest.sName, "hdmi", strlen("hdmi")); - omx_err = m_omx_render.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); - if (omx_err != OMX_ErrorNone) - CLog::Log(LOGERROR, "%s::%s - m_omx_render.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + if ( m_omx_render.IsInitialized() ) + { + if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") + strncpy((char *)audioDest.sName, "local", strlen("local")); + else + strncpy((char *)audioDest.sName, "hdmi", strlen("hdmi")); + omx_err = m_omx_render.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - m_omx_render.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } + if ( m_omx_render_slave.IsInitialized() ) + { + if (CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue") + strncpy((char *)audioDest.sName, "local", strlen("local")); + else + strncpy((char *)audioDest.sName, "hdmi", strlen("hdmi")); + omx_err = m_omx_render_slave.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - m_omx_render_slave.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } } static void SetAudioProps(bool stream_channels, uint32_t channel_map) @@ -176,8 +190,11 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) m_initFormat = format; // analogue only supports stereo - if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") + if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") + { format.m_channelLayout = AE_CH_LAYOUT_2_0; + m_passthrough = false; + } // setup for a 50ms sink feed from SoftAE if (format.m_dataFormat != AE_FMT_FLOATP && format.m_dataFormat != AE_FMT_FLOAT && @@ -196,18 +213,29 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) m_format = format; m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate); - CLog::Log(LOGDEBUG, "%s:%s Format:%d Channels:%d Samplerate:%d framesize:%d bufsize:%d bytes/s=%.2f", CLASSNAME, __func__, - m_format.m_dataFormat, channels, m_format.m_sampleRate, m_format.m_frameSize, m_format.m_frameSize * m_format.m_frames, 1.0/m_sinkbuffer_sec_per_byte); - - CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__); + CLog::Log(LOGDEBUG, "%s:%s Format:%d Channels:%d Samplerate:%d framesize:%d bufsize:%d bytes/s=%.2f dest=%s", CLASSNAME, __func__, + m_format.m_dataFormat, channels, m_format.m_sampleRate, m_format.m_frameSize, m_format.m_frameSize * m_format.m_frames, 1.0/m_sinkbuffer_sec_per_byte, + CSettings::Get().GetString("audiooutput.audiodevice").c_str()); OMX_ERRORTYPE omx_err = OMX_ErrorNone; if (!m_omx_render.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) CLog::Log(LOGERROR, "%s::%s - m_omx_render.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") + { + if (!m_omx_splitter.Initialize("OMX.broadcom.audio_splitter", OMX_IndexParamAudioInit)) + CLog::Log(LOGERROR, "%s::%s - m_omx_splitter.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + if (!m_omx_render_slave.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) + CLog::Log(LOGERROR, "%s::%s - m_omx_render.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + m_omx_output = &m_omx_splitter; + } + else + m_omx_output = &m_omx_render; + + SetAudioDest(); + OMX_INIT_STRUCTURE(m_pcm_input); - m_pcm_input.nPortIndex = m_omx_render.GetInputPort(); m_pcm_input.eNumData = OMX_NumericalDataSigned; m_pcm_input.eEndian = OMX_EndianLittle; m_pcm_input.bInterleaved = OMX_TRUE; @@ -222,37 +250,100 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) m_pcm_input.nChannels = channels; m_pcm_input.nSamplingRate = m_format.m_sampleRate; - omx_err = m_omx_render.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); - if (omx_err != OMX_ErrorNone) - CLog::Log(LOGERROR, "%s::%s - error m_omx_render SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + if ( m_omx_splitter.IsInitialized() ) + { + m_pcm_input.nPortIndex = m_omx_splitter.GetInputPort(); + omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + m_pcm_input.nPortIndex = m_omx_splitter.GetOutputPort(); + omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); + if(omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + + m_pcm_input.nPortIndex = m_omx_splitter.GetOutputPort() + 1; + omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); + if(omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } - m_omx_render.ResetEos(); + if ( m_omx_render_slave.IsInitialized() ) + { + m_pcm_input.nPortIndex = m_omx_render_slave.GetInputPort(); + omx_err = m_omx_render_slave.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_render_slave SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } - SetAudioDest(); + if ( m_omx_render.IsInitialized() ) + { + m_pcm_input.nPortIndex = m_omx_render.GetInputPort(); + omx_err = m_omx_render.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s::%s - error m_omx_render SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } - // set up the number/size of buffers for decoder input - OMX_PARAM_PORTDEFINITIONTYPE port_param; - OMX_INIT_STRUCTURE(port_param); - port_param.nPortIndex = m_omx_render.GetInputPort(); + if ( m_omx_output->IsInitialized() ) + { + // set up the number/size of buffers for decoder input + OMX_PARAM_PORTDEFINITIONTYPE port_param; + OMX_INIT_STRUCTURE(port_param); + port_param.nPortIndex = m_omx_output->GetInputPort(); - omx_err = m_omx_render.GetParameter(OMX_IndexParamPortDefinition, &port_param); - if (omx_err != OMX_ErrorNone) - CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + omx_err = m_omx_output->GetParameter(OMX_IndexParamPortDefinition, &port_param); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); - port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)NUM_OMX_BUFFERS); - port_param.nBufferSize = m_format.m_frameSize * m_format.m_frames; + port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)NUM_OMX_BUFFERS); + port_param.nBufferSize = ALIGN_UP(m_format.m_frameSize * m_format.m_frames, port_param.nBufferAlignment); - omx_err = m_omx_render.SetParameter(OMX_IndexParamPortDefinition, &port_param); - if (omx_err != OMX_ErrorNone) - CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (intput) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + omx_err = m_omx_output->SetParameter(OMX_IndexParamPortDefinition, &port_param); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); - omx_err = m_omx_render.AllocInputBuffers(); - if (omx_err != OMX_ErrorNone) - CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err); + omx_err = m_omx_output->AllocInputBuffers(); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err); + } - omx_err = m_omx_render.SetStateForComponent(OMX_StateExecuting); - if (omx_err != OMX_ErrorNone) - CLog::Log(LOGERROR, "%s:%s - m_omx_render OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + if ( m_omx_splitter.IsInitialized() ) + { + m_omx_tunnel_splitter.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort(), &m_omx_render, m_omx_render.GetInputPort()); + omx_err = m_omx_tunnel_splitter.Establish(); + if (omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter.Establish 0x%08x", omx_err); + return false; + } + + m_omx_tunnel_splitter_slave.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort() + 1, &m_omx_render_slave, m_omx_render_slave.GetInputPort()); + omx_err = m_omx_tunnel_splitter_slave.Establish(); + if (omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter_slave.Establish 0x%08x", omx_err); + return false; + } + } + + if ( m_omx_splitter.IsInitialized() ) + { + omx_err = m_omx_splitter.SetStateForComponent(OMX_StateExecuting); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - m_omx_splitter OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } + if ( m_omx_render.IsInitialized() ) + { + omx_err = m_omx_render.SetStateForComponent(OMX_StateExecuting); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - m_omx_render OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } + if ( m_omx_render_slave.IsInitialized() ) + { + omx_err = m_omx_render_slave.SetStateForComponent(OMX_StateExecuting); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s - m_omx_render_slave OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); + } m_Initialized = true; return true; @@ -263,12 +354,32 @@ void CAESinkPi::Deinitialize() { CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__); SetAudioProps(false, 0); - if (m_Initialized) - { + + if ( m_omx_render.IsInitialized() ) + m_omx_render.IgnoreNextError(OMX_ErrorPortUnpopulated); + if ( m_omx_render_slave.IsInitialized() ) + m_omx_render_slave.IgnoreNextError(OMX_ErrorPortUnpopulated); + + if ( m_omx_tunnel_splitter.IsInitialized() ) + m_omx_tunnel_splitter.Deestablish(); + if ( m_omx_tunnel_splitter_slave.IsInitialized() ) + m_omx_tunnel_splitter_slave.Deestablish(); + + if ( m_omx_splitter.IsInitialized() ) + m_omx_splitter.FlushAll(); + if ( m_omx_render.IsInitialized() ) m_omx_render.FlushAll(); + if ( m_omx_render_slave.IsInitialized() ) + m_omx_render_slave.FlushAll(); + + if ( m_omx_splitter.IsInitialized() ) + m_omx_splitter.Deinitialize(); + if ( m_omx_render.IsInitialized() ) m_omx_render.Deinitialize(); - m_Initialized = false; - } + if ( m_omx_render_slave.IsInitialized() ) + m_omx_render_slave.Deinitialize(); + + m_Initialized = false; } bool CAESinkPi::IsCompatible(const AEAudioFormat &format, const std::string &device) @@ -314,7 +425,7 @@ double CAESinkPi::GetCacheTotal() unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset) { - if (!m_Initialized || !frames) + if (!m_Initialized || !m_omx_output || !frames) return frames; OMX_ERRORTYPE omx_err = OMX_ErrorNone; @@ -332,7 +443,7 @@ unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned if (delay <= 0.0 && m_submitted) CLog::Log(LOGNOTICE, "%s:%s Underrun (delay:%.2f frames:%d)", CLASSNAME, __func__, delay, frames); - omx_buffer = m_omx_render.GetInputBuffer(1000); + omx_buffer = m_omx_output->GetInputBuffer(1000); if (omx_buffer == NULL) { CLog::Log(LOGERROR, "CAESinkPi::AddPackets timeout"); @@ -351,7 +462,7 @@ unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned for (int i=0; i < planes; i++) memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, data[i] + offset * pitch, planesize); } - omx_err = m_omx_render.EmptyThisBuffer(omx_buffer); + omx_err = m_omx_output->EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) CLog::Log(LOGERROR, "%s:%s frames=%d err=%x", CLASSNAME, __func__, frames, omx_err); m_submitted++; @@ -419,6 +530,26 @@ void CAESinkPi::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) m_info.m_dataFormats.push_back(AE_FMT_S16NEP); list.push_back(m_info); + + m_info.m_channels.Reset(); + m_info.m_dataFormats.clear(); + m_info.m_sampleRates.clear(); + + m_info.m_deviceType = AE_DEVTYPE_PCM; + m_info.m_deviceName = "Both"; + m_info.m_displayName = "HDMI and Analogue"; + m_info.m_displayNameExtra = ""; + m_info.m_channels += AE_CH_FL; + m_info.m_channels += AE_CH_FR; + m_info.m_sampleRates.push_back(48000); + m_info.m_dataFormats.push_back(AE_FMT_FLOAT); + m_info.m_dataFormats.push_back(AE_FMT_S32LE); + m_info.m_dataFormats.push_back(AE_FMT_S16LE); + m_info.m_dataFormats.push_back(AE_FMT_FLOATP); + m_info.m_dataFormats.push_back(AE_FMT_S32NEP); + m_info.m_dataFormats.push_back(AE_FMT_S16NEP); + + list.push_back(m_info); } #endif diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.h b/xbmc/cores/AudioEngine/Sinks/AESinkPi.h index 8ab1d086db..5c57999335 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.h @@ -57,8 +57,13 @@ private: bool m_Initialized; uint32_t m_submitted; OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_input; + COMXCoreComponent *m_omx_output; + COMXCoreComponent m_omx_splitter; COMXCoreComponent m_omx_render; + COMXCoreComponent m_omx_render_slave; bool m_passthrough; + COMXCoreTunel m_omx_tunnel_splitter; + COMXCoreTunel m_omx_tunnel_splitter_slave; }; #endif diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.cpp b/xbmc/cores/AudioEngine/Utils/AEUtil.cpp index 44cf2566fe..f535512451 100644 --- a/xbmc/cores/AudioEngine/Utils/AEUtil.cpp +++ b/xbmc/cores/AudioEngine/Utils/AEUtil.cpp @@ -25,6 +25,10 @@ #include "utils/log.h" #include "utils/TimeUtils.h" +extern "C" { +#include "libavutil/channel_layout.h" +} + using namespace std; /* declare the rng seed and initialize it */ @@ -526,3 +530,86 @@ bool CAEUtil::S16NeedsByteSwap(AEDataFormat in, AEDataFormat out) return in != out; } + +uint64_t CAEUtil::GetAVChannelLayout(CAEChannelInfo &info) +{ + uint64_t channelLayout = 0; + if (info.HasChannel(AE_CH_FL)) channelLayout |= AV_CH_FRONT_LEFT; + if (info.HasChannel(AE_CH_FR)) channelLayout |= AV_CH_FRONT_RIGHT; + if (info.HasChannel(AE_CH_FC)) channelLayout |= AV_CH_FRONT_CENTER; + if (info.HasChannel(AE_CH_LFE)) channelLayout |= AV_CH_LOW_FREQUENCY; + if (info.HasChannel(AE_CH_BL)) channelLayout |= AV_CH_BACK_LEFT; + if (info.HasChannel(AE_CH_BR)) channelLayout |= AV_CH_BACK_RIGHT; + if (info.HasChannel(AE_CH_FLOC)) channelLayout |= AV_CH_FRONT_LEFT_OF_CENTER; + if (info.HasChannel(AE_CH_FROC)) channelLayout |= AV_CH_FRONT_RIGHT_OF_CENTER; + if (info.HasChannel(AE_CH_BC)) channelLayout |= AV_CH_BACK_CENTER; + if (info.HasChannel(AE_CH_SL)) channelLayout |= AV_CH_SIDE_LEFT; + if (info.HasChannel(AE_CH_SR)) channelLayout |= AV_CH_SIDE_RIGHT; + if (info.HasChannel(AE_CH_TC)) channelLayout |= AV_CH_TOP_CENTER; + if (info.HasChannel(AE_CH_TFL)) channelLayout |= AV_CH_TOP_FRONT_LEFT; + if (info.HasChannel(AE_CH_TFC)) channelLayout |= AV_CH_TOP_FRONT_CENTER; + if (info.HasChannel(AE_CH_TFR)) channelLayout |= AV_CH_TOP_FRONT_RIGHT; + if (info.HasChannel(AE_CH_TBL)) channelLayout |= AV_CH_TOP_BACK_LEFT; + if (info.HasChannel(AE_CH_TBC)) channelLayout |= AV_CH_TOP_BACK_CENTER; + if (info.HasChannel(AE_CH_TBR)) channelLayout |= AV_CH_TOP_BACK_RIGHT; + + return channelLayout; +} + +AVSampleFormat CAEUtil::GetAVSampleFormat(AEDataFormat format) +{ + if (format == AE_FMT_U8) return AV_SAMPLE_FMT_U8; + else if (format == AE_FMT_S16NE) return AV_SAMPLE_FMT_S16; + else if (format == AE_FMT_S32NE) return AV_SAMPLE_FMT_S32; + else if (format == AE_FMT_S24NE4) return AV_SAMPLE_FMT_S32; + else if (format == AE_FMT_S24NE4MSB)return AV_SAMPLE_FMT_S32; + else if (format == AE_FMT_S24NE3) return AV_SAMPLE_FMT_S32; + else if (format == AE_FMT_FLOAT) return AV_SAMPLE_FMT_FLT; + else if (format == AE_FMT_DOUBLE) return AV_SAMPLE_FMT_DBL; + + else if (format == AE_FMT_U8P) return AV_SAMPLE_FMT_U8P; + else if (format == AE_FMT_S16NEP) return AV_SAMPLE_FMT_S16P; + else if (format == AE_FMT_S32NEP) return AV_SAMPLE_FMT_S32P; + else if (format == AE_FMT_S24NE4P) return AV_SAMPLE_FMT_S32P; + else if (format == AE_FMT_S24NE4MSBP)return AV_SAMPLE_FMT_S32P; + else if (format == AE_FMT_S24NE3P) return AV_SAMPLE_FMT_S32P; + else if (format == AE_FMT_FLOATP) return AV_SAMPLE_FMT_FLTP; + else if (format == AE_FMT_DOUBLEP) return AV_SAMPLE_FMT_DBLP; + + if (AE_IS_PLANAR(format)) + return AV_SAMPLE_FMT_FLTP; + else + return AV_SAMPLE_FMT_FLT; +} + +uint64_t CAEUtil::GetAVChannel(enum AEChannel aechannel) +{ + switch (aechannel) + { + case AE_CH_FL: return AV_CH_FRONT_LEFT; + case AE_CH_FR: return AV_CH_FRONT_RIGHT; + case AE_CH_FC: return AV_CH_FRONT_CENTER; + case AE_CH_LFE: return AV_CH_LOW_FREQUENCY; + case AE_CH_BL: return AV_CH_BACK_LEFT; + case AE_CH_BR: return AV_CH_BACK_RIGHT; + case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER; + case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER; + case AE_CH_BC: return AV_CH_BACK_CENTER; + case AE_CH_SL: return AV_CH_SIDE_LEFT; + case AE_CH_SR: return AV_CH_SIDE_RIGHT; + case AE_CH_TC: return AV_CH_TOP_CENTER; + case AE_CH_TFL: return AV_CH_TOP_FRONT_LEFT; + case AE_CH_TFC: return AV_CH_TOP_FRONT_CENTER; + case AE_CH_TFR: return AV_CH_TOP_FRONT_RIGHT; + case AE_CH_TBL: return AV_CH_TOP_BACK_LEFT; + case AE_CH_TBC: return AV_CH_TOP_BACK_CENTER; + case AE_CH_TBR: return AV_CH_TOP_BACK_RIGHT; + default: + return 0; + } +} + +int CAEUtil::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout) +{ + return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); +} diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.h b/xbmc/cores/AudioEngine/Utils/AEUtil.h index 1e61c50716..782a9ba32f 100644 --- a/xbmc/cores/AudioEngine/Utils/AEUtil.h +++ b/xbmc/cores/AudioEngine/Utils/AEUtil.h @@ -23,6 +23,10 @@ #include "PlatformDefs.h" #include <math.h> +extern "C" { +#include "libavutil/samplefmt.h" +} + #ifdef TARGET_WINDOWS #if _M_IX86_FP>0 && !defined(__SSE__) #define __SSE__ @@ -220,4 +224,9 @@ public: static void FloatRand4(const float min, const float max, float result[4], __m128 *sseresult = NULL); static bool S16NeedsByteSwap(AEDataFormat in, AEDataFormat out); + + static uint64_t GetAVChannelLayout(CAEChannelInfo &info); + static AVSampleFormat GetAVSampleFormat(AEDataFormat format); + static uint64_t GetAVChannel(enum AEChannel aechannel); + static int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout); }; diff --git a/xbmc/cores/DllLoader/exports/Makefile.in b/xbmc/cores/DllLoader/exports/Makefile.in index ce920ce736..db31666278 100644 --- a/xbmc/cores/DllLoader/exports/Makefile.in +++ b/xbmc/cores/DllLoader/exports/Makefile.in @@ -19,5 +19,5 @@ exports_python_linux.o : exports_python_linux.cpp wrapper.def : wrapper.o nm wrapper.o | grep __wrap | awk '{printf("%s ", $$3);}' | sed "s/___wrap_/__wrap_/g" | sed "s/__wrap_/-Wl,-wrap,/g" > $@ ifeq (@USE_ANDROID@,1) - echo "-L$(prefix)/lib/dummy-libxbmc/ -lxbmc" >> $@ + echo "-L$(prefix)/lib/dummy-lib@APP_NAME_LC@/ -l@APP_NAME_LC@" >> $@ endif diff --git a/xbmc/cores/DllLoader/exports/emu_kernel32.cpp b/xbmc/cores/DllLoader/exports/emu_kernel32.cpp index bf4d64ee69..f3333a0e41 100644 --- a/xbmc/cores/DllLoader/exports/emu_kernel32.cpp +++ b/xbmc/cores/DllLoader/exports/emu_kernel32.cpp @@ -20,6 +20,7 @@ #include "emu_kernel32.h" #include "emu_dummy.h" +#include "CompileInfo.h" #include "utils/log.h" #include "storage/IoSupport.h" @@ -451,7 +452,7 @@ extern "C" int WINAPI dllGetStartupInfoA(LPSTARTUPINFOA lpStartupInfo) lpStartupInfo->lpDesktop = NULL; lpStartupInfo->lpReserved = NULL; lpStartupInfo->lpReserved2 = 0; - lpStartupInfo->lpTitle = (LPTSTR)"XBMC"; + lpStartupInfo->lpTitle = (LPTSTR)CCompileInfo::GetAppName(); lpStartupInfo->wShowWindow = 0; return 1; } diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp index 5bde82e71e..58474d25d3 100644 --- a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp +++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp @@ -530,7 +530,7 @@ extern "C" if (bWrite) bResult = pFile->OpenForWrite(CUtil::ValidatePath(str), bOverwrite); else - bResult = pFile->Open(CUtil::ValidatePath(str)); + bResult = pFile->Open(CUtil::ValidatePath(str), READ_TRUNCATED); if (bResult) { diff --git a/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp b/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp index 9adf26e046..afc1206f0f 100644 --- a/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp +++ b/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp @@ -22,6 +22,7 @@ #include "system.h" #include "signal.h" #include "limits.h" +#include "CompileInfo.h" #include "threads/SingleLock.h" #include "ExternalPlayer.h" #include "windowing/WindowingFactory.h" @@ -292,13 +293,13 @@ void CExternalPlayer::Process() if (m_hidexbmc && !m_islauncher) { - CLog::Log(LOGNOTICE, "%s: Hiding XBMC window", __FUNCTION__); + CLog::Log(LOGNOTICE, "%s: Hiding %s window", __FUNCTION__, CCompileInfo::GetAppName()); g_Windowing.Hide(); } #if defined(TARGET_WINDOWS) else if (currentStyle & WS_EX_TOPMOST) { - CLog::Log(LOGNOTICE, "%s: Lowering XBMC window", __FUNCTION__); + CLog::Log(LOGNOTICE, "%s: Lowering %s window", __FUNCTION__, CCompileInfo::GetAppName()); SetWindowPos(g_hWnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOREDRAW); } @@ -338,7 +339,7 @@ void CExternalPlayer::Process() { if (m_hidexbmc) { - CLog::Log(LOGNOTICE, "%s: XBMC cannot stay hidden for a launcher process", __FUNCTION__); + CLog::Log(LOGNOTICE, "%s: %s cannot stay hidden for a launcher process", __FUNCTION__, CCompileInfo::GetAppName()); g_Windowing.Show(false); } @@ -362,14 +363,14 @@ void CExternalPlayer::Process() if (currentStyle & WS_EX_TOPMOST) { - CLog::Log(LOGNOTICE, "%s: Showing XBMC window TOPMOST", __FUNCTION__); + CLog::Log(LOGNOTICE, "%s: Showing %s window TOPMOST", __FUNCTION__, CCompileInfo::GetAppName()); SetWindowPos(g_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW); SetForegroundWindow(g_hWnd); } else #endif { - CLog::Log(LOGNOTICE, "%s: Showing XBMC window", __FUNCTION__); + CLog::Log(LOGNOTICE, "%s: Showing %s window", __FUNCTION__, CCompileInfo::GetAppName()); g_Windowing.Show(); } diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp index 78599497f7..9b5d0a94f9 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp @@ -2541,6 +2541,9 @@ bool CLinuxRendererGL::UploadVAAPITexture(int index) return false; } + if (!vaapi->CopyGlx()) + return false; + plane.id = vaapi->texture; // in stereoscopic mode sourceRect may only diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp index 72b9bcaeaa..75fd6bb374 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp @@ -165,6 +165,7 @@ int CDVDOverlayCodecFFmpeg::Decode(DemuxPacket *pPacket) if (len < 0) { CLog::Log(LOGERROR, "%s - avcodec_decode_subtitle returned failure", __FUNCTION__); + Flush(); return OC_ERROR; } @@ -235,7 +236,10 @@ CDVDOverlay* CDVDOverlayCodecFFmpeg::GetOverlay() if(m_Subtitle.rects[m_SubtitleIndex] == NULL) return NULL; + AVSubtitleRect& rect = *m_Subtitle.rects[m_SubtitleIndex]; + if (rect.pict.data[0] == NULL) + return NULL; CDVDOverlayImage* overlay = new CDVDOverlayImage(); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp index baa24b862f..1983499c9d 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp @@ -114,7 +114,8 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option case AV_CODEC_ID_H263: case AV_CODEC_ID_H263P: case AV_CODEC_ID_H263I: - m_pFormatName = "am-h263"; + // amcodec can't handle h263 + return false; break; case AV_CODEC_ID_FLV1: m_pFormatName = "am-flv1"; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp index 3e4f88510f..e4e01ca694 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp @@ -1512,36 +1512,38 @@ CDVDVideoCodecVideoToolBox::CreateVTSession(int width, int height, CMFormatDescr OSStatus status; #if defined(TARGET_DARWIN_IOS) - //TODO - remove the clamp for ipad3 when CVOpenGLESTextureCacheCreateTextureFromImage - //has been planted ... - //if (!DarwinIsIPad3()) - { - // decoding, scaling and rendering above 1920 x 800 runs into - // some bandwidth limit. detect and scale down to reduce - // the bandwidth requirements. - int width_clamp = 1280; - if ((width * height) > (1920 * 800)) - width_clamp = 960; - - int new_width = CheckNP2(width); - if (width != new_width) - { - // force picture width to power of two and scale up height - // we do this because no GL_UNPACK_ROW_LENGTH in OpenGLES - // and the CVPixelBufferPixel gets created using some - // strange alignment when width is non-standard. - double w_scaler = (double)new_width / width; - width = new_width; - height = height * w_scaler; - } - // scale output pictures down to 720p size for display - if (width > width_clamp) - { - double w_scaler = (float)width_clamp / width; - width = width_clamp; - height = height * w_scaler; - } - } + double scale = 0.0; + + // decoding, scaling and rendering above 1920 x 800 runs into + // some bandwidth limit. detect and scale down to reduce + // the bandwidth requirements. + int width_clamp = 1280; + if ((width * height) > (1920 * 800)) + width_clamp = 960; + + // allow rendering without scaledown for all + // retina devices (which have enough power to handle it) + if (CDarwinUtils::DeviceHasRetina(scale)) + width_clamp = 1920; + + int new_width = CheckNP2(width); + if (width != new_width) + { + // force picture width to power of two and scale up height + // we do this because no GL_UNPACK_ROW_LENGTH in OpenGLES + // and the CVPixelBufferPixel gets created using some + // strange alignment when width is non-standard. + double w_scaler = (double)new_width / width; + width = new_width; + height = height * w_scaler; + } + // scale output pictures down to 720p size for display + if (width > width_clamp) + { + double w_scaler = (float)width_clamp / width; + width = width_clamp; + height = height * w_scaler; + } #endif destinationPixelBufferAttributes = CFDictionaryCreateMutable( NULL, // CFAllocatorRef allocator diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp index 065b643828..2caf2b292b 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp @@ -347,12 +347,15 @@ bool CDXVAContext::GetInputAndTarget(int codec, GUID &inGuid, D3DFORMAT &outForm outFormat = D3DFMT_UNKNOWN; UINT output_count = 0; D3DFORMAT *output_list = NULL; + + // iterate through our predifined dxva modes and find the first matching for desired codec + // once we found a mode, get a target we support in render_targets for (const dxva2_mode_t* mode = dxva2_modes; mode->name && outFormat == D3DFMT_UNKNOWN; mode++) { if (mode->codec != codec) continue; - for (unsigned i = 0; i < m_input_count; i++) + for (unsigned i = 0; i < m_input_count && outFormat == D3DFMT_UNKNOWN; i++) { if (!IsEqualGUID(m_input_list[i], *mode->guid)) continue; @@ -365,14 +368,16 @@ bool CDXVAContext::GetInputAndTarget(int codec, GUID &inGuid, D3DFORMAT &outForm break; } - for (unsigned j = 0; render_targets[j] != D3DFMT_UNKNOWN; j++) + for (unsigned j = 0; render_targets[j] != D3DFMT_UNKNOWN && outFormat == D3DFMT_UNKNOWN; j++) { for (unsigned k = 0; k < output_count; k++) - if (output_list[k] == render_targets[j]) { - inGuid = m_input_list[i]; - outFormat = output_list[k]; - break; + if (output_list[k] == render_targets[j]) + { + inGuid = m_input_list[i]; + outFormat = output_list[k]; + break; + } } } } @@ -500,7 +505,6 @@ CSurfaceContext::~CSurfaceContext() void CSurfaceContext::AddSurface(IDirect3DSurface9* surf) { CSingleLock lock(m_section); - surf->AddRef(); m_state[surf] = 0; m_freeSurfaces.push_back(surf); } diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp index 8b5b5b81a2..707d609d92 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp @@ -417,6 +417,12 @@ bool CVideoSurfaces::HasFree() return !m_freeSurfaces.empty(); } +int CVideoSurfaces::NumFree() +{ + CSingleLock lock(m_section); + return m_freeSurfaces.size(); +} + bool CVideoSurfaces::HasRefs() { CSingleLock lock(m_section); @@ -610,7 +616,7 @@ long CDecoder::Release() if (m_vaapiConfigured == true) { CSingleLock lock(m_DecoderSection); - CLog::Log(LOGNOTICE,"VAAPI::Release pre-cleanup"); + CLog::Log(LOGDEBUG,"VAAPI::Release pre-cleanup"); Message *reply; if (m_vaapiOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::PRECLEANUP, @@ -737,7 +743,6 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) int retval = 0; uint16_t decoded, processed, render; - int vapipe; bool vpp; Message *msg; while (m_vaapiOutput.m_controlPort.ReceiveInMessage(&msg)) @@ -755,8 +760,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) while (!retval) { // first fill the buffers to keep vaapi busy - vapipe = vpp ? decoded + processed : decoded; - if (vapipe < 4 && m_videoSurfaces.HasFree()) + if (decoded < 2 && processed < 3 && m_videoSurfaces.HasFree()) { retval |= VC_BUFFER; } @@ -794,8 +798,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) msg->Release(); } - vapipe = vpp ? decoded + processed : decoded; - if (vapipe < 4 && m_videoSurfaces.HasFree()) + if (decoded < 2 && processed < 3 && m_videoSurfaces.HasFree()) { retval |= VC_BUFFER; } @@ -829,7 +832,7 @@ int CDecoder::Check(AVCodecContext* avctx) if (state == VAAPI_LOST) { - CLog::Log(LOGNOTICE,"VAAPI::Check waiting for display reset event"); + CLog::Log(LOGDEBUG,"VAAPI::Check waiting for display reset event"); if (!m_DisplayEvent.WaitMSec(4000)) { CLog::Log(LOGERROR, "VAAPI::Check - device didn't reset in reasonable time"); @@ -1085,6 +1088,10 @@ void CDecoder::ReturnRenderPicture(CVaapiRenderPicture *renderPic) m_vaapiOutput.m_dataPort.SendOutMessage(COutputDataProtocol::RETURNPIC, &renderPic, sizeof(renderPic)); } +void CDecoder::ReturnProcPicture(int id) +{ + m_vaapiOutput.m_dataPort.SendOutMessage(COutputDataProtocol::RETURNPROCPIC, &id, sizeof(int)); +} //----------------------------------------------------------------------------- // RenderPicture @@ -1126,6 +1133,69 @@ void CVaapiRenderPicture::ReturnUnused() vaapi->ReturnRenderPicture(this); } +bool CVaapiRenderPicture::CopyGlx() +{ + CSingleLock lock(renderPicSection); + + if (glx.bound == true) + return true; + + if (glx.procPic.source == CVaapiProcessedPicture::SKIP_SRC || + glx.procPic.source == CVaapiProcessedPicture::VPP_SRC) + { + unsigned int colorStandard; + switch(glx.procPic.DVDPic.color_matrix) + { + case AVCOL_SPC_BT709: + colorStandard = VA_SRC_BT709; + break; + case AVCOL_SPC_BT470BG: + case AVCOL_SPC_SMPTE170M: + colorStandard = VA_SRC_BT601; + break; + case AVCOL_SPC_SMPTE240M: + case AVCOL_SPC_FCC: + case AVCOL_SPC_UNSPECIFIED: + case AVCOL_SPC_RGB: + default: + if(texWidth > 1000) + colorStandard = VA_SRC_BT709; + else + colorStandard = VA_SRC_BT601; + } + + if (vaSyncSurface(glx.vadsp, glx.procPic.videoSurface) != VA_STATUS_SUCCESS) + return false; + + if (vaPutSurface(glx.vadsp, + glx.procPic.videoSurface, + glx.pixmap, + 0,0, + texWidth, texHeight, + 0,0, + texWidth, texHeight, + NULL,0, + VA_FRAME_PICTURE | colorStandard) != VA_STATUS_SUCCESS) + { + return false; + } + + XSync(glx.x11dsp, false); + glEnable(glx.textureTarget); + glBindTexture(glx.textureTarget, texture); + glx.glXBindTexImageEXT(glx.x11dsp, glx.glPixmap, GLX_FRONT_LEFT_EXT, NULL); + glBindTexture(glx.textureTarget, 0); + glDisable(glx.textureTarget); + + glx.bound = true; + + vaapi->ReturnProcPicture(glx.procPic.id); + glx.procPic.id = -1; + } + + return true; +} + void CVaapiRenderPicture::Sync() { #ifdef GL_ARB_sync @@ -1140,6 +1210,15 @@ void CVaapiRenderPicture::Sync() fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } #endif + + if (DVDPic.format == RENDER_FMT_VAAPI && glx.bound) + { + glEnable(glx.textureTarget); + glBindTexture(glx.textureTarget, texture); + glx.glXReleaseTexImageEXT(glx.x11dsp, glx.glPixmap, GLX_FRONT_LEFT_EXT); + glBindTexture(glx.textureTarget, 0); + glDisable(glx.textureTarget); + } } //----------------------------------------------------------------------------- @@ -1271,6 +1350,11 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) pic = *((CVaapiRenderPicture**)msg->data); QueueReturnPicture(pic); return; + case COutputDataProtocol::RETURNPROCPIC: + int id; + id = *((int*)msg->data); + ProcessReturnProcPicture(id); + return; default: break; } @@ -1357,6 +1441,12 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) m_controlPort.SendInMessage(COutputControlProtocol::STATS); m_extTimeout = 0; return; + case COutputDataProtocol::RETURNPROCPIC: + int id; + id = *((int*)msg->data); + ProcessReturnProcPicture(id); + m_extTimeout = 0; + return; default: break; } @@ -1485,7 +1575,7 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) m_config.stats->DecProcessed(); m_bufferPool.processedPics.pop_front(); outPic = ProcessPicture(procPic); - ReleaseProcessedPicture(procPic); + //ReleaseProcessedPicture(procPic); if (outPic) { m_config.stats->IncRender(); @@ -1672,8 +1762,15 @@ void COutput::Flush() bool COutput::HasWork() { - if ((!m_bufferPool.freeRenderPics.empty() && !m_bufferPool.processedPics.empty()) || - (!m_bufferPool.decodedPics.empty() && m_bufferPool.processedPics.size() < 4)) + // send a pic to renderer + if (!m_bufferPool.freeRenderPics.empty() && !m_bufferPool.processedPics.empty()) + return true; + + bool ppWantsPic = true; + if (m_pp) + ppWantsPic = m_pp->WantsPic(); + + if (!m_bufferPool.decodedPics.empty() && m_bufferPool.processedPics.size() < 4 && ppWantsPic) return true; return false; @@ -1686,6 +1783,9 @@ bool COutput::PreferPP() if (!m_pp) return true; + if (!m_pp->WantsPic()) + return false; + if (!m_pp->DoesSync() && m_bufferPool.processedPics.size() < 4) return true; @@ -1804,53 +1904,11 @@ CVaapiRenderPicture* COutput::ProcessPicture(CVaapiProcessedPicture &pic) if (pic.source == CVaapiProcessedPicture::SKIP_SRC || pic.source == CVaapiProcessedPicture::VPP_SRC) { - unsigned int colorStandard; - switch(pic.DVDPic.color_matrix) - { - case AVCOL_SPC_BT709: - colorStandard = VA_SRC_BT709; - break; - case AVCOL_SPC_BT470BG: - case AVCOL_SPC_SMPTE170M: - colorStandard = VA_SRC_BT601; - break; - case AVCOL_SPC_SMPTE240M: - case AVCOL_SPC_FCC: - case AVCOL_SPC_UNSPECIFIED: - case AVCOL_SPC_RGB: - default: - if(m_config.surfaceWidth > 1000) - colorStandard = VA_SRC_BT709; - else - colorStandard = VA_SRC_BT601; - } - - if (!CheckSuccess(vaSyncSurface(m_config.dpy, pic.videoSurface))) - return NULL; - - XLockDisplay(m_Display); - if (!CheckSuccess(vaPutSurface(m_config.dpy, - pic.videoSurface, - retPic->pixmap, - 0,0, - m_config.vidWidth, m_config.vidHeight, - 0,0, - m_config.outWidth, m_config.outHeight, - NULL,0, - VA_FRAME_PICTURE | colorStandard))) - { - return NULL; - } - XUnlockDisplay(m_Display); - - XSync(m_config.x11dsp, false); - glEnable(m_textureTarget); - glBindTexture(m_textureTarget, retPic->texture); - glXBindTexImageEXT(m_Display, retPic->glPixmap, GLX_FRONT_LEFT_EXT, NULL); - glBindTexture(m_textureTarget, 0); - glDisable(m_textureTarget); - + pic.id = m_bufferPool.procPicId++; + m_bufferPool.processedPicsAway.push_back(pic); retPic->DVDPic.format = RENDER_FMT_VAAPI; + retPic->glx.procPic = pic; + retPic->glx.bound = false; } else if (pic.source == CVaapiProcessedPicture::FFMPEG_SRC) { @@ -1913,6 +1971,18 @@ void COutput::DropVppProcessedPictures() else ++it; } + + it = m_bufferPool.processedPicsAway.begin(); + while (it != m_bufferPool.processedPicsAway.end()) + { + if (it->source == CVaapiProcessedPicture::VPP_SRC) + { + it = m_bufferPool.processedPicsAway.erase(it); + } + else + ++it; + } + m_controlPort.SendInMessage(COutputControlProtocol::STATS); } @@ -1958,7 +2028,7 @@ bool COutput::ProcessSyncPicture() #ifdef GL_ARB_sync if (pic->usefence) { - if (glIsSync(pic->fence)) + if (pic->fence) { GLint state; GLsizei length; @@ -2010,16 +2080,22 @@ void COutput::ProcessReturnPicture(CVaapiRenderPicture *pic) if (pic->avFrame) av_frame_unref(pic->avFrame); - if (pic->DVDPic.format == RENDER_FMT_VAAPI) + ProcessReturnProcPicture(pic->glx.procPic.id); + pic->valid = false; +} + +void COutput::ProcessReturnProcPicture(int id) +{ + std::deque<CVaapiProcessedPicture>::iterator it; + for (it=m_bufferPool.processedPicsAway.begin(); it!=m_bufferPool.processedPicsAway.end(); ++it) { - glEnable(m_textureTarget); - glBindTexture(m_textureTarget, pic->texture); - glXReleaseTexImageEXT(m_Display, pic->glPixmap, GLX_FRONT_LEFT_EXT); - glBindTexture(m_textureTarget, 0); - glDisable(m_textureTarget); + if (it->id == id) + { + ReleaseProcessedPicture(*it); + m_bufferPool.processedPicsAway.erase(it); + break; + } } - - pic->valid = false; } bool COutput::EnsureBufferPool() @@ -2065,33 +2141,40 @@ bool COutput::EnsureBufferPool() { pic = m_bufferPool.allRenderPics[i]; - pic->pixmap = XCreatePixmap(m_Display, + pic->glx.pixmap = XCreatePixmap(m_Display, m_Window, m_config.outWidth, m_config.outHeight, wndattribs.depth); - if (!pic->pixmap) + if (!pic->glx.pixmap) { CLog::Log(LOGERROR, "VAAPI::COutput::EnsureBufferPool - Unable to create XPixmap"); return false; } // create gl pixmap - pic->glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], pic->pixmap, pixmapAttribs); + pic->glx.glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], pic->glx.pixmap, pixmapAttribs); - if (!pic->glPixmap) + if (!pic->glx.glPixmap) { - CLog::Log(LOGINFO, "VAAPI::COutput::EnsureBufferPool - Could not create glPixmap"); + CLog::Log(LOGERROR, "VAAPI::COutput::EnsureBufferPool - Could not create glPixmap"); return false; } glGenTextures(1, &pic->texture); + pic->glx.vadsp = m_config.dpy; + pic->glx.x11dsp = m_Display; + pic->glx.glXBindTexImageEXT = glXBindTexImageEXT; + pic->glx.glXReleaseTexImageEXT = glXReleaseTexImageEXT; + pic->glx.textureTarget = m_textureTarget; pic->avFrame = av_frame_alloc(); pic->valid = false; } - CLog::Log(LOGNOTICE, "VAAPI::COutput::InitBufferPool - Surfaces created"); + m_bufferPool.procPicId = 0; + + CLog::Log(LOGDEBUG, "VAAPI::COutput::InitBufferPool - Surfaces created"); return true; } @@ -2111,7 +2194,7 @@ void COutput::ReleaseBufferPool(bool precleanup) if (pic->usefence) { #ifdef GL_ARB_sync - while (glIsSync(pic->fence)) + while (pic->fence) { GLint state; GLsizei length; @@ -2119,6 +2202,7 @@ void COutput::ReleaseBufferPool(bool precleanup) if(state == GL_SIGNALED || timeout.IsTimePast()) { glDeleteSync(pic->fence); + pic->fence = None; } else { @@ -2144,11 +2228,12 @@ void COutput::ReleaseBufferPool(bool precleanup) if (precleanup && pic->valid) continue; - if (glIsTexture(pic->texture)) + + if (pic->texture) { glDeleteTextures(1, &pic->texture); - glXDestroyPixmap(m_Display, pic->glPixmap); - XFreePixmap(m_Display, pic->pixmap); + glXDestroyPixmap(m_Display, pic->glx.glPixmap); + XFreePixmap(m_Display, pic->glx.pixmap); pic->texture = None; } av_frame_free(&pic->avFrame); @@ -2187,7 +2272,6 @@ bool COutput::GLInit() glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXReleaseTexImageEXT"); - return true; } @@ -2243,7 +2327,7 @@ bool COutput::CreateGlxContext() if (!m_glPixmap) { - CLog::Log(LOGINFO, "VAAPI::COutput::CreateGlxContext - Could not create glPixmap"); + CLog::Log(LOGERROR, "VAAPI::COutput::CreateGlxContext - Could not create glPixmap"); return false; } @@ -2251,11 +2335,11 @@ bool COutput::CreateGlxContext() if (!glXMakeCurrent(m_Display, m_glPixmap, m_glContext)) { - CLog::Log(LOGINFO, "VAAPI::COutput::CreateGlxContext - Could not make Pixmap current"); + CLog::Log(LOGERROR, "VAAPI::COutput::CreateGlxContext - Could not make Pixmap current"); return false; } - CLog::Log(LOGNOTICE, "VAAPI::COutput::CreateGlxContext - created context"); + CLog::Log(LOGDEBUG, "VAAPI::COutput::CreateGlxContext - created context"); return true; } @@ -2371,7 +2455,7 @@ bool CVppPostproc::PreInit(CVaapiConfig &config, SDiMethods *methods) // create surfaces VASurfaceID surfaces[32]; - int nb_surfaces = 5; + int nb_surfaces = NUM_RENDER_PICS; if (!CheckSuccess(vaCreateSurfaces(m_config.dpy, VA_RT_FORMAT_YUV420, m_config.surfaceWidth, @@ -2780,6 +2864,15 @@ bool CVppPostproc::DoesSync() return false; } +bool CVppPostproc::WantsPic() +{ + // need at least 2 for deinterlacing + if (m_videoSurfaces.NumFree() > 1) + return true; + + return false; +} + bool CVppPostproc::CheckSuccess(VAStatus status) { if (status != VA_STATUS_SUCCESS) @@ -2822,7 +2915,7 @@ bool CFFmpegPostproc::PreInit(CVaapiConfig &config, SDiMethods *methods) bool use_filter = true; if (!m_dllSSE4.Load()) { - CLog::Log(LOGNOTICE,"VAAPI::SupportsFilter failed loading sse4 lib"); + CLog::Log(LOGERROR,"VAAPI::SupportsFilter failed loading sse4 lib"); return false; } @@ -2837,17 +2930,17 @@ bool CFFmpegPostproc::PreInit(CVaapiConfig &config, SDiMethods *methods) VAStatus status = vaDeriveImage(config.dpy, surface, &image); if (status != VA_STATUS_SUCCESS) { - CLog::Log(LOGNOTICE,"VAAPI::SupportsFilter vaDeriveImage not supported"); + CLog::Log(LOGWARNING,"VAAPI::SupportsFilter vaDeriveImage not supported"); use_filter = false; } if (image.format.fourcc != VA_FOURCC_NV12) { - CLog::Log(LOGNOTICE,"VAAPI::SupportsFilter image format not NV12"); + CLog::Log(LOGWARNING,"VAAPI::SupportsFilter image format not NV12"); use_filter = false; } if ((image.pitches[0] % 64) || (image.pitches[1] % 64)) { - CLog::Log(LOGNOTICE,"VAAPI::SupportsFilter patches no multiple of 64"); + CLog::Log(LOGWARNING,"VAAPI::SupportsFilter patches no multiple of 64"); use_filter = false; } CheckSuccess(vaDestroyImage(config.dpy,image.image_id)); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h index c45e97ddce..6b2b67a246 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h @@ -144,6 +144,7 @@ struct CVaapiProcessedPicture DVDVideoPicture DVDPic; VASurfaceID videoSurface; AVFrame *frame; + int id; enum { VPP_SRC, @@ -153,6 +154,19 @@ struct CVaapiProcessedPicture bool crop; }; +struct VaapiGlx +{ + Display *x11dsp; + VADisplay vadsp; + Pixmap pixmap; + GLXPixmap glPixmap; + GLenum textureTarget; + PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT; + PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT; + CVaapiProcessedPicture procPic; + bool bound; +}; + /** * Ready to render textures * Sent from COutput back to CDecoder @@ -168,6 +182,7 @@ public: : texWidth(0), texHeight(0), texture(None), valid(false), vaapi(NULL), avFrame(NULL), usefence(false), refCount(0), renderPicSection(section) { fence = None; } void Sync(); + bool CopyGlx(); DVDVideoPicture DVDPic; int texWidth, texHeight; CRect crop; @@ -182,8 +197,7 @@ private: bool usefence; GLsync fence; int refCount; - Pixmap pixmap; - GLXPixmap glPixmap; + VaapiGlx glx; CCriticalSection &renderPicSection; }; @@ -204,8 +218,10 @@ struct VaapiBufferPool std::deque<int> freeRenderPics; std::deque<int> syncRenderPics; std::deque<CVaapiProcessedPicture> processedPics; + std::deque<CVaapiProcessedPicture> processedPicsAway; std::deque<CVaapiDecodedPicture> decodedPics; CCriticalSection renderPicSec; + int procPicId; }; class COutputControlProtocol : public Protocol @@ -235,6 +251,7 @@ public: { NEWFRAME = 0, RETURNPIC, + RETURNPROCPIC, }; enum InSignal { @@ -276,6 +293,7 @@ protected: CVaapiRenderPicture* ProcessPicture(CVaapiProcessedPicture &pic); void QueueReturnPicture(CVaapiRenderPicture *pic); void ProcessReturnPicture(CVaapiRenderPicture *pic); + void ProcessReturnProcPicture(int id); bool ProcessSyncPicture(); void ReleaseProcessedPicture(CVaapiProcessedPicture &pic); void DropVppProcessedPictures(); @@ -332,6 +350,7 @@ public: int Size(); bool HasFree(); bool HasRefs(); + int NumFree(); protected: std::map<VASurfaceID, int> m_state; std::list<VASurfaceID> m_freeSurfaces; @@ -393,7 +412,7 @@ public: virtual void Close(); virtual long Release(); virtual bool CanSkipDeint(); - virtual unsigned GetAllowedReferences() { return 5; } + virtual unsigned GetAllowedReferences() { return 4; } virtual int Check(AVCodecContext* avctx); virtual const std::string Name() { return "vaapi"; } @@ -410,6 +429,7 @@ protected: bool CheckStatus(VAStatus vdp_st, int line); void FiniVAAPIOutput(); void ReturnRenderPicture(CVaapiRenderPicture *renderPic); + void ReturnProcPicture(int id); long ReleasePicReference(); bool CheckSuccess(VAStatus status); @@ -458,6 +478,7 @@ public: virtual void Flush() = 0; virtual bool Compatible(EINTERLACEMETHOD method) = 0; virtual bool DoesSync() = 0; + virtual bool WantsPic() {return true;} protected: CVaapiConfig m_config; int m_step; @@ -497,6 +518,7 @@ public: void Flush(); bool Compatible(EINTERLACEMETHOD method); bool DoesSync(); + bool WantsPic(); protected: bool CheckSuccess(VAStatus status); void Dispose(); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS/Makefile.in b/xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS/Makefile.in index 81d7b6ed4e..29ee0808ab 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS/Makefile.in +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS/Makefile.in @@ -16,7 +16,7 @@ INCLUDES += -I${prefix}/opt/android-source/libhardware/include LIBNAME=libXBMCvcodec_stagefrightICS LIB_SHARED=@abs_top_srcdir@/system/players/dvdplayer/$(LIBNAME)-$(ARCH).so -LIBS += -landroid -lEGL -lGLESv2 -L${prefix}/opt/android-libs -lstdc++ -lutils -lcutils -lstagefright -lbinder -lui -lgui -L@abs_top_srcdir@ -lxbmc +LIBS += -landroid -lEGL -lGLESv2 -L${prefix}/opt/android-libs -lstdc++ -lutils -lcutils -lstagefright -lbinder -lui -lgui -L@abs_top_srcdir@ -l@APP_NAME_LC@ all: $(LIB_SHARED) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index b835fa8c71..81a511ea81 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1214,8 +1214,12 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) XFILE::CFile file; if(pStream->codec->extradata && file.OpenForWrite(fileName)) { - file.Write(pStream->codec->extradata, pStream->codec->extradata_size); - file.Close(); + if (file.Write(pStream->codec->extradata, pStream->codec->extradata_size) != pStream->codec->extradata_size) + { + file.Close(); + XFILE::CFile::Delete(fileName); + CLog::Log(LOGDEBUG, "%s: Error saving font file \"%s\"", __FUNCTION__, fileName.c_str()); + } } } } diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp index cb745be32b..6ed1253566 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp @@ -73,7 +73,7 @@ int DllLibbluray::file_eof(BD_FILE_H *file) int64_t DllLibbluray::file_read(BD_FILE_H *file, uint8_t *buf, int64_t size) { - return static_cast<CFile*>(file->internal)->Read(buf, size); + return static_cast<CFile*>(file->internal)->Read(buf, size); // TODO: fix size cast } int64_t DllLibbluray::file_write(BD_FILE_H *file, const uint8_t *buf, int64_t size) diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp index 1b0f7e8460..8bb5c17544 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp @@ -113,12 +113,16 @@ int CDVDInputStreamFile::Read(uint8_t* buf, int buf_size) { if(!m_pFile) return -1; - unsigned int ret = m_pFile->Read(buf, buf_size); + ssize_t ret = m_pFile->Read(buf, buf_size); + + if (ret < 0) + return -1; // player will retry read in case of error until playback is stopped /* we currently don't support non completing reads */ - if( ret == 0 ) m_eof = true; + if (ret == 0) + m_eof = true; - return (int)(ret & 0xFFFFFFFF); + return (int)ret; } int64_t CDVDInputStreamFile::Seek(int64_t offset, int whence) diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp index 30e027bd52..8c846bcdfe 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp @@ -100,12 +100,16 @@ int CDVDInputStreamTV::Read(uint8_t* buf, int buf_size) { if(!m_pFile) return -1; - unsigned int ret = m_pFile->Read(buf, buf_size); + ssize_t ret = m_pFile->Read(buf, buf_size); + + if (ret < 0) + return -1; // player will retry read in case of error until playback is stopped /* we currently don't support non completing reads */ - if( ret == 0 ) m_eof = true; + if (ret == 0) + m_eof = true; - return (int)(ret & 0xFFFFFFFF); + return (int)ret; } int64_t CDVDInputStreamTV::Seek(int64_t offset, int whence) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp index 73181a4bf8..63cbe661b5 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -2112,7 +2112,7 @@ void CDVDPlayer::CheckAutoSceneSkip() /* * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. */ - m_messenger.Put(new CDVDMsgPlayerSeek(seek, true, false, true, false, true)); + m_messenger.Put(new CDVDMsgPlayerSeek(seek, true, m_omxplayer_mode, true, false, true)); /* * Seek doesn't always work reliably. Last physical seek time is recorded to prevent looping * if there was an error with seeking and it landed somewhere unexpected, perhaps back in the @@ -2130,7 +2130,7 @@ void CDVDPlayer::CheckAutoSceneSkip() /* * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. */ - m_messenger.Put(new CDVDMsgPlayerSeek(cut.end + 1, true, false, true, false, true)); + m_messenger.Put(new CDVDMsgPlayerSeek(cut.end + 1, true, m_omxplayer_mode, true, false, true)); /* * Each commercial break is only skipped once so poorly detected commercial breaks can be * manually re-entered. Start and end are recorded to prevent looping and to allow seeking back @@ -3411,7 +3411,7 @@ void CDVDPlayer::UpdateClockMaster() void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) { double startpts; - if(accurate) + if(accurate && !m_omxplayer_mode) startpts = pts; else startpts = DVD_NOPTS_VALUE; diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp index e039c2b938..5a758ab714 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -164,7 +164,7 @@ CDVDPlayerVideo::CDVDPlayerVideo( CDVDClock* pClock CDVDPlayerVideo::~CDVDPlayerVideo() { StopThread(); - g_VideoReferenceClock.StopThread(); + g_VideoReferenceClock.Stop(); } double CDVDPlayerVideo::GetOutputDelay() @@ -205,9 +205,6 @@ bool CDVDPlayerVideo::OpenStream( CDVDStreamInfo &hint ) if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") && !g_VideoReferenceClock.IsRunning()) { g_VideoReferenceClock.Create(); - //we have to wait for the clock to start otherwise alsa can cause trouble - if (!g_VideoReferenceClock.WaitStarted(2000)) - CLog::Log(LOGDEBUG, "g_VideoReferenceClock didn't start in time"); } if(m_messageQueue.IsInited()) diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp index 9e98207cbf..6c7fcc2c9c 100644 --- a/xbmc/cores/omxplayer/OMXAudio.cpp +++ b/xbmc/cores/omxplayer/OMXAudio.cpp @@ -124,17 +124,17 @@ bool COMXAudio::PortSettingsChanged() if(!m_omx_mixer.Initialize("OMX.broadcom.audio_mixer", OMX_IndexParamAudioInit)) return false; } - if(CSettings::Get().GetBool("audiooutput.dualaudio")) + if(CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") { if(!m_omx_splitter.Initialize("OMX.broadcom.audio_splitter", OMX_IndexParamAudioInit)) return false; } - if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") + if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") { if(!m_omx_render_analog.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) return false; } - if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue") + if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:HDMI") { if(!m_omx_render_hdmi.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) return false; @@ -252,7 +252,7 @@ bool COMXAudio::PortSettingsChanged() { // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync - if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || (CSettings::Get().GetBool("audiooutput.dualaudio") && CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue")) + if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") { OMX_CONFIG_BOOLEANTYPE configBool; OMX_INIT_STRUCTURE(configBool); @@ -278,7 +278,7 @@ bool COMXAudio::PortSettingsChanged() { // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync - if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || (CSettings::Get().GetBool("audiooutput.dualaudio") && CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue")) + if(CSettings::Get().GetBool("videoplayer.usedisplayasclock")) { OMX_CONFIG_BOOLEANTYPE configBool; OMX_INIT_STRUCTURE(configBool); @@ -601,7 +601,7 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo CAEChannelInfo stdLayout = (enum AEStdChLayout)CSettings::Get().GetInt("audiooutput.channels"); // ignore layout setting for analogue - if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") + if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") stdLayout = AE_CH_LAYOUT_2_0; // force out layout to stereo if input is not multichannel - it gives the receiver a chance to upmix diff --git a/xbmc/cores/omxplayer/OMXImage.cpp b/xbmc/cores/omxplayer/OMXImage.cpp index 3fbea3b445..aa413b95af 100644 --- a/xbmc/cores/omxplayer/OMXImage.cpp +++ b/xbmc/cores/omxplayer/OMXImage.cpp @@ -206,7 +206,8 @@ bool COMXImage::CreateThumb(const std::string& srcFile, unsigned int maxHeight, COMXImageReEnc reenc; void *pDestBuffer; unsigned int nDestSize; - if (URIUtils::HasExtension(srcFile, ".jpg|.tbn") && file.ReadFile(srcFile) && reenc.ReEncode(file, maxWidth, maxHeight, pDestBuffer, nDestSize)) + int orientation = additional_info == "flipped" ? 1:0; + if (URIUtils::HasExtension(srcFile, ".jpg|.tbn") && file.ReadFile(srcFile, orientation) && reenc.ReEncode(file, maxWidth, maxHeight, pDestBuffer, nDestSize)) { XFILE::CFile outfile; if (outfile.OpenForWrite(destFile, true)) @@ -591,7 +592,7 @@ static void inline SKIPN(uint8_t * &p, unsigned int n) p += n; } -OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height) +OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height, int orientation) { OMX_IMAGE_CODINGTYPE eCompressionFormat = OMX_IMAGE_CodingMax; bool progressive = false; @@ -808,7 +809,7 @@ OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned { SKIPN(p, 1 * 7); readBits += 7; - m_orientation = READ8(p); + m_orientation = READ8(p)-1; readBits += 1; SKIPN(p, 1 * 2); readBits += 2; @@ -817,7 +818,7 @@ OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned { SKIPN(p, 1 * 6); readBits += 6; - m_orientation = READ8(p); + m_orientation = READ8(p)-1; readBits += 1; SKIPN(p, 1 * 3); readBits += 3; @@ -847,7 +848,9 @@ OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned } } - if(m_orientation > 8) + // apply input orientation + m_orientation = m_orientation ^ orientation; + if(m_orientation < 0 || m_orientation >= 8) m_orientation = 0; if(eCompressionFormat == OMX_IMAGE_CodingMax) @@ -871,7 +874,7 @@ OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned } -bool COMXImageFile::ReadFile(const std::string& inputFile) +bool COMXImageFile::ReadFile(const std::string& inputFile, int orientation) { XFILE::CFile m_pFile; m_filename = inputFile.c_str(); @@ -902,7 +905,7 @@ bool COMXImageFile::ReadFile(const std::string& inputFile) m_pFile.Read(m_image_buffer, m_image_size); m_pFile.Close(); - OMX_IMAGE_CODINGTYPE eCompressionFormat = GetCodingType(m_width, m_height); + OMX_IMAGE_CODINGTYPE eCompressionFormat = GetCodingType(m_width, m_height, orientation); if(eCompressionFormat != OMX_IMAGE_CodingJPEG) { CLog::Log(LOGERROR, "%s::%s %s GetCodingType=0x%x\n", CLASSNAME, __func__, inputFile.c_str(), eCompressionFormat); @@ -1658,7 +1661,7 @@ bool COMXImageReEnc::HandlePortSettingChange(unsigned int resize_width, unsigned item.metadata.eValueCharset = OMX_MetadataCharsetASCII; item.metadata.sLanguageCountry = 0; item.metadata.nValueMaxSize = sizeof(item.metadata_space); - sprintf((char *)item.metadata.nValue, "%d", orientation); + sprintf((char *)item.metadata.nValue, "%d", orientation + 1); item.metadata.nValueSizeUsed = strlen((char *)item.metadata.nValue); omx_err = m_omx_encoder.SetParameter(OMX_IndexConfigMetadataItem, &item); diff --git a/xbmc/cores/omxplayer/OMXImage.h b/xbmc/cores/omxplayer/OMXImage.h index 90e513afac..a93aa82663 100644 --- a/xbmc/cores/omxplayer/OMXImage.h +++ b/xbmc/cores/omxplayer/OMXImage.h @@ -94,7 +94,7 @@ class COMXImageFile public: COMXImageFile(); virtual ~COMXImageFile(); - bool ReadFile(const std::string& inputFile); + bool ReadFile(const std::string& inputFile, int orientation = 0); int GetOrientation() { return m_orientation; }; unsigned int GetWidth() { return m_width; }; unsigned int GetHeight() { return m_height; }; @@ -102,7 +102,7 @@ public: const uint8_t *GetImageBuffer() { return (const uint8_t *)m_image_buffer; }; const char *GetFilename() { return m_filename; }; protected: - OMX_IMAGE_CODINGTYPE GetCodingType(unsigned int &width, unsigned int &height); + OMX_IMAGE_CODINGTYPE GetCodingType(unsigned int &width, unsigned int &height, int orientation); uint8_t *m_image_buffer; unsigned long m_image_size; unsigned int m_width; diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp index 2c25fd93a5..ac838ce9c0 100644 --- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp @@ -806,7 +806,7 @@ void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height, f if(!g_renderManager.Configure(width, height, iDisplayWidth, iDisplayHeight, m_fFrameRate, flags, format, 0, - m_hints.orientation, 0)) + m_hints.orientation, 3)) { CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); return; diff --git a/xbmc/cores/paplayer/DVDPlayerCodec.cpp b/xbmc/cores/paplayer/DVDPlayerCodec.cpp index c619b32535..fd7716ba6b 100644 --- a/xbmc/cores/paplayer/DVDPlayerCodec.cpp +++ b/xbmc/cores/paplayer/DVDPlayerCodec.cpp @@ -20,7 +20,7 @@ #include "DVDPlayerCodec.h" #include "cores/AudioEngine/Utils/AEUtil.h" -#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h" +#include "cores/AudioEngine/AEResampleFactory.h" #include "cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.h" #include "cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h" @@ -234,17 +234,17 @@ bool DVDPlayerCodec::Init(const std::string &strFile, unsigned int filecache) if (NeedConvert(m_DataFormat)) { m_needConvert = true; - m_pResampler = new ActiveAE::CActiveAEResample(); - m_pResampler->Init(ActiveAE::CActiveAEResample::GetAVChannelLayout(m_ChannelInfo), + m_pResampler = ActiveAE::CAEResampleFactory::Create(); + m_pResampler->Init(CAEUtil::GetAVChannelLayout(m_ChannelInfo), m_ChannelInfo.Count(), m_SampleRate, - ActiveAE::CActiveAEResample::GetAVSampleFormat(AE_FMT_FLOAT), + CAEUtil::GetAVSampleFormat(AE_FMT_FLOAT), CAEUtil::DataFormatToUsedBits(AE_FMT_FLOAT), CAEUtil::DataFormatToDitherBits(AE_FMT_FLOAT), - ActiveAE::CActiveAEResample::GetAVChannelLayout(m_ChannelInfo), + CAEUtil::GetAVChannelLayout(m_ChannelInfo), m_ChannelInfo.Count(), m_SampleRate, - ActiveAE::CActiveAEResample::GetAVSampleFormat(m_DataFormat), + CAEUtil::GetAVSampleFormat(m_DataFormat), CAEUtil::DataFormatToUsedBits(m_DataFormat), CAEUtil::DataFormatToDitherBits(m_DataFormat), false, diff --git a/xbmc/cores/paplayer/DVDPlayerCodec.h b/xbmc/cores/paplayer/DVDPlayerCodec.h index 469e2ffaa1..576fb97cb2 100644 --- a/xbmc/cores/paplayer/DVDPlayerCodec.h +++ b/xbmc/cores/paplayer/DVDPlayerCodec.h @@ -29,7 +29,7 @@ namespace ActiveAE { - class CActiveAEResample; + class IAEResample; }; class DVDPlayerCodec : public ICodec @@ -71,7 +71,7 @@ private: bool m_bInited; bool m_bCanSeek; - ActiveAE::CActiveAEResample *m_pResampler; + ActiveAE::IAEResample *m_pResampler; uint8_t *m_audioPlanes[8]; int m_planes; bool m_needConvert; diff --git a/xbmc/cores/paplayer/OggCallback.cpp b/xbmc/cores/paplayer/OggCallback.cpp index 6b26008e79..20d8687f1f 100644 --- a/xbmc/cores/paplayer/OggCallback.cpp +++ b/xbmc/cores/paplayer/OggCallback.cpp @@ -46,7 +46,10 @@ size_t COggCallback::ReadCallback(void *ptr, size_t size, size_t nmemb, void *da if (!pCallback) return 0; - return pCallback->m_file.Read(ptr, size*nmemb); + const ssize_t res = pCallback->m_file.Read(ptr, size*nmemb); + if (res < 0) + return 0; + return res; } int COggCallback::SeekCallback(void *datasource, ogg_int64_t offset, int whence) diff --git a/xbmc/cores/paplayer/PCMCodec.cpp b/xbmc/cores/paplayer/PCMCodec.cpp index 9a6ed2ec65..242d3ae23c 100644 --- a/xbmc/cores/paplayer/PCMCodec.cpp +++ b/xbmc/cores/paplayer/PCMCodec.cpp @@ -73,7 +73,7 @@ int PCMCodec::ReadPCM(BYTE *pBuffer, int size, int *actualsize) { *actualsize = 0; - int iAmountRead = m_file.Read(pBuffer, 2 * (size / 2)); + ssize_t iAmountRead = m_file.Read(pBuffer, 2 * (size / 2)); if (iAmountRead > 0) { uint16_t *buffer = (uint16_t*) pBuffer; diff --git a/xbmc/cores/paplayer/SPCCodec.cpp b/xbmc/cores/paplayer/SPCCodec.cpp index 7fad97c81e..c06fb5caff 100644 --- a/xbmc/cores/paplayer/SPCCodec.cpp +++ b/xbmc/cores/paplayer/SPCCodec.cpp @@ -103,7 +103,7 @@ bool SPCCodec::Init(const std::string &strFile, unsigned int filecache) return false; } m_szBuffer = new char[0x10200]; - if (!file.Read(m_szBuffer,0x10200)) + if (file.Read(m_szBuffer,0x10200) <= 0) { delete[] m_szBuffer; m_szBuffer = NULL; diff --git a/xbmc/epg/GUIEPGGridContainer.cpp b/xbmc/epg/GUIEPGGridContainer.cpp index 8a9faed520..bb11a5ea1d 100644 --- a/xbmc/epg/GUIEPGGridContainer.cpp +++ b/xbmc/epg/GUIEPGGridContainer.cpp @@ -748,26 +748,25 @@ bool CGUIEPGGridContainer::OnMessage(CGUIMessage& message) } /* Create Channel items */ - int iLastChannelNumber = -1; + int iLastChannelID = -1; ItemsPtr itemsPointer; itemsPointer.start = 0; for (unsigned int i = 0; i < m_programmeItems.size(); ++i) { const CEpgInfoTag* tag = ((CFileItem*)m_programmeItems[i].get())->GetEPGInfoTag(); - int iCurrentChannelNumber = tag->PVRChannelNumber(); - if (iCurrentChannelNumber != iLastChannelNumber) + CPVRChannelPtr channel = tag->ChannelTag(); + if (!channel) + continue; + int iCurrentChannelID = channel->ChannelID(); + if (iCurrentChannelID != iLastChannelID) { - CPVRChannelPtr channel = tag->ChannelTag(); - if (!channel) - continue; - if (i > 0) { itemsPointer.stop = i-1; m_epgItemsPtr.push_back(itemsPointer); itemsPointer.start = i; } - iLastChannelNumber = iCurrentChannelNumber; + iLastChannelID = iCurrentChannelID; CGUIListItemPtr item(new CFileItem(*channel)); m_channelItems.push_back(item); } diff --git a/xbmc/filesystem/AFPFile.cpp b/xbmc/filesystem/AFPFile.cpp index e4b48c9a7a..b3047bb138 100644 --- a/xbmc/filesystem/AFPFile.cpp +++ b/xbmc/filesystem/AFPFile.cpp @@ -530,11 +530,11 @@ int CAFPFile::Stat(const CURL& url, struct __stat64* buffer) return iResult; } -unsigned int CAFPFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CAFPFile::Read(void *lpBuf, size_t uiBufSize) { CSingleLock lock(gAfpConnection); if (m_pFp == NULL || !m_pAfpVol) - return 0; + return -1; if (uiBufSize > AFP_MAX_READ_SIZE) uiBufSize = AFP_MAX_READ_SIZE; @@ -548,7 +548,7 @@ unsigned int CAFPFile::Read(void *lpBuf, int64_t uiBufSize) #endif int eof = 0; - int bytesRead = gAfpConnection.GetImpl()->afp_wrap_read(m_pAfpVol, + ssize_t bytesRead = gAfpConnection.GetImpl()->afp_wrap_read(m_pAfpVol, name, (char *)lpBuf,(size_t)uiBufSize, m_fileOffset, m_pFp, &eof); if (bytesRead > 0) m_fileOffset += bytesRead; @@ -556,10 +556,10 @@ unsigned int CAFPFile::Read(void *lpBuf, int64_t uiBufSize) if (bytesRead < 0) { CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno)); - return 0; + return -1; } - return (unsigned int)bytesRead; + return bytesRead; } int64_t CAFPFile::Seek(int64_t iFilePosition, int iWhence) @@ -610,13 +610,13 @@ void CAFPFile::Close() } } -int CAFPFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CAFPFile::Write(const void* lpBuf, size_t uiBufSize) { CSingleLock lock(gAfpConnection); if (m_pFp == NULL || !m_pAfpVol) return -1; - int numberOfBytesWritten = 0; + ssize_t numberOfBytesWritten = 0; uid_t uid; gid_t gid; @@ -631,7 +631,7 @@ int CAFPFile::Write(const void* lpBuf, int64_t uiBufSize) name = m_pFp->basename; #endif numberOfBytesWritten = gAfpConnection.GetImpl()->afp_wrap_write(m_pAfpVol, - name, (const char *)lpBuf, (size_t)uiBufSize, m_fileOffset, m_pFp, uid, gid); + name, (const char *)lpBuf, uiBufSize, m_fileOffset, m_pFp, uid, gid); if (numberOfBytesWritten > 0) m_fileOffset += numberOfBytesWritten; diff --git a/xbmc/filesystem/AFPFile.h b/xbmc/filesystem/AFPFile.h index 1a7e8d2bac..9880b26cd6 100644 --- a/xbmc/filesystem/AFPFile.h +++ b/xbmc/filesystem/AFPFile.h @@ -100,14 +100,14 @@ public: virtual ~CAFPFile(); virtual void Close(); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); virtual int Stat(struct __stat64* buffer); virtual int64_t GetLength(); virtual int64_t GetPosition(); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false); virtual bool Delete(const CURL& url); diff --git a/xbmc/filesystem/APKFile.cpp b/xbmc/filesystem/APKFile.cpp index dafbdf1fd0..5eb70e3094 100644 --- a/xbmc/filesystem/APKFile.cpp +++ b/xbmc/filesystem/APKFile.cpp @@ -175,9 +175,12 @@ int64_t CAPKFile::Seek(int64_t iFilePosition, int iWhence) return m_file_pos; } -unsigned int CAPKFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CAPKFile::Read(void *lpBuf, size_t uiBufSize) { - int bytes_read = uiBufSize; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + + ssize_t bytes_read = uiBufSize; if (m_zip_archive && m_zip_file) { // check for a read pas EOF and clamp it to EOF @@ -191,7 +194,7 @@ unsigned int CAPKFile::Read(void *lpBuf, int64_t uiBufSize) bytes_read = 0; } - return (unsigned int)bytes_read; + return bytes_read; } int CAPKFile::Stat(struct __stat64* buffer) diff --git a/xbmc/filesystem/APKFile.h b/xbmc/filesystem/APKFile.h index 99a4f4d025..c966607fb4 100644 --- a/xbmc/filesystem/APKFile.h +++ b/xbmc/filesystem/APKFile.h @@ -37,7 +37,7 @@ namespace XFILE virtual bool Exists(const CURL& url); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int Stat(struct __stat64* buffer); virtual int Stat(const CURL& url, struct __stat64* buffer); virtual int64_t GetLength(); diff --git a/xbmc/filesystem/AndroidAppDirectory.cpp b/xbmc/filesystem/AndroidAppDirectory.cpp index 1699fb4924..b1a07b793c 100644 --- a/xbmc/filesystem/AndroidAppDirectory.cpp +++ b/xbmc/filesystem/AndroidAppDirectory.cpp @@ -30,6 +30,7 @@ #include "utils/log.h" #include "utils/StringUtils.h" #include "URL.h" +#include "CompileInfo.h" using namespace XFILE; using namespace std; @@ -47,6 +48,10 @@ bool CAndroidAppDirectory::GetDirectory(const CURL& url, CFileItemList &items) std::string dirname = url.GetFileName(); URIUtils::RemoveSlashAtEnd(dirname); CLog::Log(LOGDEBUG, "CAndroidAppDirectory::GetDirectory: %s",dirname.c_str()); + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + std::string className = "org.xbmc." + appName; + if (dirname == "apps") { vector<androidPackage> applications = CXBMCApp::GetApplications(); @@ -57,7 +62,7 @@ bool CAndroidAppDirectory::GetDirectory(const CURL& url, CFileItemList &items) } for(std::vector<androidPackage>::iterator i = applications.begin(); i != applications.end(); ++i) { - if ((*i).packageName == "org.xbmc.xbmc") + if ((*i).packageName == className.c_str()) continue; CFileItemPtr pItem(new CFileItem((*i).packageName)); pItem->m_bIsFolder = false; diff --git a/xbmc/filesystem/AndroidAppFile.cpp b/xbmc/filesystem/AndroidAppFile.cpp index 0c7361df3b..439780db52 100644 --- a/xbmc/filesystem/AndroidAppFile.cpp +++ b/xbmc/filesystem/AndroidAppFile.cpp @@ -74,10 +74,11 @@ bool CFileAndroidApp::Exists(const CURL& url) return false; } -unsigned int CFileAndroidApp::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CFileAndroidApp::Read(void* lpBuf, size_t uiBufSize) { - CXBMCApp::GetIcon(m_appname, lpBuf, uiBufSize); - return uiBufSize; + if(CXBMCApp::GetIcon(m_appname, lpBuf, uiBufSize)) + return uiBufSize; // FIXME: not full buffer may be used + return -1; } void CFileAndroidApp::Close() diff --git a/xbmc/filesystem/AndroidAppFile.h b/xbmc/filesystem/AndroidAppFile.h index 17d0300dec..a7099fd7ad 100644 --- a/xbmc/filesystem/AndroidAppFile.h +++ b/xbmc/filesystem/AndroidAppFile.h @@ -37,7 +37,7 @@ public: virtual int Stat(const CURL& url, struct __stat64* buffer); /*! \brief Return 32bit rgba raw bitmap. */ - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual void Close(); virtual int64_t GetLength(); virtual int64_t Seek(int64_t, int) {return -1;}; diff --git a/xbmc/filesystem/BlurayFile.cpp b/xbmc/filesystem/BlurayFile.cpp new file mode 100644 index 0000000000..2731f1cc8f --- /dev/null +++ b/xbmc/filesystem/BlurayFile.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" +#ifdef HAVE_LIBBLURAY +#include "BlurayFile.h" +#include "URL.h" +#include "utils/StringUtils.h" + +namespace XFILE +{ + + CBlurayFile::CBlurayFile(void) + { + } + + CBlurayFile::~CBlurayFile(void) + { + Close(); + } + + CURL CBlurayFile::RemoveProtocol(const CURL& url) + { + assert(url.IsProtocol("bluray")); + + std::string host = url.GetHostName(); + std::string filename = url.GetFileName(); + if (host.empty() || filename.empty()) + return CURL(); + return CURL(host.append(filename)); + } + + bool CBlurayFile::Open(const CURL& url) + { + return m_file.Open(RemoveProtocol(url)); + } + + bool CBlurayFile::Exists(const CURL& url) + { + return m_file.Exists(RemoveProtocol(url)); + } + + int CBlurayFile::Stat(const CURL& url, struct __stat64* buffer) + { + return m_file.Stat(RemoveProtocol(url), buffer); + } + + ssize_t CBlurayFile::Read(void* lpBuf, size_t uiBufSize) + { + return m_file.Read(lpBuf, uiBufSize); + } + + int64_t CBlurayFile::Seek(int64_t iFilePosition, int iWhence /*=SEEK_SET*/) + { + return m_file.Seek(iFilePosition, iWhence); + } + + void CBlurayFile::Close() + { + m_file.Close(); + } + + int64_t CBlurayFile::GetPosition() + { + return m_file.GetPosition(); + } + + int64_t CBlurayFile::GetLength() + { + return m_file.GetLength(); + } +} /* namespace XFILE */ +#endif diff --git a/xbmc/filesystem/BlurayFile.h b/xbmc/filesystem/BlurayFile.h new file mode 100644 index 0000000000..e05b9de026 --- /dev/null +++ b/xbmc/filesystem/BlurayFile.h @@ -0,0 +1,52 @@ +#pragma once + +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "File.h" +#include "IFile.h" + + +namespace XFILE +{ + + class CBlurayFile : public IFile + { + public: + CBlurayFile(); + virtual ~CBlurayFile(); + + virtual bool Open(const CURL& url); + virtual bool Exists(const CURL& url); + virtual int Stat(const CURL& url, struct __stat64* buffer); + + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); + virtual void Close(); + virtual int64_t GetPosition(); + virtual int64_t GetLength(); + + protected: + CFile m_file; + + private: + CURL RemoveProtocol(const CURL& url); + }; +} diff --git a/xbmc/filesystem/CDDAFile.cpp b/xbmc/filesystem/CDDAFile.cpp index 5e3970f18c..b3405c49eb 100644 --- a/xbmc/filesystem/CDDAFile.cpp +++ b/xbmc/filesystem/CDDAFile.cpp @@ -114,16 +114,19 @@ int CFileCDDA::Stat(const CURL& url, struct __stat64* buffer) return -1; } -unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CFileCDDA::Read(void* lpBuf, size_t uiBufSize) { if (!m_pCdIo || !g_mediaManager.IsDiscInDrive()) - return 0; + return -1; + + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; // limit number of sectors that fits in buffer by m_iSectorCount int iSectorCount = std::min((int)uiBufSize / CDIO_CD_FRAMESIZE_RAW, m_iSectorCount); if (iSectorCount <= 0) - return 0; + return -1; // Are there enough sectors left to read if (m_lsnCurrent + iSectorCount > m_lsnEnd) @@ -150,7 +153,7 @@ unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize) if (iSectorCount <= 10) { CLog::Log(LOGERROR, "file cdda: Reading %d sectors of audio data starting at lsn %d failed with error code %i", iSectorCount, m_lsnCurrent, iret); - return 0; + return -1; } iSectorCount = 10; diff --git a/xbmc/filesystem/CDDAFile.h b/xbmc/filesystem/CDDAFile.h index 41771a166c..801b02618c 100644 --- a/xbmc/filesystem/CDDAFile.h +++ b/xbmc/filesystem/CDDAFile.h @@ -37,7 +37,7 @@ public: virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/CacheStrategy.cpp b/xbmc/filesystem/CacheStrategy.cpp index 095d3fb25f..acc86afd35 100644 --- a/xbmc/filesystem/CacheStrategy.cpp +++ b/xbmc/filesystem/CacheStrategy.cpp @@ -20,17 +20,21 @@ #include "threads/SystemClock.h" #include "CacheStrategy.h" -#ifdef TARGET_POSIX -#include "PlatformInclude.h" -#endif +#include "IFile.h" #include "Util.h" #include "utils/log.h" #include "threads/SingleLock.h" #include "utils/TimeUtils.h" #include "SpecialProtocol.h" -#ifdef TARGET_WINDOWS #include "PlatformDefs.h" //for PRIdS, PRId64 -#endif +#include "URL.h" +#if defined(TARGET_POSIX) +#include "posix/PosixFile.h" +#define CacheLocalFile CPosixFile +#elif defined(TARGET_WINDOWS) +#include "win32/Win32File.h" +#define CacheLocalFile CWin32File +#endif // TARGET_WINDOWS using namespace XFILE; @@ -58,8 +62,8 @@ void CCacheStrategy::ClearEndOfInput() } CSimpleFileCache::CSimpleFileCache() - : m_hCacheFileRead(NULL) - , m_hCacheFileWrite(NULL) + : m_cacheFileRead(new CacheLocalFile()) + , m_cacheFileWrite(new CacheLocalFile()) , m_hDataAvailEvent(NULL) , m_nStartPosition(0) , m_nWritePosition(0) @@ -69,6 +73,8 @@ CSimpleFileCache::CSimpleFileCache() CSimpleFileCache::~CSimpleFileCache() { Close(); + delete m_cacheFileRead; + delete m_cacheFileWrite; } int CSimpleFileCache::Open() @@ -77,38 +83,26 @@ int CSimpleFileCache::Open() m_hDataAvailEvent = new CEvent; - std::string fileName = CSpecialProtocol::TranslatePath(CUtil::GetNextFilename("special://temp/filecache%03d.cache", 999)); - if(fileName.empty()) + m_filename = CSpecialProtocol::TranslatePath(CUtil::GetNextFilename("special://temp/filecache%03d.cache", 999)); + if (m_filename.empty()) { CLog::Log(LOGERROR, "%s - Unable to generate a new filename", __FUNCTION__); Close(); return CACHE_RC_ERROR; } - m_hCacheFileWrite = CreateFile(fileName.c_str() - , GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE - , NULL - , CREATE_ALWAYS - , FILE_ATTRIBUTE_NORMAL - , NULL); + CURL fileURL(m_filename); - if(m_hCacheFileWrite == INVALID_HANDLE_VALUE) + if (!m_cacheFileWrite->OpenForWrite(fileURL, false)) { - CLog::Log(LOGERROR, "%s - failed to create file %s with error code %d", __FUNCTION__, fileName.c_str(), GetLastError()); + CLog::LogF(LOGERROR, "failed to create file \"%s\" for writing", m_filename.c_str()); Close(); return CACHE_RC_ERROR; } - m_hCacheFileRead = CreateFile(fileName.c_str() - , GENERIC_READ, FILE_SHARE_WRITE - , NULL - , OPEN_EXISTING - , FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE - , NULL); - - if(m_hCacheFileRead == INVALID_HANDLE_VALUE) + if (!m_cacheFileRead->Open(fileURL)) { - CLog::Log(LOGERROR, "%s - failed to open file %s with error code %d", __FUNCTION__, fileName.c_str(), GetLastError()); + CLog::LogF(LOGERROR, "failed to open file \"%s\" for reading", m_filename.c_str()); Close(); return CACHE_RC_ERROR; } @@ -123,33 +117,35 @@ void CSimpleFileCache::Close() m_hDataAvailEvent = NULL; - if (m_hCacheFileWrite) - CloseHandle(m_hCacheFileWrite); - - m_hCacheFileWrite = NULL; + m_cacheFileWrite->Close(); + m_cacheFileRead->Close(); - if (m_hCacheFileRead) - CloseHandle(m_hCacheFileRead); + if (!m_cacheFileRead->Delete(CURL(m_filename))) + CLog::LogF(LOGWARNING, "failed to delete temporary file \"%s\"", m_filename.c_str()); - m_hCacheFileRead = NULL; + m_filename.clear(); } int CSimpleFileCache::WriteToCache(const char *pBuffer, size_t iSize) { - DWORD iWritten=0; - if (!WriteFile(m_hCacheFileWrite, pBuffer, iSize, &iWritten, NULL)) + size_t written = 0; + while (iSize > 0) { - CLog::Log(LOGERROR, "%s - failed to write to file. err: %u", - __FUNCTION__, GetLastError()); - return CACHE_RC_ERROR; + const ssize_t lastWritten = m_cacheFileWrite->Write(pBuffer, (iSize > SSIZE_MAX) ? SSIZE_MAX : iSize); + if (lastWritten <= 0) + { + CLog::LogF(LOGERROR, "failed to write to file"); + return CACHE_RC_ERROR; + } + m_nWritePosition += lastWritten; + iSize -= lastWritten; + written += lastWritten; } - m_nWritePosition += iWritten; - // when reader waits for data it will wait on the event. m_hDataAvailEvent->Set(); - return iWritten; + return written; } int64_t CSimpleFileCache::GetAvailableRead() @@ -160,24 +156,31 @@ int64_t CSimpleFileCache::GetAvailableRead() int CSimpleFileCache::ReadFromCache(char *pBuffer, size_t iMaxSize) { int64_t iAvailable = GetAvailableRead(); - if ( iAvailable <= 0 ) { + if ( iAvailable <= 0 ) return m_bEndOfInput? 0 : CACHE_RC_WOULD_BLOCK; - } - if (iMaxSize > (size_t)iAvailable) - iMaxSize = (size_t)iAvailable; + size_t toRead = ((int64_t)iMaxSize > iAvailable) ? (size_t)iAvailable : iMaxSize; - DWORD iRead = 0; - if (!ReadFile(m_hCacheFileRead, pBuffer, iMaxSize, &iRead, NULL)) { - CLog::Log(LOGERROR,"CSimpleFileCache::ReadFromCache - failed to read %" PRIdS" bytes.", iMaxSize); - return CACHE_RC_ERROR; + size_t readBytes = 0; + while (toRead > 0) + { + const ssize_t lastRead = m_cacheFileRead->Read(pBuffer, (toRead > SSIZE_MAX) ? SSIZE_MAX : toRead); + if (lastRead == 0) + break; + if (lastRead < 0) + { + CLog::LogF(LOGERROR, "failed to read from file"); + return CACHE_RC_ERROR; + } + m_nReadPosition += lastRead; + toRead -= lastRead; + readBytes += lastRead; } - m_nReadPosition += iRead; - if (iRead > 0) + if (readBytes > 0) m_space.Set(); - return iRead; + return readBytes; } int64_t CSimpleFileCache::WaitForData(unsigned int iMinAvail, unsigned int iMillis) @@ -215,13 +218,13 @@ int64_t CSimpleFileCache::Seek(int64_t iFilePosition) return CACHE_RC_ERROR; } - LARGE_INTEGER pos; - pos.QuadPart = iTarget; - - if(!SetFilePointerEx(m_hCacheFileRead, pos, NULL, FILE_BEGIN)) + m_nReadPosition = m_cacheFileRead->Seek(iTarget, SEEK_SET); + if (m_nReadPosition != iTarget) + { + CLog::LogF(LOGERROR, "can't seek file"); return CACHE_RC_ERROR; + } - m_nReadPosition = iTarget; m_space.Set(); return iFilePosition; @@ -229,21 +232,15 @@ int64_t CSimpleFileCache::Seek(int64_t iFilePosition) void CSimpleFileCache::Reset(int64_t iSourcePosition, bool clearAnyway) { - LARGE_INTEGER pos; if (!clearAnyway && IsCachedPosition(iSourcePosition)) { - pos.QuadPart = m_nReadPosition = iSourcePosition - m_nStartPosition; - SetFilePointerEx(m_hCacheFileRead, pos, NULL, FILE_BEGIN); + m_nReadPosition = m_cacheFileRead->Seek(iSourcePosition - m_nStartPosition, SEEK_SET); return; } - pos.QuadPart = 0; - - SetFilePointerEx(m_hCacheFileWrite, pos, NULL, FILE_BEGIN); - SetFilePointerEx(m_hCacheFileRead, pos, NULL, FILE_BEGIN); m_nStartPosition = iSourcePosition; - m_nReadPosition = 0; - m_nWritePosition = 0; + m_nWritePosition = m_cacheFileWrite->Seek(0, SEEK_SET); + m_nReadPosition = m_cacheFileRead->Seek(0, SEEK_SET); } void CSimpleFileCache::EndOfInput() diff --git a/xbmc/filesystem/CacheStrategy.h b/xbmc/filesystem/CacheStrategy.h index 9c2c28be42..9ea7274e87 100644 --- a/xbmc/filesystem/CacheStrategy.h +++ b/xbmc/filesystem/CacheStrategy.h @@ -23,11 +23,7 @@ #define XFILECACHESTRATEGY_H #include <stdint.h> -#ifdef TARGET_POSIX -#include "PlatformDefs.h" -#include "XHandlePublic.h" -#include "XFileUtils.h" -#endif +#include <string> #include "threads/CriticalSection.h" #include "threads/Event.h" @@ -38,6 +34,8 @@ namespace XFILE { #define CACHE_RC_WOULD_BLOCK -2 #define CACHE_RC_TIMEOUT -3 +class IFile; // forward declaration + class CCacheStrategy{ public: CCacheStrategy(); @@ -95,8 +93,9 @@ public: int64_t GetAvailableRead(); protected: - HANDLE m_hCacheFileRead; - HANDLE m_hCacheFileWrite; + std::string m_filename; + IFile* m_cacheFileRead; + IFile* m_cacheFileWrite; CEvent* m_hDataAvailEvent; volatile int64_t m_nStartPosition; volatile int64_t m_nWritePosition; diff --git a/xbmc/filesystem/CurlFile.cpp b/xbmc/filesystem/CurlFile.cpp index 9292d7b811..8408762c79 100644 --- a/xbmc/filesystem/CurlFile.cpp +++ b/xbmc/filesystem/CurlFile.cpp @@ -863,16 +863,14 @@ bool CCurlFile::Download(const std::string& strURL, const std::string& strFileNa strFileName.c_str(), GetLastError()); return false; } - if (strData.size()) - file.Write(strData.c_str(), strData.size()); - file.Close(); + ssize_t written = 0; + if (strData.size() > 0) + written = file.Write(strData.c_str(), strData.size()); if (pdwSize != NULL) - { - *pdwSize = strData.size(); - } + *pdwSize = written > 0 ? written : 0; - return true; + return written == strData.size(); } // Detect whether we are "online" or not! Very simple and dirty! @@ -1027,7 +1025,7 @@ bool CCurlFile::OpenForWrite(const CURL& url, bool bOverWrite) return true; } -int CCurlFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CCurlFile::Write(const void* lpBuf, size_t uiBufSize) { if (!(m_opened && m_forWrite) || m_inError) return -1; @@ -1388,7 +1386,7 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer) return 0; } -unsigned int CCurlFile::CReadState::Read(void* lpBuf, int64_t uiBufSize) +unsigned int CCurlFile::CReadState::Read(void* lpBuf, size_t uiBufSize) { /* only request 1 byte, for truncated reads (only if not eof) */ if((m_fileSize == 0 || m_filePos < m_fileSize) && !FillBuffer(1)) @@ -1408,7 +1406,7 @@ unsigned int CCurlFile::CReadState::Read(void* lpBuf, int64_t uiBufSize) if (!m_stillRunning && (m_fileSize == 0 || m_filePos != m_fileSize)) { CLog::Log(LOGWARNING, "%s - Transfer ended before entire file was retrieved pos %" PRId64", size %" PRId64, __FUNCTION__, m_filePos, m_fileSize); - return 0; + return -1; } return 0; diff --git a/xbmc/filesystem/CurlFile.h b/xbmc/filesystem/CurlFile.h index 123dae6dff..1cc7bc376e 100644 --- a/xbmc/filesystem/CurlFile.h +++ b/xbmc/filesystem/CurlFile.h @@ -57,8 +57,8 @@ namespace XFILE virtual int Stat(const CURL& url, struct __stat64* buffer); virtual void Close(); virtual bool ReadString(char *szLine, int iLineLength) { return m_state->ReadString(szLine, iLineLength); } - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize) { return m_state->Read(lpBuf, uiBufSize); } - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize) { return m_state->Read(lpBuf, uiBufSize); } + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual std::string GetMimeType() { return m_state->m_httpheader.GetMimeType(); } virtual std::string GetContent() { return GetMimeType(); } virtual int IoControl(EIoControl request, void* param); @@ -138,7 +138,7 @@ namespace XFILE size_t HeaderCallback(void *ptr, size_t size, size_t nmemb); bool Seek(int64_t pos); - unsigned int Read(void* lpBuf, int64_t uiBufSize); + unsigned int Read(void* lpBuf, size_t uiBufSize); bool ReadString(char *szLine, int iLineLength); bool FillBuffer(unsigned int want); void SetReadBuffer(const void* lpBuf, int64_t uiBufSize); diff --git a/xbmc/filesystem/DAAPFile.cpp b/xbmc/filesystem/DAAPFile.cpp index 65e66ce7dd..26d4608696 100644 --- a/xbmc/filesystem/DAAPFile.cpp +++ b/xbmc/filesystem/DAAPFile.cpp @@ -203,7 +203,7 @@ bool CDAAPFile::Open(const CURL& url) //********************************************************************************************* -unsigned int CDAAPFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CDAAPFile::Read(void *lpBuf, size_t uiBufSize) { return m_curl.Read(lpBuf, uiBufSize); } diff --git a/xbmc/filesystem/DAAPFile.h b/xbmc/filesystem/DAAPFile.h index 3fd2daafe0..e23e7b18e3 100644 --- a/xbmc/filesystem/DAAPFile.h +++ b/xbmc/filesystem/DAAPFile.h @@ -76,7 +76,7 @@ public: virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); virtual int IoControl(EIoControl request, void* param); diff --git a/xbmc/filesystem/File.cpp b/xbmc/filesystem/File.cpp index 121e0af8dc..c4ac83372e 100644 --- a/xbmc/filesystem/File.cpp +++ b/xbmc/filesystem/File.cpp @@ -130,10 +130,10 @@ bool CFile::Copy(const CURL& url2, const CURL& dest, XFILE::IFileCallback* pCall return false; } - int iBufferSize = 128 * 1024; + static const int iBufferSize = 128 * 1024; auto_buffer buffer(iBufferSize); - int iRead, iWrite; + ssize_t iRead, iWrite; UINT64 llFileSize = file.GetLength(); UINT64 llPos = 0; @@ -158,7 +158,7 @@ bool CFile::Copy(const CURL& url2, const CURL& dest, XFILE::IFileCallback* pCall iWrite = 0; while(iWrite < iRead) { - int iWrite2 = newFile.Write(buffer.get()+iWrite, iRead-iWrite); + ssize_t iWrite2 = newFile.Write(buffer.get() + iWrite, iRead - iWrite); if(iWrite2 <=0) break; iWrite+=iWrite2; @@ -495,16 +495,21 @@ int CFile::Stat(const CURL& file, struct __stat64* buffer) return -1; } -unsigned int CFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CFile::Read(void *lpBuf, size_t uiBufSize) { - if (!m_pFile || !lpBuf) - return 0; + if (!m_pFile) + return -1; + if (lpBuf == NULL && uiBufSize != 0) + return -1; + + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; if(m_pBuffer) { if(m_flags & READ_TRUNCATED) { - unsigned int nBytes = m_pBuffer->sgetn( + const ssize_t nBytes = m_pBuffer->sgetn( (char *)lpBuf, min<streamsize>((streamsize)uiBufSize, m_pBuffer->in_avail())); if (m_bitStreamStats && nBytes>0) @@ -513,7 +518,7 @@ unsigned int CFile::Read(void *lpBuf, int64_t uiBufSize) } else { - unsigned int nBytes = m_pBuffer->sgetn((char*)lpBuf, uiBufSize); + const ssize_t nBytes = m_pBuffer->sgetn((char*)lpBuf, uiBufSize); if (m_bitStreamStats && nBytes>0) m_bitStreamStats->AddSampleBytes(nBytes); return nBytes; @@ -524,20 +529,24 @@ unsigned int CFile::Read(void *lpBuf, int64_t uiBufSize) { if(m_flags & READ_TRUNCATED) { - unsigned int nBytes = m_pFile->Read(lpBuf, uiBufSize); + const ssize_t nBytes = m_pFile->Read(lpBuf, uiBufSize); if (m_bitStreamStats && nBytes>0) m_bitStreamStats->AddSampleBytes(nBytes); return nBytes; } else { - unsigned int done = 0; + ssize_t done = 0; while((uiBufSize-done) > 0) { - int curr = m_pFile->Read((char*)lpBuf+done, uiBufSize-done); - if(curr<=0) - break; + const ssize_t curr = m_pFile->Read((char*)lpBuf+done, uiBufSize-done); + if (curr <= 0) + { + if (curr < 0 && done == 0) + return -1; + break; + } done+=curr; } if (m_bitStreamStats && done > 0) @@ -549,6 +558,7 @@ unsigned int CFile::Read(void *lpBuf, int64_t uiBufSize) catch(...) { CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__); + return -1; } return 0; } @@ -733,9 +743,11 @@ bool CFile::ReadString(char *szLine, int iLineLength) return false; } -int CFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CFile::Write(const void* lpBuf, size_t uiBufSize) { - if (!m_pFile || !lpBuf) + if (!m_pFile) + return -1; + if (lpBuf == NULL && uiBufSize != 0) return -1; try diff --git a/xbmc/filesystem/File.h b/xbmc/filesystem/File.h index 454d20e087..43d3ca5099 100644 --- a/xbmc/filesystem/File.h +++ b/xbmc/filesystem/File.h @@ -84,9 +84,25 @@ public: bool Open(const std::string& strFileName, const unsigned int flags = 0); bool OpenForWrite(const std::string& strFileName, bool bOverWrite = false); - unsigned int Read(void* lpBuf, int64_t uiBufSize); + /** + * Attempt to read bufSize bytes from currently opened file into buffer bufPtr. + * @param bufPtr pointer to buffer + * @param bufSize size of the buffer + * @return number of successfully read bytes if any bytes were read and stored in + * buffer, zero if no bytes are available to read (end of file was reached) + * or undetectable error occur, -1 in case of any explicit error + */ + ssize_t Read(void* bufPtr, size_t bufSize); bool ReadString(char *szLine, int iLineLength); - int Write(const void* lpBuf, int64_t uiBufSize); + /** + * Attempt to write bufSize bytes from buffer bufPtr into currently opened file. + * @param bufPtr pointer to buffer + * @param bufSize size of the buffer + * @return number of successfully written bytes if any bytes were written, + * zero if no bytes were written and no detectable error occur, + * -1 in case of any explicit error + */ + ssize_t Write(const void* bufPtr, size_t bufSize); void Flush(); int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); int Truncate(int64_t iSize); diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp index ab7d114c8a..50fe9b4a71 100644 --- a/xbmc/filesystem/FileCache.cpp +++ b/xbmc/filesystem/FileCache.cpp @@ -264,7 +264,7 @@ void CFileCache::Process() } } - int iRead = 0; + ssize_t iRead = 0; if (!cacheReachEOF) iRead = m_source.Read(buffer.get(), m_chunkSize); if (iRead == 0) @@ -348,16 +348,19 @@ int CFileCache::Stat(const CURL& url, struct __stat64* buffer) return CFile::Stat(url.Get(), buffer); } -unsigned int CFileCache::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CFileCache::Read(void* lpBuf, size_t uiBufSize) { CSingleLock lock(m_sync); if (!m_pCache) { CLog::Log(LOGERROR,"%s - sanity failed. no cache strategy!", __FUNCTION__); - return 0; + return -1; } int64_t iRc; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + retry: // attempt to read iRc = m_pCache->ReadFromCache((char *)lpBuf, (size_t)uiBufSize); @@ -378,7 +381,7 @@ retry: if (iRc == CACHE_RC_TIMEOUT) { CLog::Log(LOGWARNING, "%s - timeout waiting for data", __FUNCTION__); - return 0; + return -1; } if (iRc == 0) @@ -386,7 +389,7 @@ retry: // unknown error code CLog::Log(LOGERROR, "%s - cache strategy returned unknown error code %d", __FUNCTION__, (int)iRc); - return 0; + return -1; } int64_t CFileCache::Seek(int64_t iFilePosition, int iWhence) diff --git a/xbmc/filesystem/FileCache.h b/xbmc/filesystem/FileCache.h index 2d298dd3c0..a144cc10b2 100644 --- a/xbmc/filesystem/FileCache.h +++ b/xbmc/filesystem/FileCache.h @@ -48,7 +48,7 @@ namespace XFILE virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/FileFactory.cpp b/xbmc/filesystem/FileFactory.cpp index 61debc76e4..f9df33a3cd 100644 --- a/xbmc/filesystem/FileFactory.cpp +++ b/xbmc/filesystem/FileFactory.cpp @@ -84,6 +84,9 @@ #ifdef HAS_UPNP #include "UPnPFile.h" #endif +#ifdef HAVE_LIBBLURAY +#include "BlurayFile.h" +#endif #include "PipesManager.h" #include "PipeFile.h" #include "MusicDatabaseFile.h" @@ -207,6 +210,9 @@ IFile* CFileFactory::CreateLoader(const CURL& url) #ifdef HAS_UPNP else if (url.IsProtocol("upnp")) return new CUPnPFile(); #endif +#ifdef HAVE_LIBBLURAY + else if (url.IsProtocol("bluray")) return new CBlurayFile(); +#endif } CLog::Log(LOGWARNING, "%s - %sunsupported protocol(%s) in %s", __FUNCTION__, networkAvailable ? "" : "Network down or ", url.GetProtocol().c_str(), url.GetRedacted().c_str()); diff --git a/xbmc/filesystem/FileReaderFile.cpp b/xbmc/filesystem/FileReaderFile.cpp index e4405e2987..4e6c08c59d 100644 --- a/xbmc/filesystem/FileReaderFile.cpp +++ b/xbmc/filesystem/FileReaderFile.cpp @@ -67,15 +67,15 @@ bool CFileReaderFile::OpenForWrite(const CURL& url, bool bOverWrite) } //********************************************************************************************* -unsigned int CFileReaderFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CFileReaderFile::Read(void *lpBuf, size_t uiBufSize) { return m_reader.Read(lpBuf,uiBufSize); } //********************************************************************************************* -int CFileReaderFile::Write(const void *lpBuf, int64_t uiBufSize) +ssize_t CFileReaderFile::Write(const void *lpBuf, size_t uiBufSize) { - return 0; + return -1; } //********************************************************************************************* diff --git a/xbmc/filesystem/FileReaderFile.h b/xbmc/filesystem/FileReaderFile.h index 7c51a3f684..2e6e89ba52 100644 --- a/xbmc/filesystem/FileReaderFile.h +++ b/xbmc/filesystem/FileReaderFile.h @@ -36,8 +36,8 @@ public: virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); diff --git a/xbmc/filesystem/HDHomeRunFile.cpp b/xbmc/filesystem/HDHomeRunFile.cpp index 0bd2a162fc..e35ebb4d35 100644 --- a/xbmc/filesystem/HDHomeRunFile.cpp +++ b/xbmc/filesystem/HDHomeRunFile.cpp @@ -106,8 +106,11 @@ bool CHomeRunFile::Open(const CURL &url) return true; } -unsigned int CHomeRunFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CHomeRunFile::Read(void* lpBuf, size_t uiBufSize) { + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + size_t datasize; if(uiBufSize < VIDEO_DATA_PACKET_SIZE) @@ -125,7 +128,7 @@ unsigned int CHomeRunFile::Read(void* lpBuf, int64_t uiBufSize) if(ptr) { memcpy(lpBuf, ptr, datasize); - return (unsigned int)datasize; + return datasize; } if(timestamp.IsTimePast()) @@ -133,7 +136,7 @@ unsigned int CHomeRunFile::Read(void* lpBuf, int64_t uiBufSize) Sleep(64); } - return (unsigned int)datasize; + return datasize; } void CHomeRunFile::Close() diff --git a/xbmc/filesystem/HDHomeRunFile.h b/xbmc/filesystem/HDHomeRunFile.h index 2d74549f23..0c1be66891 100644 --- a/xbmc/filesystem/HDHomeRunFile.h +++ b/xbmc/filesystem/HDHomeRunFile.h @@ -40,7 +40,7 @@ namespace XFILE virtual bool Open(const CURL& url); virtual void Close(); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int GetChunkSize(); private: struct hdhomerun_device_t* m_device; diff --git a/xbmc/filesystem/HTSPSession.cpp b/xbmc/filesystem/HTSPSession.cpp index e77ed71187..0465ec21d5 100644 --- a/xbmc/filesystem/HTSPSession.cpp +++ b/xbmc/filesystem/HTSPSession.cpp @@ -24,6 +24,7 @@ #include "FileItem.h" #include "utils/log.h" #include "utils/StringUtils.h" +#include "utils/SystemInfo.h" #include "settings/AdvancedSettings.h" #include "Util.h" @@ -239,7 +240,9 @@ bool CHTSPSession::Connect(const std::string& hostname, int port) // send hello m = htsmsg_create_map(); htsmsg_add_str(m, "method", "hello"); - htsmsg_add_str(m, "clientname", "XBMC Media Center"); + std::string fullAppName = CSysInfo::GetAppName(); + fullAppName += " Media Center"; + htsmsg_add_str(m, "clientname", fullAppName.c_str()); htsmsg_add_u32(m, "htspversion", 1); // read welcome diff --git a/xbmc/filesystem/HTTPFile.cpp b/xbmc/filesystem/HTTPFile.cpp index 6e0b209c57..8711f3e7e4 100644 --- a/xbmc/filesystem/HTTPFile.cpp +++ b/xbmc/filesystem/HTTPFile.cpp @@ -40,7 +40,7 @@ bool CHTTPFile::OpenForWrite(const CURL& url, bool bOverWrite) return true; } -int CHTTPFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CHTTPFile::Write(const void* lpBuf, size_t uiBufSize) { // Although we can not verify much, try to catch errors where we can if (!m_openedforwrite) @@ -60,6 +60,6 @@ int CHTTPFile::Write(const void* lpBuf, int64_t uiBufSize) return -1; // Finally (and this is a clumsy hack) return the http response code - return (int) m_httpresponse; + return m_httpresponse; } diff --git a/xbmc/filesystem/HTTPFile.h b/xbmc/filesystem/HTTPFile.h index 68732a70d8..730151c146 100644 --- a/xbmc/filesystem/HTTPFile.h +++ b/xbmc/filesystem/HTTPFile.h @@ -30,7 +30,7 @@ namespace XFILE CHTTPFile(void); virtual ~CHTTPFile(void); virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); private: bool m_openedforwrite; CURL m_urlforwrite; diff --git a/xbmc/filesystem/IFile.h b/xbmc/filesystem/IFile.h index 377ccb1489..795ec1161e 100644 --- a/xbmc/filesystem/IFile.h +++ b/xbmc/filesystem/IFile.h @@ -29,15 +29,23 @@ #pragma once -#ifdef TARGET_POSIX -#include "PlatformDefs.h" // for __stat64 -#endif +#include "PlatformDefs.h" // for __stat64, ssize_t #include <stdio.h> #include <stdint.h> #include <sys/stat.h> #include <string> +#if !defined(SIZE_MAX) || !defined(SSIZE_MAX) +#include <limits.h> +#ifndef SIZE_MAX +#define SIZE_MAX UINTPTR_MAX +#endif // ! SIZE_MAX +#ifndef SSIZE_MAX +#define SSIZE_MAX INTPTR_MAX +#endif // ! SSIZE_MAX +#endif // ! SIZE_MAX || ! SSIZE_MAX + #include "IFileTypes.h" class CURL; @@ -79,8 +87,24 @@ public: * @return zero of success, -1 otherwise. */ virtual int Stat(struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize) = 0; - virtual int Write(const void* lpBuf, int64_t uiBufSize) { return -1;}; + /** + * Attempt to read bufSize bytes from currently opened file into buffer bufPtr. + * @param bufPtr pointer to buffer + * @param bufSize size of the buffer + * @return number of successfully read bytes if any bytes were read and stored in + * buffer, zero if no bytes are available to read (end of file was reached) + * or undetectable error occur, -1 in case of any explicit error + */ + virtual ssize_t Read(void* bufPtr, size_t bufSize) = 0; + /** + * Attempt to write bufSize bytes from buffer bufPtr into currently opened file. + * @param bufPtr pointer to buffer + * @param bufSize size of the buffer + * @return number of successfully written bytes if any bytes were written, + * zero if no bytes were written and no detectable error occur, + * -1 in case of any explicit error + */ + virtual ssize_t Write(const void* bufPtr, size_t bufSize) { return -1;} virtual bool ReadString(char *szLine, int iLineLength); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET) = 0; virtual void Close() = 0; diff --git a/xbmc/filesystem/ISOFile.cpp b/xbmc/filesystem/ISOFile.cpp index 8c403fbd67..00cac8b397 100644 --- a/xbmc/filesystem/ISOFile.cpp +++ b/xbmc/filesystem/ISOFile.cpp @@ -67,9 +67,13 @@ bool CISOFile::Open(const CURL& url) } //********************************************************************************************* -unsigned int CISOFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CISOFile::Read(void *lpBuf, size_t uiBufSize) { - if (!m_bOpened) return 0; + if (!m_bOpened) + return -1; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + char *pData = (char *)lpBuf; if (m_cache.getSize() > 0) @@ -99,10 +103,8 @@ unsigned int CISOFile::Read(void *lpBuf, int64_t uiBufSize) } return lTotalBytesRead; } - int iResult = m_isoReader.ReadFile( m_hFile, (uint8_t*)pData, (long)uiBufSize); - if (iResult == -1) - return 0; - return iResult; + + return m_isoReader.ReadFile( m_hFile, (uint8_t*)pData, (long)uiBufSize);; } //********************************************************************************************* diff --git a/xbmc/filesystem/ISOFile.h b/xbmc/filesystem/ISOFile.h index 10fb941dc6..1b4cb1e6c7 100644 --- a/xbmc/filesystem/ISOFile.h +++ b/xbmc/filesystem/ISOFile.h @@ -45,7 +45,7 @@ public: virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); protected: diff --git a/xbmc/filesystem/ImageFile.cpp b/xbmc/filesystem/ImageFile.cpp index 2db3dbd935..572d3b256e 100644 --- a/xbmc/filesystem/ImageFile.cpp +++ b/xbmc/filesystem/ImageFile.cpp @@ -85,7 +85,7 @@ int CImageFile::Stat(const CURL& url, struct __stat64* buffer) return -1; } -unsigned int CImageFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CImageFile::Read(void* lpBuf, size_t uiBufSize) { return m_file.Read(lpBuf, uiBufSize); } diff --git a/xbmc/filesystem/ImageFile.h b/xbmc/filesystem/ImageFile.h index 0a216f51b0..867c213292 100644 --- a/xbmc/filesystem/ImageFile.h +++ b/xbmc/filesystem/ImageFile.h @@ -33,7 +33,7 @@ namespace XFILE virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/Makefile.in b/xbmc/filesystem/Makefile.in index 1997f89daf..144bebc4de 100644 --- a/xbmc/filesystem/Makefile.in +++ b/xbmc/filesystem/Makefile.in @@ -121,6 +121,7 @@ endif ifeq (@HAVE_LIBBLURAY@,1) SRCS += BlurayDirectory.cpp +SRCS += BlurayFile.cpp endif ifeq (@USE_UPNP@,1) diff --git a/xbmc/filesystem/MultiPathFile.cpp b/xbmc/filesystem/MultiPathFile.cpp index a552c4bfac..6cc7db9dd7 100644 --- a/xbmc/filesystem/MultiPathFile.cpp +++ b/xbmc/filesystem/MultiPathFile.cpp @@ -94,7 +94,7 @@ int CMultiPathFile::Stat(const CURL& url, struct __stat64* buffer) return -1; } -unsigned int CMultiPathFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CMultiPathFile::Read(void* lpBuf, size_t uiBufSize) { return m_file.Read(lpBuf, uiBufSize); } diff --git a/xbmc/filesystem/MultiPathFile.h b/xbmc/filesystem/MultiPathFile.h index 2b0e044f6d..3d50537736 100644 --- a/xbmc/filesystem/MultiPathFile.h +++ b/xbmc/filesystem/MultiPathFile.h @@ -33,7 +33,7 @@ namespace XFILE virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/MusicDatabaseFile.cpp b/xbmc/filesystem/MusicDatabaseFile.cpp index 20fdf666e7..4edc05a71e 100644 --- a/xbmc/filesystem/MusicDatabaseFile.cpp +++ b/xbmc/filesystem/MusicDatabaseFile.cpp @@ -78,7 +78,7 @@ int CMusicDatabaseFile::Stat(const CURL& url, struct __stat64* buffer) return m_file.Stat(TranslateUrl(url), buffer); } -unsigned int CMusicDatabaseFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CMusicDatabaseFile::Read(void* lpBuf, size_t uiBufSize) { return m_file.Read(lpBuf, uiBufSize); } diff --git a/xbmc/filesystem/MusicDatabaseFile.h b/xbmc/filesystem/MusicDatabaseFile.h index 165a7f21db..9095fad7b1 100644 --- a/xbmc/filesystem/MusicDatabaseFile.h +++ b/xbmc/filesystem/MusicDatabaseFile.h @@ -33,7 +33,7 @@ public: virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/MythFile.cpp b/xbmc/filesystem/MythFile.cpp index 947faf9715..ec2aa2a01f 100644 --- a/xbmc/filesystem/MythFile.cpp +++ b/xbmc/filesystem/MythFile.cpp @@ -492,14 +492,17 @@ int64_t CMythFile::GetLength() return -1; } -unsigned int CMythFile::Read(void* buffer, int64_t size) +ssize_t CMythFile::Read(void* buffer, size_t size) { /* check for any events */ HandleEvents(); /* file might have gotten closed */ if(!m_recorder && !m_file) - return 0; + return -1; + + if (size > SSIZE_MAX) + size = SSIZE_MAX; int ret; if(m_recorder) @@ -508,10 +511,8 @@ unsigned int CMythFile::Read(void* buffer, int64_t size) ret = m_dll->file_read(m_file, (char*)buffer, (unsigned long)size); if(ret < 0) - { CLog::Log(LOGERROR, "%s - cmyth read returned error %d", __FUNCTION__, ret); - return 0; - } + return ret; } diff --git a/xbmc/filesystem/MythFile.h b/xbmc/filesystem/MythFile.h index d5f707477d..70a7ac513c 100644 --- a/xbmc/filesystem/MythFile.h +++ b/xbmc/filesystem/MythFile.h @@ -51,7 +51,7 @@ public: virtual int64_t GetLength(); virtual int Stat(const CURL& url, struct __stat64* buffer) { return -1; } virtual void Close(); - virtual unsigned int Read(void* buffer, int64_t size); + virtual ssize_t Read(void* buffer, size_t size); virtual std::string GetContent() { return ""; } virtual bool SkipNext(); diff --git a/xbmc/filesystem/NFSFile.cpp b/xbmc/filesystem/NFSFile.cpp index 6a375257c6..a2c2d9d05e 100644 --- a/xbmc/filesystem/NFSFile.cpp +++ b/xbmc/filesystem/NFSFile.cpp @@ -634,12 +634,16 @@ int CNFSFile::Stat(const CURL& url, struct __stat64* buffer) return ret; } -unsigned int CNFSFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CNFSFile::Read(void *lpBuf, size_t uiBufSize) { - int numberOfBytesRead = 0; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + + ssize_t numberOfBytesRead = 0; CSingleLock lock(gNfsConnection); - if (m_pFileHandle == NULL || m_pNfsContext == NULL ) return 0; + if (m_pFileHandle == NULL || m_pNfsContext == NULL ) + return -1; numberOfBytesRead = gNfsConnection.GetImpl()->nfs_read(m_pNfsContext, m_pFileHandle, uiBufSize, (char *)lpBuf); @@ -649,11 +653,9 @@ unsigned int CNFSFile::Read(void *lpBuf, int64_t uiBufSize) //something went wrong ... if (numberOfBytesRead < 0) - { CLog::Log(LOGERROR, "%s - Error( %d, %s )", __FUNCTION__, numberOfBytesRead, gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext)); - return 0; - } - return (unsigned int)numberOfBytesRead; + + return numberOfBytesRead; } int64_t CNFSFile::Seek(int64_t iFilePosition, int iWhence) @@ -718,13 +720,13 @@ void CNFSFile::Close() //this was a bitch! //for nfs write to work we have to write chunked //otherwise this could crash on big files -int CNFSFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CNFSFile::Write(const void* lpBuf, size_t uiBufSize) { - int numberOfBytesWritten = 0; + size_t numberOfBytesWritten = 0; int writtenBytes = 0; - int64_t leftBytes = uiBufSize; + size_t leftBytes = uiBufSize; //clamp max write chunksize to 32kb - fixme - this might be superfluious with future libnfs versions - int64_t chunkSize = gNfsConnection.GetMaxWriteChunkSize() > 32768 ? 32768 : gNfsConnection.GetMaxWriteChunkSize(); + size_t chunkSize = gNfsConnection.GetMaxWriteChunkSize() > 32768 ? 32768 : (size_t)gNfsConnection.GetMaxWriteChunkSize(); CSingleLock lock(gNfsConnection); @@ -751,7 +753,10 @@ int CNFSFile::Write(const void* lpBuf, int64_t uiBufSize) //danger - something went wrong if (writtenBytes < 0) { - CLog::Log(LOGERROR, "Failed to pwrite(%s) %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext)); + CLog::Log(LOGERROR, "Failed to pwrite(%s) %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext)); + if (numberOfBytesWritten == 0) + return -1; + break; } } diff --git a/xbmc/filesystem/NFSFile.h b/xbmc/filesystem/NFSFile.h index 279248e950..4c01e4eff2 100644 --- a/xbmc/filesystem/NFSFile.h +++ b/xbmc/filesystem/NFSFile.h @@ -135,14 +135,14 @@ namespace XFILE virtual ~CNFSFile(); virtual void Close(); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); virtual int Stat(struct __stat64* buffer); virtual int64_t GetLength(); virtual int64_t GetPosition(); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual int Truncate(int64_t iSize); //implement iocontrol for seek_possible for preventing the stat in File class for diff --git a/xbmc/filesystem/PVRFile.cpp b/xbmc/filesystem/PVRFile.cpp index b9af336fc1..4e9abf934a 100644 --- a/xbmc/filesystem/PVRFile.cpp +++ b/xbmc/filesystem/PVRFile.cpp @@ -101,9 +101,20 @@ void CPVRFile::Close() g_PVRManager.CloseStream(); } -unsigned int CPVRFile::Read(void* buffer, int64_t size) +ssize_t CPVRFile::Read(void* buffer, size_t size) { - return g_PVRManager.IsStarted() ? g_PVRClients->ReadStream((BYTE*)buffer, size) : 0; + if (size > SSIZE_MAX) + size = SSIZE_MAX; + + if (!g_PVRManager.IsStarted()) + return -1; + + // TODO: Fix overflow in case of sizeof(int) != sizeof(size_t) + const int ret = g_PVRClients->ReadStream((BYTE*)buffer, size); + if (ret < 0) + return -1; + + return ret; } int64_t CPVRFile::GetLength() diff --git a/xbmc/filesystem/PVRFile.h b/xbmc/filesystem/PVRFile.h index 6cba5e34c3..78851b3574 100644 --- a/xbmc/filesystem/PVRFile.h +++ b/xbmc/filesystem/PVRFile.h @@ -42,7 +42,7 @@ public: virtual int64_t GetLength(); virtual int Stat(const CURL& url, struct __stat64* buffer) { return -1; } virtual void Close(); - virtual unsigned int Read(void* buffer, int64_t size); + virtual ssize_t Read(void* buffer, size_t size); virtual std::string GetContent() { return ""; } virtual bool SkipNext() { return !m_isPlayRecording; } diff --git a/xbmc/filesystem/PipeFile.cpp b/xbmc/filesystem/PipeFile.cpp index 69c31de403..9bbfe6cc0d 100644 --- a/xbmc/filesystem/PipeFile.cpp +++ b/xbmc/filesystem/PipeFile.cpp @@ -77,21 +77,24 @@ int CPipeFile::Stat(struct __stat64* buffer) return 0; } -unsigned int CPipeFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CPipeFile::Read(void* lpBuf, size_t uiBufSize) { if (!m_pipe) return -1; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + return m_pipe->Read((char *)lpBuf,(int)uiBufSize); } -int CPipeFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CPipeFile::Write(const void* lpBuf, size_t uiBufSize) { if (!m_pipe) return -1; // m_pipe->Write return bool. either all was written or not. - return m_pipe->Write((const char *)lpBuf,(int)uiBufSize) ? (int)uiBufSize : 0; + return m_pipe->Write((const char *)lpBuf,uiBufSize) ? uiBufSize : -1; } void CPipeFile::SetEof() diff --git a/xbmc/filesystem/PipeFile.h b/xbmc/filesystem/PipeFile.h index 540a646312..4aae91ff49 100644 --- a/xbmc/filesystem/PipeFile.h +++ b/xbmc/filesystem/PipeFile.h @@ -50,8 +50,8 @@ public: virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); virtual int Stat(struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); virtual void Flush(); diff --git a/xbmc/filesystem/RTVFile.cpp b/xbmc/filesystem/RTVFile.cpp index 833a40c9b0..e1dac313bf 100644 --- a/xbmc/filesystem/RTVFile.cpp +++ b/xbmc/filesystem/RTVFile.cpp @@ -121,12 +121,16 @@ int CRTVFile::Stat(const CURL& url, struct __stat64* buffer) } //********************************************************************************************* -unsigned int CRTVFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CRTVFile::Read(void *lpBuf, size_t uiBufSize) { - size_t lenread; + ssize_t lenread; // Don't read if no connection is open! - if (!m_bOpened) return 0; + if (!m_bOpened) + return -1; + + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; // Read uiBufSize bytes from the m_rtvd connection lenread = rtv_read_file(m_rtvd, (char *) lpBuf, (size_t) uiBufSize); @@ -137,7 +141,7 @@ unsigned int CRTVFile::Read(void *lpBuf, int64_t uiBufSize) if(m_filePos + lenread > m_fileSize) { CLog::Log(LOGWARNING, "%s - RTV library read passed filesize, returning last chunk", __FUNCTION__); - lenread = (size_t)(m_fileSize - m_filePos); + lenread = (m_fileSize - m_filePos); m_filePos = m_fileSize; return lenread; } diff --git a/xbmc/filesystem/RTVFile.h b/xbmc/filesystem/RTVFile.h index a1bed4e1c0..75c7683eb7 100644 --- a/xbmc/filesystem/RTVFile.h +++ b/xbmc/filesystem/RTVFile.h @@ -45,7 +45,7 @@ public: bool Open(const std::string& strHostName, const std::string& strFileName, int iport); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); protected: diff --git a/xbmc/filesystem/RarFile.cpp b/xbmc/filesystem/RarFile.cpp index 1b82b94b4c..37e70e0726 100644 --- a/xbmc/filesystem/RarFile.cpp +++ b/xbmc/filesystem/RarFile.cpp @@ -269,11 +269,14 @@ bool CRarFile::OpenForWrite(const CURL& url) return false; } -unsigned int CRarFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CRarFile::Read(void *lpBuf, size_t uiBufSize) { #ifdef HAS_FILESYSTEM_RAR if (!m_bOpen) - return 0; + return -1; + + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; if (m_bUseFile) return m_File.Read(lpBuf,uiBufSize); @@ -284,7 +287,7 @@ unsigned int CRarFile::Read(void *lpBuf, int64_t uiBufSize) if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(5000) ) { CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__); - return 0; + return -1; } @@ -351,17 +354,12 @@ unsigned int CRarFile::Read(void *lpBuf, int64_t uiBufSize) m_pExtract->GetDataIO().hBufferEmpty->Set(); - return static_cast<unsigned int>(uiBufSize-uicBufSize); + return (ssize_t)(uiBufSize-uicBufSize); #else return 0; #endif } -unsigned int CRarFile::Write(void *lpBuf, int64_t uiBufSize) -{ - return 0; -} - void CRarFile::Close() { #ifdef HAS_FILESYSTEM_RAR @@ -527,7 +525,7 @@ int64_t CRarFile::GetPosition() return m_iFilePosition; } -int CRarFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CRarFile::Write(const void* lpBuf, size_t uiBufSize) { return -1; } diff --git a/xbmc/filesystem/RarFile.h b/xbmc/filesystem/RarFile.h index cc1fea3d7e..8aac5272c8 100644 --- a/xbmc/filesystem/RarFile.h +++ b/xbmc/filesystem/RarFile.h @@ -71,8 +71,8 @@ namespace XFILE virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence=SEEK_SET); virtual void Close(); virtual void Flush(); diff --git a/xbmc/filesystem/SAPFile.cpp b/xbmc/filesystem/SAPFile.cpp index 3cdc9a44ab..4633f4eed7 100644 --- a/xbmc/filesystem/SAPFile.cpp +++ b/xbmc/filesystem/SAPFile.cpp @@ -27,6 +27,7 @@ #include <sys/stat.h> #include <vector> +#include <limits> using namespace std; using namespace XFILE; @@ -111,9 +112,14 @@ int CSAPFile::Stat(const CURL& url, struct __stat64* buffer) } -unsigned int CSAPFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CSAPFile::Read(void *lpBuf, size_t uiBufSize) { - return (unsigned int)m_stream.readsome((char*)lpBuf, (streamsize)uiBufSize); + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + if (uiBufSize > std::numeric_limits<std::streamsize>::max()) + uiBufSize = (size_t)std::numeric_limits<std::streamsize>::max(); + + return (ssize_t)m_stream.readsome((char*)lpBuf, (streamsize)uiBufSize); } void CSAPFile::Close() diff --git a/xbmc/filesystem/SAPFile.h b/xbmc/filesystem/SAPFile.h index cffce9b0a6..2d9af5d9de 100644 --- a/xbmc/filesystem/SAPFile.h +++ b/xbmc/filesystem/SAPFile.h @@ -41,7 +41,7 @@ public: virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); diff --git a/xbmc/filesystem/SFTPFile.cpp b/xbmc/filesystem/SFTPFile.cpp index 0b166f4f02..5b5ad10970 100644 --- a/xbmc/filesystem/SFTPFile.cpp +++ b/xbmc/filesystem/SFTPFile.cpp @@ -637,10 +637,13 @@ int64_t CSFTPFile::Seek(int64_t iFilePosition, int iWhence) } } -unsigned int CSFTPFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CSFTPFile::Read(void* lpBuf, size_t uiBufSize) { if (m_session && m_sftp_handle) { + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + int rc = m_session->Read(m_sftp_handle, lpBuf, (size_t)uiBufSize); if (rc >= 0) diff --git a/xbmc/filesystem/SFTPFile.h b/xbmc/filesystem/SFTPFile.h index b32b831b3c..4a057d173e 100644 --- a/xbmc/filesystem/SFTPFile.h +++ b/xbmc/filesystem/SFTPFile.h @@ -30,7 +30,6 @@ #define ssize_t SSIZE_T #include <libssh/sftp.h> #undef ssize_t -#include "PlatformDefs.h" #else // !TARGET_WINDOWS #include <libssh/sftp.h> #endif // !TARGET_WINDOWS @@ -107,7 +106,7 @@ namespace XFILE virtual ~CSFTPFile(); virtual void Close(); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); diff --git a/xbmc/filesystem/SMBDirectory.cpp b/xbmc/filesystem/SMBDirectory.cpp index bf4710eafe..0815208e07 100644 --- a/xbmc/filesystem/SMBDirectory.cpp +++ b/xbmc/filesystem/SMBDirectory.cpp @@ -45,9 +45,9 @@ #include <libsmbclient.h> #if defined(TARGET_DARWIN) -#define XBMC_SMB_MOUNT_PATH "Library/Application Support/XBMC/Mounts/" +#define XBMC_SMB_MOUNT_PATH "Library/Application Support/Kodi/Mounts/" #else -#define XBMC_SMB_MOUNT_PATH "/media/xbmc/smb/" +#define XBMC_SMB_MOUNT_PATH "/media/kodi/smb/" #endif struct CachedDirEntry @@ -248,7 +248,9 @@ int CSMBDirectory::OpenDir(const CURL& url, std::string& strAuth) s.erase(len - 1, 1); } - CLog::Log(LOGDEBUG, "%s - Using authentication url %s", __FUNCTION__, CURL::GetRedacted(s).c_str()); + if (g_advancedSettings.CanLogComponent(LOGSAMBA)) + CLog::LogFunction(LOGDEBUG, __FUNCTION__, "Using authentication url %s", CURL::GetRedacted(s).c_str()); + { CSingleLock lock(smb); fd = smbc_opendir(s.c_str()); } diff --git a/xbmc/filesystem/SMBFile.cpp b/xbmc/filesystem/SMBFile.cpp index 9fbb0075b2..355c4cb3bd 100644 --- a/xbmc/filesystem/SMBFile.cpp +++ b/xbmc/filesystem/SMBFile.cpp @@ -508,9 +508,14 @@ int CSMBFile::Truncate(int64_t size) return 0; } -unsigned int CSMBFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CSMBFile::Read(void *lpBuf, size_t uiBufSize) { - if (m_fd == -1) return 0; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + + if (m_fd == -1) + return -1; + CSingleLock lock(smb); // Init not called since it has to be "inited" by now smb.SetActivityTime(); /* work around stupid bug in samba */ @@ -523,7 +528,7 @@ unsigned int CSMBFile::Read(void *lpBuf, int64_t uiBufSize) if( uiBufSize >= 64*1024-2 ) uiBufSize = 64*1024-2; - int bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); + ssize_t bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); if ( bytesRead < 0 && errno == EINVAL ) { @@ -532,12 +537,9 @@ unsigned int CSMBFile::Read(void *lpBuf, int64_t uiBufSize) } if ( bytesRead < 0 ) - { CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno)); - return 0; - } - return (unsigned int)bytesRead; + return bytesRead; } int64_t CSMBFile::Seek(int64_t iFilePosition, int iWhence) @@ -568,7 +570,7 @@ void CSMBFile::Close() m_fd = -1; } -int CSMBFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CSMBFile::Write(const void* lpBuf, size_t uiBufSize) { if (m_fd == -1) return -1; DWORD dwNumberOfBytesWritten = 0; @@ -578,7 +580,7 @@ int CSMBFile::Write(const void* lpBuf, int64_t uiBufSize) CSingleLock lock(smb); dwNumberOfBytesWritten = smbc_write(m_fd, (void*)lpBuf, (DWORD)uiBufSize); - return (int)dwNumberOfBytesWritten; + return dwNumberOfBytesWritten; } bool CSMBFile::Delete(const CURL& url) diff --git a/xbmc/filesystem/SMBFile.h b/xbmc/filesystem/SMBFile.h index a9dc153ba2..0f6de4256d 100644 --- a/xbmc/filesystem/SMBFile.h +++ b/xbmc/filesystem/SMBFile.h @@ -79,7 +79,7 @@ public: virtual ~CSMBFile(); virtual void Close(); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); @@ -87,7 +87,7 @@ public: virtual int Truncate(int64_t size); virtual int64_t GetLength(); virtual int64_t GetPosition(); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false); virtual bool Delete(const CURL& url); diff --git a/xbmc/filesystem/ShoutcastFile.cpp b/xbmc/filesystem/ShoutcastFile.cpp index 068a7c646f..4ed46bbc94 100644 --- a/xbmc/filesystem/ShoutcastFile.cpp +++ b/xbmc/filesystem/ShoutcastFile.cpp @@ -95,8 +95,11 @@ bool CShoutcastFile::Open(const CURL& url) return result; } -unsigned int CShoutcastFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CShoutcastFile::Read(void* lpBuf, size_t uiBufSize) { + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + if (m_currint >= m_metaint && m_metaint > 0) { unsigned char header; @@ -114,13 +117,14 @@ unsigned int CShoutcastFile::Read(void* lpBuf, int64_t uiBufSize) m_currint = 0; } - unsigned int toRead; + ssize_t toRead; if (m_metaint > 0) - toRead = std::min((unsigned int)uiBufSize,(unsigned int)m_metaint-m_currint); + toRead = std::min<size_t>(uiBufSize,m_metaint-m_currint); else - toRead = std::min((unsigned int)uiBufSize,(unsigned int)16*255); + toRead = std::min<size_t>(uiBufSize,16*255); toRead = m_file.Read(lpBuf,toRead); - m_currint += toRead; + if (toRead > 0) + m_currint += toRead; return toRead; } diff --git a/xbmc/filesystem/ShoutcastFile.h b/xbmc/filesystem/ShoutcastFile.h index f454589479..2b12ba2df9 100644 --- a/xbmc/filesystem/ShoutcastFile.h +++ b/xbmc/filesystem/ShoutcastFile.h @@ -44,7 +44,7 @@ public: virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url) { return true;}; virtual int Stat(const CURL& url, struct __stat64* buffer) { errno = ENOENT; return -1; }; - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); int IoControl(EIoControl request, void* param); diff --git a/xbmc/filesystem/SlingboxFile.cpp b/xbmc/filesystem/SlingboxFile.cpp index ad53844996..9aeb162a25 100644 --- a/xbmc/filesystem/SlingboxFile.cpp +++ b/xbmc/filesystem/SlingboxFile.cpp @@ -157,16 +157,16 @@ bool CSlingboxFile::Open(const CURL& url) return true; } -unsigned int CSlingboxFile::Read(void * pBuffer, int64_t iSize) +ssize_t CSlingboxFile::Read(void * pBuffer, size_t iSize) { + if (iSize > SSIZE_MAX) + iSize = SSIZE_MAX; + // Read the data and check for any errors - int iRead = m_pSlingbox->ReadStream(pBuffer, (unsigned int)iSize); + ssize_t iRead = m_pSlingbox->ReadStream(pBuffer, (unsigned int)iSize); if (iRead < 0) - { CLog::Log(LOGERROR, "%s - Error reading stream from Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str()); - return 0; - } return iRead; } diff --git a/xbmc/filesystem/SlingboxFile.h b/xbmc/filesystem/SlingboxFile.h index 17b402a5fd..9cfa0fa220 100644 --- a/xbmc/filesystem/SlingboxFile.h +++ b/xbmc/filesystem/SlingboxFile.h @@ -33,7 +33,7 @@ namespace XFILE CSlingboxFile(); virtual ~CSlingboxFile(); virtual bool Open(const CURL& url); - virtual unsigned int Read(void * buffer, int64_t size); + virtual ssize_t Read(void * buffer, size_t size); virtual void Close(); virtual bool SkipNext(); diff --git a/xbmc/filesystem/SourcesDirectory.cpp b/xbmc/filesystem/SourcesDirectory.cpp index c03d297cfc..20e6d6ba31 100644 --- a/xbmc/filesystem/SourcesDirectory.cpp +++ b/xbmc/filesystem/SourcesDirectory.cpp @@ -18,10 +18,12 @@ * */ +#include "system.h" #include "SourcesDirectory.h" #include "utils/URIUtils.h" #include "URL.h" #include "Util.h" +#include "Directory.h" #include "FileItem.h" #include "File.h" #include "profiles/ProfilesManager.h" @@ -49,14 +51,22 @@ bool CSourcesDirectory::GetDirectory(const CURL& url, CFileItemList &items) VECSOURCES sources; VECSOURCES *sourcesFromType = CMediaSourceSettings::Get().GetSources(type); - if (sourcesFromType) - sources = *sourcesFromType; + if (!sourcesFromType) + return false; + + sources = *sourcesFromType; g_mediaManager.GetRemovableDrives(sources); - if (!sourcesFromType) + if (!GetDirectory(sources, items)) return false; - return GetDirectory(sources, items); +#ifdef HAS_UPNP + CFileItemList upnpServers; + if (CDirectory::GetDirectory("upnp://", upnpServers)) + items.Append(upnpServers); +#endif + + return true; } bool CSourcesDirectory::GetDirectory(const VECSOURCES &sources, CFileItemList &items) diff --git a/xbmc/filesystem/SpecialProtocol.h b/xbmc/filesystem/SpecialProtocol.h index 81442506f7..4475f24c7d 100644 --- a/xbmc/filesystem/SpecialProtocol.h +++ b/xbmc/filesystem/SpecialProtocol.h @@ -28,23 +28,23 @@ special://xbmc/ - the main XBMC folder (i.e. where the app resides). special://home/ - a writeable version of the main XBMC folder - Linux: ~/.xbmc/ - OS X: ~/Library/Application Support/XBMC/ + Linux: ~/.kodi/ + OS X: ~/Library/Application Support/Kodi/ Win32: ~/Application Data/XBMC/ special://userhome/ - a writable version of the user home directory - Linux, OS X: ~/.xbmc + Linux, OS X: ~/.kodi Win32: home directory of user special://masterprofile/ - the master users userdata folder - usually special://home/userdata - Linux: ~/.xbmc/userdata/ - OS X: ~/Library/Application Support/XBMC/UserData/ + Linux: ~/.kodi/userdata/ + OS X: ~/Library/Application Support/Kodi/UserData/ Win32: ~/Application Data/XBMC/UserData/ special://profile/ - the current users userdata folder - usually special://masterprofile/profiles/<current_profile> - Linux: ~/.xbmc/userdata/profiles/<current_profile> - OS X: ~/Library/Application Support/XBMC/UserData/profiles/<current_profile> + Linux: ~/.kodi/userdata/profiles/<current_profile> + OS X: ~/Library/Application Support/Kodi/UserData/profiles/<current_profile> Win32: ~/Application Data/XBMC/UserData/profiles/<current_profile> special://temp/ - the temporary directory. - Linux: ~/tmp/xbmc<username> + Linux: ~/.kodi/temp OS X: ~/ Win32: ~/Application Data/XBMC/cache */ diff --git a/xbmc/filesystem/SpecialProtocolFile.cpp b/xbmc/filesystem/SpecialProtocolFile.cpp index 6366714ef0..f72bbb04a8 100644 --- a/xbmc/filesystem/SpecialProtocolFile.cpp +++ b/xbmc/filesystem/SpecialProtocolFile.cpp @@ -83,12 +83,12 @@ int CSpecialProtocolFile::Stat(struct __stat64* buffer) return m_file.Stat(buffer); } -unsigned int CSpecialProtocolFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CSpecialProtocolFile::Read(void* lpBuf, size_t uiBufSize) { return m_file.Read(lpBuf, uiBufSize); } -int CSpecialProtocolFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CSpecialProtocolFile::Write(const void* lpBuf, size_t uiBufSize) { return m_file.Write(lpBuf,uiBufSize); } diff --git a/xbmc/filesystem/SpecialProtocolFile.h b/xbmc/filesystem/SpecialProtocolFile.h index 0aeddb6fbc..680c4a7572 100644 --- a/xbmc/filesystem/SpecialProtocolFile.h +++ b/xbmc/filesystem/SpecialProtocolFile.h @@ -37,8 +37,8 @@ public: virtual bool Delete(const CURL& url); virtual bool Rename(const CURL& url, const CURL& urlnew); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/TuxBoxFile.cpp b/xbmc/filesystem/TuxBoxFile.cpp index 25dffb5526..8290035003 100644 --- a/xbmc/filesystem/TuxBoxFile.cpp +++ b/xbmc/filesystem/TuxBoxFile.cpp @@ -47,9 +47,9 @@ bool CTuxBoxFile::Open(const CURL& url) return true; } -unsigned int CTuxBoxFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CTuxBoxFile::Read(void* lpBuf, size_t uiBufSize) { - return 0; + return -1; } int64_t CTuxBoxFile::Seek(int64_t iFilePosition, int iWhence) diff --git a/xbmc/filesystem/TuxBoxFile.h b/xbmc/filesystem/TuxBoxFile.h index 2c5edfdd93..9498f459c3 100644 --- a/xbmc/filesystem/TuxBoxFile.h +++ b/xbmc/filesystem/TuxBoxFile.h @@ -34,7 +34,7 @@ namespace XFILE virtual void Close(); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); protected: }; diff --git a/xbmc/filesystem/UDFFile.cpp b/xbmc/filesystem/UDFFile.cpp index 6426f7e305..c72bb0ff17 100644 --- a/xbmc/filesystem/UDFFile.cpp +++ b/xbmc/filesystem/UDFFile.cpp @@ -26,6 +26,7 @@ #include <sys/stat.h> #include <errno.h> +#include <limits.h> using namespace std; using namespace XFILE; @@ -65,15 +66,18 @@ bool CUDFFile::Open(const CURL& url) } //********************************************************************************************* -unsigned int CUDFFile::Read(void *lpBuf, int64_t uiBufSize) +ssize_t CUDFFile::Read(void *lpBuf, size_t uiBufSize) { - if (!m_bOpened) return 0; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + if (uiBufSize > LONG_MAX) + uiBufSize = LONG_MAX; + + if (!m_bOpened) + return -1; char *pData = (char *)lpBuf; - int iResult = m_udfIsoReaderLocal.ReadFile( m_hFile, (unsigned char*)pData, (long)uiBufSize); - if (iResult == -1) - return 0; - return iResult; + return m_udfIsoReaderLocal.ReadFile( m_hFile, (unsigned char*)pData, (long)uiBufSize); } //********************************************************************************************* diff --git a/xbmc/filesystem/UDFFile.h b/xbmc/filesystem/UDFFile.h index 2326cd8ab4..4bde20be8c 100644 --- a/xbmc/filesystem/UDFFile.h +++ b/xbmc/filesystem/UDFFile.h @@ -38,7 +38,7 @@ public: virtual bool Open(const CURL& url); virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); protected: diff --git a/xbmc/filesystem/UPnPFile.h b/xbmc/filesystem/UPnPFile.h index 4b9a70fccc..0d7e674edf 100644 --- a/xbmc/filesystem/UPnPFile.h +++ b/xbmc/filesystem/UPnPFile.h @@ -32,7 +32,7 @@ namespace XFILE virtual bool Exists(const CURL& url); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize) {return -1;} + virtual ssize_t Read(void* lpBuf, size_t uiBufSize) {return -1;} virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET) {return -1;} virtual void Close(){} virtual int64_t GetPosition() {return -1;} diff --git a/xbmc/filesystem/VTPFile.cpp b/xbmc/filesystem/VTPFile.cpp index 64a8bd9ee1..0aaf984919 100644 --- a/xbmc/filesystem/VTPFile.cpp +++ b/xbmc/filesystem/VTPFile.cpp @@ -92,10 +92,13 @@ bool CVTPFile::Open(const CURL& url2) return true; } -unsigned int CVTPFile::Read(void* buffer, int64_t size) +ssize_t CVTPFile::Read(void* buffer, size_t size) { + if (size > SSIZE_MAX) + size = SSIZE_MAX; + if(m_socket == INVALID_SOCKET) - return 0; + return -1; fd_set set_r, set_e; struct timeval tv; @@ -112,7 +115,7 @@ unsigned int CVTPFile::Read(void* buffer, int64_t size) if(res < 0) { CLog::Log(LOGERROR, "CVTPFile::Read - select failed"); - return 0; + return -1; } if(res == 0) { @@ -120,17 +123,12 @@ unsigned int CVTPFile::Read(void* buffer, int64_t size) return 0; } - res = recv(m_socket, (char*)buffer, (size_t)size, 0); + res = recv(m_socket, (char*)buffer, size, 0); if(res < 0) - { CLog::Log(LOGERROR, "CVTPFile::Read - failed"); - return 0; - } + if(res == 0) - { CLog::Log(LOGERROR, "CVTPFile::Read - eof"); - return 0; - } return res; } diff --git a/xbmc/filesystem/VTPFile.h b/xbmc/filesystem/VTPFile.h index f84dc5015a..750b342150 100644 --- a/xbmc/filesystem/VTPFile.h +++ b/xbmc/filesystem/VTPFile.h @@ -41,7 +41,7 @@ public: virtual int64_t GetLength() { return -1; } virtual int Stat(const CURL& url, struct __stat64* buffer) { return -1; } virtual void Close(); - virtual unsigned int Read(void* buffer, int64_t size); + virtual ssize_t Read(void* buffer, size_t size); virtual std::string GetContent() { return ""; } virtual bool SkipNext() { return m_socket ? true : false; } diff --git a/xbmc/filesystem/ZipFile.cpp b/xbmc/filesystem/ZipFile.cpp index 709d00dd7b..d589bdda34 100644 --- a/xbmc/filesystem/ZipFile.cpp +++ b/xbmc/filesystem/ZipFile.cpp @@ -283,8 +283,11 @@ int CZipFile::Stat(const CURL& url, struct __stat64* buffer) return 0; } -unsigned int CZipFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CZipFile::Read(void* lpBuf, size_t uiBufSize) { + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + if (m_bCached) return mFile.Read(lpBuf,uiBufSize); @@ -328,7 +331,7 @@ unsigned int CZipFile::Read(void* lpBuf, int64_t uiBufSize) if (iMessage < 0) { Close(); - return 0; // READ ERROR + return -1; // READ ERROR } m_bFlush = ((iMessage == Z_OK) && (m_ZStream.avail_out == 0))?true:false; // more info in input buffer @@ -346,13 +349,15 @@ unsigned int CZipFile::Read(void* lpBuf, int64_t uiBufSize) { return 0; // we are past eof, this shouldn't happen but test anyway } - unsigned int iResult = mFile.Read(lpBuf,uiBufSize); + ssize_t iResult = mFile.Read(lpBuf,uiBufSize); + if (iResult < 0) + return -1; m_iZipFilePos += iResult; m_iFilePos += iResult; return iResult; } else - return false; // shouldn't happen. compression method checked in open + return -1; // shouldn't happen. compression method checked in open } void CZipFile::Close() @@ -435,9 +440,9 @@ bool CZipFile::ReadString(char* szLine, int iLineLength) bool CZipFile::FillBuffer() { - unsigned int sToRead = 65535; + ssize_t sToRead = 65535; if (m_iZipFilePos+65535 > mZipItem.csize) - sToRead = static_cast<int>(mZipItem.csize-m_iZipFilePos); + sToRead = mZipItem.csize-m_iZipFilePos; if (sToRead <= 0) return false; // eof! diff --git a/xbmc/filesystem/ZipFile.h b/xbmc/filesystem/ZipFile.h index c2c4ff7a26..facdc7b1a0 100644 --- a/xbmc/filesystem/ZipFile.h +++ b/xbmc/filesystem/ZipFile.h @@ -40,7 +40,7 @@ namespace XFILE virtual bool Exists(const CURL& url); virtual int Stat(struct __stat64* buffer); virtual int Stat(const CURL& url, struct __stat64* buffer); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); //virtual bool ReadString(char *szLine, int iLineLength); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual void Close(); @@ -59,7 +59,7 @@ namespace XFILE char m_szBuffer[65535]; // 64k buffer for compressed data char* m_szStringBuffer; char* m_szStartOfStringBuffer; // never allocated! - int m_iDataInStringBuffer; + size_t m_iDataInStringBuffer; int m_iRead; bool m_bFlush; bool m_bCached; diff --git a/xbmc/filesystem/ZipManager.cpp b/xbmc/filesystem/ZipManager.cpp index 7364cc7348..76fa5d3002 100644 --- a/xbmc/filesystem/ZipManager.cpp +++ b/xbmc/filesystem/ZipManager.cpp @@ -82,8 +82,7 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) } unsigned int hdr; - mFile.Read(&hdr, 4); - if( Endian_SwapLE32(hdr) != ZIP_LOCAL_HEADER ) + if (mFile.Read(&hdr, 4)!=4 || Endian_SwapLE32(hdr) != ZIP_LOCAL_HEADER ) { CLog::Log(LOGDEBUG,"ZipManager: not a zip file!"); mFile.Close(); @@ -107,17 +106,18 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) int extraBlockSize = searchSize % blockSize; // Signature is on 4 bytes // It could be between 2 blocks, so we need to read 3 extra bytes - char *buffer = new char[blockSize+3]; + auto_buffer buffer(blockSize + 3); bool found = false; // Loop through blocks starting at the end of the file (minus ECDREC_SIZE-1) for (int nb=1; !found && (nb <= nbBlock); nb++) { mFile.Seek(fileSize-ECDREC_SIZE+1-(blockSize*nb),SEEK_SET); - mFile.Read(buffer,blockSize+3); + if (mFile.Read(buffer.get(), blockSize + 3) != blockSize + 3) + return false; for (int i=blockSize-1; !found && (i >= 0); i--) { - if ( Endian_SwapLE32(*((unsigned int*)(buffer+i))) == ZIP_END_CENTRAL_HEADER ) + if ( Endian_SwapLE32(*((unsigned int*)(buffer.get()+i))) == ZIP_END_CENTRAL_HEADER ) { // Set current position to start of end of central directory mFile.Seek(fileSize-ECDREC_SIZE+1-(blockSize*nb)+i,SEEK_SET); @@ -130,10 +130,11 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) if ( !found && (extraBlockSize > 0) ) { mFile.Seek(fileSize-ECDREC_SIZE+1-searchSize,SEEK_SET); - mFile.Read(buffer,extraBlockSize+3); + if (mFile.Read(buffer.get(), extraBlockSize + 3) != extraBlockSize + 3) + return false; for (int i=extraBlockSize-1; !found && (i >= 0); i--) { - if ( Endian_SwapLE32(*((unsigned int*)(buffer+i))) == ZIP_END_CENTRAL_HEADER ) + if ( Endian_SwapLE32(*((unsigned int*)(buffer.get()+i))) == ZIP_END_CENTRAL_HEADER ) { // Set current position to start of end of central directory mFile.Seek(fileSize-ECDREC_SIZE+1-searchSize+i,SEEK_SET); @@ -142,7 +143,7 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) } } - delete [] buffer; + buffer.clear(); if ( !found ) { @@ -154,10 +155,12 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) unsigned int cdirOffset, cdirSize; // Get size of the central directory mFile.Seek(12,SEEK_CUR); - mFile.Read(&cdirSize,4); + if (mFile.Read(&cdirSize, 4) != 4) + return false; cdirSize = Endian_SwapLE32(cdirSize); // Get Offset of start of central directory with respect to the starting disk number - mFile.Read(&cdirOffset,4); + if (mFile.Read(&cdirOffset, 4) != 4) + return false; cdirOffset = Endian_SwapLE32(cdirOffset); // Go to the start of central directory @@ -167,7 +170,8 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) while (mFile.GetPosition() < cdirOffset + cdirSize) { SZipEntry ze; - mFile.Read(temp,CHDR_SIZE); + if (mFile.Read(temp, CHDR_SIZE) != CHDR_SIZE) + return false; readCHeader(temp, ze); if (ze.header != ZIP_CENTRAL_HEADER) { @@ -177,9 +181,11 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) } // Get the filename just after the central file header - std::string strName; - strName.resize(ze.flength); - mFile.Read(&strName[0], ze.flength); + auto_buffer bufName(ze.flength); + if (mFile.Read(bufName.get(), ze.flength) != ze.flength) + return false; + std::string strName(bufName.get(), bufName.size()); + bufName.clear(); g_charsetConverter.unknownToUTF8(strName); ZeroMemory(ze.name, 255); strncpy(ze.name, strName.c_str(), strName.size()>254 ? 254 : strName.size()); @@ -197,7 +203,8 @@ bool CZipManager::GetZipList(const CURL& url, vector<SZipEntry>& items) // Go to the local file header to get the extra field length // !! local header extra field length != central file header extra field length !! mFile.Seek(ze.lhdrOffset+28,SEEK_SET); - mFile.Read(&(ze.elength),2); + if (mFile.Read(&(ze.elength), 2) != 2) + return false; ze.elength = Endian_SwapLE16(ze.elength); // Compressed data offset = local header offset + size of local header + filename length + local file header extra field length diff --git a/xbmc/filesystem/posix/PosixFile.cpp b/xbmc/filesystem/posix/PosixFile.cpp index d115d3bcc2..dd0462be98 100644 --- a/xbmc/filesystem/posix/PosixFile.cpp +++ b/xbmc/filesystem/posix/PosixFile.cpp @@ -54,8 +54,6 @@ CPosixFile::~CPosixFile() // local helper static std::string getFilename(const CURL& url) { - assert(url.GetProtocol().empty()); // function suitable only for local files - std::string filename(url.GetFileName()); if (IsAliasShortcut(filename)) TranslateAliasShortcut(filename); @@ -111,12 +109,15 @@ void CPosixFile::Close() } -unsigned int CPosixFile::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CPosixFile::Read(void* lpBuf, size_t uiBufSize) { - assert(lpBuf != NULL); - if (m_fd < 0 || !lpBuf) - return 0; // TODO: return -1 + if (m_fd < 0) + return -1; + assert(lpBuf != NULL || uiBufSize == 0); + if (lpBuf == NULL && uiBufSize != 0) + return -1; + if (uiBufSize > SSIZE_MAX) uiBufSize = SSIZE_MAX; @@ -124,7 +125,7 @@ unsigned int CPosixFile::Read(void* lpBuf, int64_t uiBufSize) if (res < 0) { Seek(0, SEEK_CUR); // force update file position - return 0; // TODO: return -1 + return -1; } if (m_filePos >= 0) @@ -147,13 +148,16 @@ unsigned int CPosixFile::Read(void* lpBuf, int64_t uiBufSize) #endif } - return (unsigned int) res; + return res; } -int CPosixFile::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CPosixFile::Write(const void* lpBuf, size_t uiBufSize) { - assert(lpBuf != NULL); - if (m_fd < 0 || !m_allowWrite || !lpBuf) + if (m_fd < 0) + return -1; + + assert(lpBuf != NULL || uiBufSize == 0); + if ((lpBuf == NULL && uiBufSize != 0) || !m_allowWrite) return -1; if (uiBufSize > SSIZE_MAX) @@ -169,7 +173,7 @@ int CPosixFile::Write(const void* lpBuf, int64_t uiBufSize) if (m_filePos >= 0) m_filePos += res; // if m_filePos was known - update it - return (int)res; + return res; } int64_t CPosixFile::Seek(int64_t iFilePosition, int iWhence /* = SEEK_SET*/) diff --git a/xbmc/filesystem/posix/PosixFile.h b/xbmc/filesystem/posix/PosixFile.h index 2f2d834027..5ea46d5f38 100644 --- a/xbmc/filesystem/posix/PosixFile.h +++ b/xbmc/filesystem/posix/PosixFile.h @@ -34,8 +34,8 @@ namespace XFILE virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false); virtual void Close(); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual int Truncate(int64_t size); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/test/TestRarFile.cpp b/xbmc/filesystem/test/TestRarFile.cpp index 1ee838d0f7..2ea62cfe9a 100644 --- a/xbmc/filesystem/test/TestRarFile.cpp +++ b/xbmc/filesystem/test/TestRarFile.cpp @@ -32,6 +32,10 @@ #include "gtest/gtest.h" +#ifndef S_IFLNK +#define S_IFLNK 0120000 +#endif + TEST(TestRarFile, Read) { XFILE::CFile file; diff --git a/xbmc/filesystem/test/TestZipFile.cpp b/xbmc/filesystem/test/TestZipFile.cpp index 106ba5d4e9..5979ac7b0a 100644 --- a/xbmc/filesystem/test/TestZipFile.cpp +++ b/xbmc/filesystem/test/TestZipFile.cpp @@ -69,6 +69,8 @@ TEST_F(TestZipFile, Read) CURL zipUrl = URIUtils::CreateArchivePath("zip", CURL(reffile), ""); ASSERT_TRUE(XFILE::CDirectory::GetDirectory(zipUrl, itemlist, "", XFILE::DIR_FLAG_NO_FILE_DIRS)); + EXPECT_GT(itemlist.Size(), 0); + EXPECT_FALSE(itemlist[0]->GetPath().empty()); strpathinzip = itemlist[0]->GetPath(); ASSERT_TRUE(file.Open(strpathinzip)); EXPECT_EQ(0, file.GetPosition()); diff --git a/xbmc/filesystem/udf25.cpp b/xbmc/filesystem/udf25.cpp index ee1c7c2165..fdbda46221 100644 --- a/xbmc/filesystem/udf25.cpp +++ b/xbmc/filesystem/udf25.cpp @@ -589,13 +589,11 @@ int udf25::GetUDFCache(UDFCacheType type, uint32_t nr, void *data) int udf25::ReadAt( int64_t pos, size_t len, unsigned char *data ) { - int64_t ret; - ret = m_fp->Seek(pos, SEEK_SET); - if(ret != pos) + if (m_fp->Seek(pos, SEEK_SET) != pos) return -1; - ret = m_fp->Read(data, len); - if(ret < (int64_t)len) + ssize_t ret = m_fp->Read(data, len); + if ( ret < len) { CLog::Log(LOGERROR, "udf25::ReadFile - less data than requested available!" ); return (int)ret; diff --git a/xbmc/filesystem/win32/Win32Directory.cpp b/xbmc/filesystem/win32/Win32Directory.cpp index 9da5a40e09..eb4c5aa395 100644 --- a/xbmc/filesystem/win32/Win32Directory.cpp +++ b/xbmc/filesystem/win32/Win32Directory.cpp @@ -41,9 +41,13 @@ inline static std::wstring prepareWin32DirectoryName(const std::string& strPath) return std::wstring(); // empty string std::wstring nameW(CWIN32Util::ConvertPathToWin32Form(strPath)); - if (!nameW.empty() && nameW.back() == L'\\') - nameW.pop_back(); // remove slash at the end if any - + if (!nameW.empty()) + { + if (nameW.back() == L'\\') + nameW.pop_back(); // remove slash at the end if any + if (nameW.length() == 6 && nameW.back() == L':') // 6 is the length of "\\?\x:" + nameW.push_back(L'\\'); // always add backslash for root folders + } return nameW; } diff --git a/xbmc/filesystem/win32/Win32File.cpp b/xbmc/filesystem/win32/Win32File.cpp index 27798aded3..dfc5babe6b 100644 --- a/xbmc/filesystem/win32/Win32File.cpp +++ b/xbmc/filesystem/win32/Win32File.cpp @@ -78,10 +78,9 @@ bool CWin32File::Open(const CURL& url) } std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); - if (pathnameW.empty()) - return false; + if (pathnameW.length() <= 6) // 6 is length of "\\?\x:" + return false; // pathnameW is empty or points to device ("\\?\x:") - assert(pathnameW.length() > 6); // 6 is length of "//?/x:" assert((pathnameW.compare(4, 4, L"UNC\\", 4) == 0 && m_smbFile) || !m_smbFile); m_filepathnameW = pathnameW; @@ -103,10 +102,9 @@ bool CWin32File::OpenForWrite(const CURL& url, bool bOverWrite /*= false*/) return false; std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); - if (pathnameW.empty()) - return false; + if (pathnameW.length() <= 6) // 6 is length of "\\?\x:" + return false; // pathnameW is empty or points to device ("\\?\x:") - assert(pathnameW.length() > 6); // 6 is length of "//?/x:" assert((pathnameW.compare(4, 4, L"UNC\\", 4) == 0 && m_smbFile) || !m_smbFile); m_hFile = CreateFileW(pathnameW.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, @@ -173,14 +171,19 @@ void CWin32File::Close() m_filepathnameW.clear(); } -unsigned int CWin32File::Read(void* lpBuf, int64_t uiBufSize) +ssize_t CWin32File::Read(void* lpBuf, size_t uiBufSize) { - assert(lpBuf != NULL); - if (m_hFile == INVALID_HANDLE_VALUE || !lpBuf) - return 0; // TODO: return -1 + if (m_hFile == INVALID_HANDLE_VALUE) + return -1; + + assert(lpBuf != NULL || uiBufSize == 0); + if (lpBuf == NULL && uiBufSize != 0) + return -1; - // TODO: Reduce uiBufSize if required/oversized - unsigned int read = 0; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + + ssize_t read = 0; // if uiBufSize is larger than ReadFile() can read at one time (larger than DWORD_MAX) // repeat ReadFile until buffer is filled @@ -190,7 +193,7 @@ unsigned int CWin32File::Read(void* lpBuf, int64_t uiBufSize) if (!ReadFile(m_hFile, ((BYTE*)lpBuf) + read, (uiBufSize > DWORD_MAX) ? DWORD_MAX : (DWORD)uiBufSize, &lastRead, NULL)) { m_filePos = -1; - return 0; // TODO: return -1 + return -1; } read += lastRead; // if m_filePos is set - update it @@ -209,10 +212,13 @@ unsigned int CWin32File::Read(void* lpBuf, int64_t uiBufSize) return read; } -int CWin32File::Write(const void* lpBuf, int64_t uiBufSize) +ssize_t CWin32File::Write(const void* lpBuf, size_t uiBufSize) { - assert(lpBuf != NULL); - if (m_hFile == INVALID_HANDLE_VALUE || !lpBuf) + if (m_hFile == INVALID_HANDLE_VALUE) + return -1; + + assert(lpBuf != NULL || uiBufSize == 0); + if (lpBuf == NULL && uiBufSize != 0) return -1; if (!m_allowWrite) @@ -221,8 +227,10 @@ int CWin32File::Write(const void* lpBuf, int64_t uiBufSize) return -1; } - // TODO: fail on oversized uiBufSize - int written = 0; + if (uiBufSize > SSIZE_MAX) + uiBufSize = SSIZE_MAX; + + ssize_t written = 0; while (uiBufSize > 0) { DWORD lastWritten = 0; @@ -430,10 +438,9 @@ int CWin32File::Stat(const CURL& url, struct __stat64* statData) return -1; std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); - if (pathnameW.empty()) - return -1; + if (pathnameW.length() <= 6) // 6 is length of "\\?\x:" + return -1; // pathnameW is empty or points to device ("\\?\x:"), on win32 stat() for devices is not supported - assert(pathnameW.length() > 6); // 6 is length of "//?/x:" assert((pathnameW.compare(4, 4, L"UNC\\", 4) == 0 && m_smbFile) || !m_smbFile); // get maximum information about file from search function diff --git a/xbmc/filesystem/win32/Win32File.h b/xbmc/filesystem/win32/Win32File.h index 905b14eb5b..0b8e528397 100644 --- a/xbmc/filesystem/win32/Win32File.h +++ b/xbmc/filesystem/win32/Win32File.h @@ -36,8 +36,8 @@ namespace XFILE virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false); virtual void Close(); - virtual unsigned int Read(void* lpBuf, int64_t uiBufSize); - virtual int Write(const void* lpBuf, int64_t uiBufSize); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); virtual int Truncate(int64_t toSize); virtual int64_t GetPosition(); diff --git a/xbmc/filesystem/win32/Win32SMBDirectory.cpp b/xbmc/filesystem/win32/Win32SMBDirectory.cpp index 1bdf71d36d..e2000ef181 100644 --- a/xbmc/filesystem/win32/Win32SMBDirectory.cpp +++ b/xbmc/filesystem/win32/Win32SMBDirectory.cpp @@ -43,6 +43,14 @@ using namespace XFILE; +// local helper +static inline bool worthTryToConnect(const DWORD lastErr) +{ + return lastErr != ERROR_FILE_NOT_FOUND && lastErr != ERROR_BAD_NET_NAME && + lastErr != ERROR_NO_NET_OR_BAD_PATH && lastErr != ERROR_NO_NETWORK && + lastErr != ERROR_BAD_NETPATH; +} + /** * Get servers recursively or get shares from specific server * @param basePathToScanPtr the pointer to start point for scan @@ -119,6 +127,9 @@ bool CWin32SMBDirectory::GetDirectory(const CURL& url, CFileItemList &items) if (hSearch == INVALID_HANDLE_VALUE) { DWORD searchErr = GetLastError(); + if (!worthTryToConnect(searchErr)) + return false; + if (ConnectAndAuthenticate(authUrl, (m_flags & DIR_FLAG_ALLOW_PROMPT) != 0)) { if (g_sysinfo.IsWindowsVersionAtLeast(CSysInfo::WindowsVersionWin7)) @@ -212,7 +223,7 @@ bool CWin32SMBDirectory::RealCreate(const CURL& url, bool tryToConnect) return RealExists(url, false); // is it file or directory? else { - if (tryToConnect) + if (tryToConnect && worthTryToConnect(GetLastError())) { CURL authUrl(url); if (ConnectAndAuthenticate(authUrl)) @@ -309,7 +320,7 @@ bool CWin32SMBDirectory::RealExists(const CURL& url, bool tryToConnect) if (fileAttrs != INVALID_FILE_ATTRIBUTES) return (fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0; // is file or directory? - if (tryToConnect) + if (tryToConnect && worthTryToConnect(GetLastError())) { CURL authUrl(url); if (ConnectAndAuthenticate(authUrl)) @@ -329,6 +340,9 @@ bool CWin32SMBDirectory::Remove(const CURL& url) if (RemoveDirectoryW(nameW.c_str())) return true; + if (!worthTryToConnect(GetLastError())) + return false; + CURL authUrl(url); if (ConnectAndAuthenticate(authUrl) && RemoveDirectoryW(nameW.c_str())) return true; diff --git a/xbmc/guilib/DDSImage.cpp b/xbmc/guilib/DDSImage.cpp index 6a8eae6c69..80f422a244 100644 --- a/xbmc/guilib/DDSImage.cpp +++ b/xbmc/guilib/DDSImage.cpp @@ -138,12 +138,10 @@ bool CDDSImage::WriteFile(const std::string &outputFile) const return false; // write the header - file.Write("DDS ", 4); - file.Write(&m_desc, sizeof(m_desc)); + return file.Write("DDS ", 4) == 4 && + file.Write(&m_desc, sizeof(m_desc)) == sizeof(m_desc) && // now the data - file.Write(m_data, m_desc.linearSize); - file.Close(); - return true; + file.Write(m_data, m_desc.linearSize) == m_desc.linearSize; } unsigned int CDDSImage::GetStorageRequirements(unsigned int width, unsigned int height, unsigned int format) diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp index 38f17a76f1..991ae5b307 100644 --- a/xbmc/guilib/GraphicContext.cpp +++ b/xbmc/guilib/GraphicContext.cpp @@ -363,8 +363,24 @@ bool CGraphicContext::IsValidResolution(RESOLUTION res) return false; } +// call SetVideoResolutionInternal and ensure its done from mainthread void CGraphicContext::SetVideoResolution(RESOLUTION res, bool forceUpdate) { + if (g_application.IsCurrentThread()) + { + SetVideoResolutionInternal(res, forceUpdate); + } + else + { + ThreadMessage msg = {TMSG_SETVIDEORESOLUTION}; + msg.param1 = res; + msg.param2 = forceUpdate ? 1 : 0; + CApplicationMessenger::Get().SendMessage(msg, true); + } +} + +void CGraphicContext::SetVideoResolutionInternal(RESOLUTION res, bool forceUpdate) +{ RESOLUTION lastRes = m_Resolution; // If the user asked us to guess, go with desktop diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h index 6c2dcd4371..c2a4c16b65 100644 --- a/xbmc/guilib/GraphicContext.h +++ b/xbmc/guilib/GraphicContext.h @@ -262,6 +262,9 @@ private: float scaleY; }; void UpdateCameraPosition(const CPoint &camera); + // this method is indirectly called by the public SetVideoResolution + // it only works when called from mainthread (thats what SetVideoResolution ensures) + void SetVideoResolutionInternal(RESOLUTION res, bool forceUpdate); RESOLUTION_INFO m_windowResolution; std::stack<CPoint> m_cameras; std::stack<CPoint> m_origins; diff --git a/xbmc/guilib/JpegIO.cpp b/xbmc/guilib/JpegIO.cpp index c9ff97f13d..236bd520b6 100644 --- a/xbmc/guilib/JpegIO.cpp +++ b/xbmc/guilib/JpegIO.cpp @@ -526,15 +526,10 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int wid delete [] rgbbuf; XFILE::CFile file; - if (file.OpenForWrite(destFile, true)) - { - file.Write(result, outBufSize); - file.Close(); - free(result); - return true; - } + const bool ret = file.OpenForWrite(destFile, true) && file.Write(result, outBufSize) == outBufSize; free(result); - return false; + + return ret; } // override libjpeg's error function to avoid an exit() call diff --git a/xbmc/guilib/Key.h b/xbmc/guilib/Key.h index 5693bd9f96..1a6e46d0f4 100644 --- a/xbmc/guilib/Key.h +++ b/xbmc/guilib/Key.h @@ -249,7 +249,6 @@ #define ACTION_ANALOG_SEEK_BACK 125 // seeks backward, and displays the seek bar. #define ACTION_VIS_PRESET_SHOW 126 -#define ACTION_VIS_PRESET_LIST 127 #define ACTION_VIS_PRESET_NEXT 128 #define ACTION_VIS_PRESET_PREV 129 #define ACTION_VIS_PRESET_LOCK 130 diff --git a/xbmc/guilib/TexturePi.cpp b/xbmc/guilib/TexturePi.cpp index 3950b3fd5f..a17bfba970 100644 --- a/xbmc/guilib/TexturePi.cpp +++ b/xbmc/guilib/TexturePi.cpp @@ -142,8 +142,8 @@ bool CPiTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned in if (okay) { m_hasAlpha = false; - if (autoRotate && orientation) - m_orientation = orientation - 1; + if (autoRotate) + m_orientation = orientation; return true; } } diff --git a/xbmc/input/ButtonTranslator.cpp b/xbmc/input/ButtonTranslator.cpp index a91c183808..467fadd60e 100644 --- a/xbmc/input/ButtonTranslator.cpp +++ b/xbmc/input/ButtonTranslator.cpp @@ -33,8 +33,10 @@ #include "utils/StringUtils.h" #include "utils/log.h" #include "utils/XBMCTinyXML.h" +#include "utils/RegExp.h" #include "XBIRRemote.h" #include "Util.h" +#include <boost/shared_ptr.hpp> #if defined(TARGET_WINDOWS) #include "input/windows/WINJoystick.h" @@ -179,7 +181,6 @@ static const ActionMapping actions[] = {"analogseekforward" , ACTION_ANALOG_SEEK_FORWARD}, {"analogseekback" , ACTION_ANALOG_SEEK_BACK}, {"showpreset" , ACTION_VIS_PRESET_SHOW}, - {"presetlist" , ACTION_VIS_PRESET_LIST}, {"nextpreset" , ACTION_VIS_PRESET_NEXT}, {"previouspreset" , ACTION_VIS_PRESET_PREV}, {"lockpreset" , ACTION_VIS_PRESET_LOCK}, @@ -759,10 +760,11 @@ int CButtonTranslator::TranslateLircRemoteString(const char* szDevice, const cha void CButtonTranslator::MapJoystickActions(int windowID, TiXmlNode *pJoystick) { string joyname = JOYSTICK_DEFAULT_MAP; // default global map name - vector<string> joynames; + vector<boost::shared_ptr<CRegExp> > joynames; map<int, string> buttonMap; map<int, string> axisMap; - map<int, string> hatMap; + AxesConfig axesConfig; + ActionMap hatMap; TiXmlElement *pJoy = pJoystick->ToElement(); if (pJoy && pJoy->Attribute("name")) @@ -770,7 +772,14 @@ void CButtonTranslator::MapJoystickActions(int windowID, TiXmlNode *pJoystick) else CLog::Log(LOGNOTICE, "No Joystick name specified, loading default map"); - joynames.push_back(joyname); + boost::shared_ptr<CRegExp> re(new CRegExp(true, CRegExp::asciiOnly)); + if (!re->RegComp(JoynameToRegex(joyname), CRegExp::StudyRegExp)) + { + CLog::Log(LOGNOTICE, "Invalid joystick regex specified: '%s'", joyname.c_str()); + return; + } + else + joynames.push_back(re); // parse map TiXmlElement *pButton = pJoystick->FirstChildElement(); @@ -811,6 +820,17 @@ void CButtonTranslator::MapJoystickActions(int windowID, TiXmlNode *pJoystick) axisMap[id] = action; axisMap[-id] = action; } + + if (windowID == -1) { + // in <global> we can override the rest state value of axes and whether they are triggers + bool trigger = false; + int restStateValue = 0; + pButton->QueryBoolAttribute("trigger", &trigger); + pButton->QueryIntAttribute("rest", &restStateValue); + // if it deviates from the defaults + if (trigger || restStateValue != 0) + axesConfig.push_back(AxisConfig(id, trigger, restStateValue)); + } } else if (type == "hat") { @@ -834,29 +854,79 @@ void CButtonTranslator::MapJoystickActions(int windowID, TiXmlNode *pJoystick) CLog::Log(LOGERROR, "Error reading joystick map element, unknown button type: %s", type.c_str()); } else if (type == "altname") - joynames.push_back(action); + { + boost::shared_ptr<CRegExp> altRe(new CRegExp(true, CRegExp::asciiOnly)); + if (!altRe->RegComp(JoynameToRegex(action), CRegExp::StudyRegExp)) + CLog::Log(LOGNOTICE, "Ignoring invalid joystick altname regex: '%s'", action.c_str()); + else + joynames.push_back(altRe); + } else CLog::Log(LOGERROR, "Error reading joystick map element, Invalid id: %d", id); pButton = pButton->NextSiblingElement(); } - vector<string>::iterator it = joynames.begin(); + vector<boost::shared_ptr<CRegExp> >::iterator it = joynames.begin(); while (it!=joynames.end()) { - m_joystickButtonMap[*it][windowID] = buttonMap; - m_joystickAxisMap[*it][windowID] = axisMap; - m_joystickHatMap[*it][windowID] = hatMap; + MergeMap(*it, &m_joystickButtonMap, windowID, buttonMap); + MergeMap(*it, &m_joystickAxisMap, windowID, axisMap); + MergeMap(*it, &m_joystickHatMap, windowID, hatMap); + if (windowID == -1) + m_joystickAxesConfigs[*it] = axesConfig; // CLog::Log(LOGDEBUG, "Found Joystick map for window %d using %s", windowID, it->c_str()); it++; } } -bool CButtonTranslator::TranslateJoystickString(int window, const char* szDevice, int id, short inputType, int& action, std::string& strAction, bool &fullrange) +std::string CButtonTranslator::JoynameToRegex(const std::string& joyName) const +{ + if (joyName.empty()) + return joyName; + + // names already presented as regex are identified by a leading / + else if (joyName[0] == '/') + return joyName.substr(1); + + // the others we'll have to escape + return "\\Q" + joyName + "\\E"; +} + +void CButtonTranslator::MergeMap(boost::shared_ptr<CRegExp> joyName, JoystickMap *joystick, int windowID, const ActionMap &map) +{ + // find or create WindowMap entry, match on pattern equality + JoystickMap::iterator jit; + for (jit = joystick->begin(); jit != joystick->end(); jit++) + { + if (jit->first->GetPattern() == joyName->GetPattern()) + break; + } + WindowMap* w = (jit == joystick->end()) ? &(*joystick)[joyName] : &jit->second; + // find or create ActionMap, and merge it + (*w)[windowID].insert(map.begin(), map.end()); +} + +CButtonTranslator::JoystickMap::const_iterator CButtonTranslator::FindWindowMap(const std::string& joyName, const JoystickMap &maps) const +{ + JoystickMap::const_iterator it; + for (it = maps.begin(); it != maps.end(); it++) + { + if (it->first->RegFind(joyName) >= 0) + { + // CLog::Log(LOGDEBUG, "Regex %s matches joystick %s", it->first->GetPattern().c_str(), joyName.c_str()); + break; + } + // CLog::Log(LOGDEBUG, "No match: %s for joystick %s", it->first->GetPattern().c_str(), joyName.c_str()); + } + return it; +} + +bool CButtonTranslator::TranslateJoystickString(int window, const std::string& joyName, int id, short inputType, int& action, std::string& strAction, bool &fullrange) { fullrange = false; // resolve the correct JoystickMap - map<string, JoystickMap> *jmap; + JoystickMap *jmap; if (inputType == JACTIVE_AXIS) jmap = &m_joystickAxisMap; else if (inputType == JACTIVE_BUTTON) @@ -869,15 +939,15 @@ bool CButtonTranslator::TranslateJoystickString(int window, const char* szDevice return false; } - map<string, JoystickMap>::iterator it = jmap->find(szDevice); + JoystickMap::const_iterator it = FindWindowMap(joyName, *jmap); if (it==jmap->end()) { - it = jmap->find(JOYSTICK_DEFAULT_MAP); // default global map name + it = FindWindowMap(JOYSTICK_DEFAULT_MAP, *jmap); // default global map name if (it==jmap->end()) return false; } - JoystickMap wmap = it->second; + WindowMap wmap = it->second; // try to get the action from the current window action = GetActionCode(window, id, wmap, strAction, fullrange); @@ -934,12 +1004,12 @@ int CButtonTranslator::GetActionCode(int window, int action) /* * Translates a joystick input to an action code */ -int CButtonTranslator::GetActionCode(int window, int id, const JoystickMap &wmap, std::string &strAction, bool &fullrange) const +int CButtonTranslator::GetActionCode(int window, int id, const WindowMap &wmap, std::string &strAction, bool &fullrange) const { int action = 0; bool found = false; - JoystickMap::const_iterator it = wmap.find(window); + WindowMap::const_iterator it = wmap.find(window); if (it != wmap.end()) { const map<int, string> &windowbmap = it->second; diff --git a/xbmc/input/ButtonTranslator.h b/xbmc/input/ButtonTranslator.h index 740810ac26..1d10bca8c5 100644 --- a/xbmc/input/ButtonTranslator.h +++ b/xbmc/input/ButtonTranslator.h @@ -35,11 +35,15 @@ class CKey; class CAction; class TiXmlNode; +struct AxisConfig; +class CRegExp; +typedef std::vector<AxisConfig> AxesConfig; // [<axis, isTrigger, rest state value>] +namespace boost { template <typename T> class shared_ptr; } struct CButtonAction { int id; - std::string strID; // needed for "XBMC.ActivateWindow()" type actions + std::string strID; // needed for "ActivateWindow()" type actions }; /// /// singleton class to map from buttons to actions @@ -91,9 +95,11 @@ public: int TranslateLircRemoteString(const char* szDevice, const char *szButton); #if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER) - bool TranslateJoystickString(int window, const char* szDevice, int id, + bool TranslateJoystickString(int window, const std::string& szDevice, int id, short inputType, int& action, std::string& strAction, bool &fullrange); + + const std::map<boost::shared_ptr<CRegExp>, AxesConfig>& GetAxesConfigs() { return m_joystickAxesConfigs; }; #endif bool TranslateTouchAction(int window, int touchAction, int touchPointers, int &action); @@ -109,8 +115,10 @@ private: int GetActionCode(int window, int action); int GetActionCode(int window, const CKey &key, std::string &strAction) const; #if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER) - typedef std::map<int, std::map<int, std::string> > JoystickMap; // <window, <button/axis, action> > - int GetActionCode(int window, int id, const JoystickMap &wmap, std::string &strAction, bool &fullrange) const; + typedef std::map<int, std::string> ActionMap; // <button/axis, action> + typedef std::map<int, ActionMap > WindowMap; // <window, actionMap> + typedef std::map<boost::shared_ptr<CRegExp>, WindowMap> JoystickMap; // <joystick, windowMap> + int GetActionCode(int window, int id, const WindowMap &wmap, std::string &strAction, bool &fullrange) const; #endif int GetFallbackWindow(int windowID); @@ -139,10 +147,13 @@ private: #if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER) void MapJoystickActions(int windowID, TiXmlNode *pJoystick); - - std::map<std::string, JoystickMap> m_joystickButtonMap; // <joy name, button map> - std::map<std::string, JoystickMap> m_joystickAxisMap; // <joy name, axis map> - std::map<std::string, JoystickMap> m_joystickHatMap; // <joy name, hat map> + std::string JoynameToRegex(const std::string& joyName) const; + void MergeMap(boost::shared_ptr<CRegExp> joyName, JoystickMap *joystick, int windowID, const ActionMap &actionMap); + JoystickMap::const_iterator FindWindowMap(const std::string& joyName, const JoystickMap &maps) const; + JoystickMap m_joystickButtonMap; // <joy name, button map> + JoystickMap m_joystickAxisMap; // <joy name, axis map> + JoystickMap m_joystickHatMap; // <joy name, hat map> + std::map<boost::shared_ptr<CRegExp>, AxesConfig> m_joystickAxesConfigs; // <joy name, axes config> #endif void MapTouchActions(int windowID, TiXmlNode *pTouch); diff --git a/xbmc/input/SDLJoystick.cpp b/xbmc/input/SDLJoystick.cpp index e1ff570050..21b26cbe76 100644 --- a/xbmc/input/SDLJoystick.cpp +++ b/xbmc/input/SDLJoystick.cpp @@ -20,32 +20,26 @@ #include "system.h" #include "SDLJoystick.h" -#include "ButtonTranslator.h" #include "peripherals/devices/PeripheralImon.h" #include "settings/AdvancedSettings.h" #include "settings/lib/Setting.h" #include "utils/log.h" #include "utils/StringUtils.h" +#include "utils/RegExp.h" #include <math.h> +#include <boost/shared_ptr.hpp> #ifdef HAS_SDL_JOYSTICK -#include <SDL/SDL.h> +#include <SDL2/SDL.h> using namespace std; CJoystick::CJoystick() { - Reset(true); m_joystickEnabled = false; - m_NumAxes = 0; - m_AxisId = 0; - m_JoyId = 0; - m_ButtonId = 0; - m_HatId = 0; - m_HatState = SDL_HAT_CENTERED; - m_ActiveFlags = JACTIVE_NONE; SetDeadzone(0); + Reset(); } void CJoystick::OnSettingChanged(const CSetting *setting) @@ -58,6 +52,16 @@ void CJoystick::OnSettingChanged(const CSetting *setting) SetEnabled(((CSettingBool*)setting)->GetValue() && PERIPHERALS::CPeripheralImon::GetCountOfImonsConflictWithDInput() == 0); } +void CJoystick::Reset() +{ + m_AxisIdx = -1; + m_ButtonIdx = -1; + m_HatIdx = -1; + m_HatState = SDL_HAT_CENTERED; + for (std::vector<AxisState>::iterator it = m_Axes.begin(); it != m_Axes.end(); ++it) + it->reset(); +} + void CJoystick::Initialize() { if (!IsEnabled()) @@ -69,92 +73,70 @@ void CJoystick::Initialize() return; } - // clear old joystick names - m_JoystickNames.clear(); - - // any open ones? if so, close them. - if (m_Joysticks.size()>0) - { - for(size_t idJoy = 0; idJoy < m_Joysticks.size(); idJoy++) - { - // any joysticks unplugged? - if(SDL_JoystickOpened(idJoy)) - SDL_JoystickClose(m_Joysticks[idJoy]); - } - m_Joysticks.clear(); - m_JoyId = -1; - } + Reset(); // Set deadzone range SetDeadzone(g_advancedSettings.m_controllerDeadzone); - // any joysticks connected? - if (SDL_NumJoysticks()>0) - { - // load joystick names and open all connected joysticks - for (int i = 0 ; i<SDL_NumJoysticks() ; i++) - { - SDL_Joystick *joy = SDL_JoystickOpen(i); - -#if defined(TARGET_DARWIN) - // On OS X, the 360 controllers are handled externally, since the SDL code is - // really buggy and doesn't handle disconnects. - // - if (std::string(SDL_JoystickName(i)).find("360") != std::string::npos) - { - CLog::Log(LOGNOTICE, "Ignoring joystick: %s", SDL_JoystickName(i)); - continue; - } -#endif - if (joy) - { - // Some (Microsoft) Keyboards are recognized as Joysticks by modern kernels - // Don't enumerate them - // https://bugs.launchpad.net/ubuntu/+source/linux/+bug/390959 - // NOTICE: Enabled Joystick: Microsoft Wired Keyboard 600 - // Details: Total Axis: 37 Total Hats: 0 Total Buttons: 57 - // NOTICE: Enabled Joystick: Microsoft Microsoft® 2.4GHz Transceiver v6.0 - // Details: Total Axis: 37 Total Hats: 0 Total Buttons: 57 - // also checks if we have at least 1 button, fixes - // NOTICE: Enabled Joystick: ST LIS3LV02DL Accelerometer - // Details: Total Axis: 3 Total Hats: 0 Total Buttons: 0 - int num_axis = SDL_JoystickNumAxes(joy); - int num_buttons = SDL_JoystickNumButtons(joy); - if ((num_axis > 20 && num_buttons > 50) || num_buttons == 0) - { - CLog::Log(LOGNOTICE, "Ignoring Joystick %s Axis: %d Buttons: %d: invalid device properties", - SDL_JoystickName(i), num_axis, num_buttons); - } - else - { - m_JoystickNames.push_back(string(SDL_JoystickName(i))); - CLog::Log(LOGNOTICE, "Enabled Joystick: %s", SDL_JoystickName(i)); - CLog::Log(LOGNOTICE, "Details: Total Axis: %d Total Hats: %d Total Buttons: %d", - num_axis, SDL_JoystickNumHats(joy), num_buttons); - m_Joysticks.push_back(joy); - } - } - else - { - m_JoystickNames.push_back(string("")); - } - } - } - - // disable joystick events, since we'll be polling them - SDL_JoystickEventState(SDL_DISABLE); + // joysticks will be loaded once SDL sees them } -void CJoystick::Reset(bool axis /*=false*/) +void CJoystick::AddJoystick(int joyIndex) { - if (axis) + SDL_Joystick *joy = SDL_JoystickOpen(joyIndex); + if (!joy) + return; + + std::string joyName = std::string(SDL_JoystickName(joy)); + + + // Some (Microsoft) Keyboards are recognized as Joysticks by modern kernels + // Don't enumerate them + // https://bugs.launchpad.net/ubuntu/+source/linux/+bug/390959 + // NOTICE: Enabled Joystick: Microsoft Wired Keyboard 600 + // Details: Total Axis: 37 Total Hats: 0 Total Buttons: 57 + // NOTICE: Enabled Joystick: Microsoft Microsoft® 2.4GHz Transceiver v6.0 + // Details: Total Axis: 37 Total Hats: 0 Total Buttons: 57 + // also checks if we have at least 1 button, fixes + // NOTICE: Enabled Joystick: ST LIS3LV02DL Accelerometer + // Details: Total Axis: 3 Total Hats: 0 Total Buttons: 0 + int num_axis = SDL_JoystickNumAxes(joy); + int num_buttons = SDL_JoystickNumButtons(joy); + int num_hats = SDL_JoystickNumHats(joy); + if ((num_axis > 20 && num_buttons > 50) || num_buttons == 0) { - SetAxisActive(false); - for (int i = 0 ; i<MAX_AXES ; i++) - { - ResetAxis(i); - } + CLog::Log(LOGNOTICE, "Ignoring Joystick %s Axis: %d Buttons: %d: invalid device properties", + joyName.c_str(), num_axis, num_buttons); + return; } + + // get details + CLog::Log(LOGNOTICE, "Enabled Joystick: %s", joyName.c_str()); + CLog::Log(LOGNOTICE, "Details: Total Axis: %d Total Hats: %d Total Buttons: %d", + num_axis, num_hats, num_buttons); + + // store joystick and its instance id for lookups + int id = SDL_JoystickInstanceID(joy); + m_Joysticks[id] = joy; + m_Axes.resize(m_Axes.size() + num_axis); + + // all indices may have changed in m_Joysticks, so we have to invalidate m_Axes + ApplyAxesConfigs(); + Reset(); +} + +void CJoystick::RemoveJoystick(int id) +{ + CLog::Log(LOGDEBUG, "Joystick with id %d removed", id); + + // invalidate our current values + SDL_Joystick *joy = m_Joysticks[id]; + m_Axes.resize(m_Axes.size() - SDL_JoystickNumAxes(joy)); + SDL_JoystickClose(joy); + m_Joysticks.erase(id); + // all indices may have changed in m_Joysticks, so we have to invalidate m_Axes + ApplyAxesConfigs(); + Reset(); } void CJoystick::Update() @@ -162,116 +144,87 @@ void CJoystick::Update() if (!IsEnabled()) return; - int buttonId = -1; - int axisId = -1; - int hatId = -1; - int numj = m_Joysticks.size(); - if (numj <= 0) - return; - // update the state of all opened joysticks SDL_JoystickUpdate(); + int axisNum; + int buttonIdx = -1, buttonNum; + int hatIdx = -1, hatNum; // go through all joysticks - for (int j = 0; j<numj; j++) + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end(); ++it) { - SDL_Joystick *joy = m_Joysticks[j]; + SDL_Joystick *joy = it->second; int numb = SDL_JoystickNumButtons(joy); int numhat = SDL_JoystickNumHats(joy); int numax = SDL_JoystickNumAxes(joy); - numax = (numax>MAX_AXES)?MAX_AXES:numax; - int axisval; uint8_t hatval; - // get button states first, they take priority over axis for (int b = 0 ; b<numb ; b++) { if (SDL_JoystickGetButton(joy, b)) { - m_JoyId = SDL_JoystickIndex(joy); - buttonId = b+1; - j = numj-1; + buttonIdx = MapButton(joy, b); break; } } - + for (int h = 0; h < numhat; h++) { hatval = SDL_JoystickGetHat(joy, h); if (hatval != SDL_HAT_CENTERED) { - m_JoyId = SDL_JoystickIndex(joy); - hatId = h + 1; + hatIdx = MapHat(joy, h); m_HatState = hatval; - j = numj-1; break; } } // get axis states - m_NumAxes = numax; for (int a = 0 ; a<numax ; a++) { - axisval = SDL_JoystickGetAxis(joy, a); - axisId = a+1; - if (axisId<=0 || axisId>=MAX_AXES) - { - CLog::Log(LOGERROR, "Axis Id out of range. Maximum supported axis: %d", MAX_AXES); - } - else - { - m_Amount[axisId] = axisval; //[-32768 to 32767] - } - } - m_AxisId = GetAxisWithMaxAmount(); - if (m_AxisId) - { - m_JoyId = SDL_JoystickIndex(joy); - j = numj-1; - break; + int axisIdx = MapAxis(joy, a); + m_Axes[axisIdx].val = SDL_JoystickGetAxis(joy, a); } } - if(hatId==-1) + SDL_Joystick *joy; + m_AxisIdx = GetAxisWithMaxAmount(); + if (m_AxisIdx >= 0) { - if(m_HatId!=0) - CLog::Log(LOGDEBUG, "Joystick %d hat %u Centered", m_JoyId, hatId); + MapAxis(m_AxisIdx, joy, axisNum); + // CLog::Log(LOGDEBUG, "Joystick %d Axis %d Amount %d", JoystickIndex(joy), axisNum + 1, m_Axes[m_AxisIdx].val); + } + + if (hatIdx == -1 && m_HatIdx != -1) + { + // now centered + MapHat(m_HatIdx, joy, hatNum); + CLog::Log(LOGDEBUG, "Joystick %d hat %u hat centered", JoystickIndex(joy), hatNum + 1); m_pressTicksHat = 0; - SetHatActive(false); - m_HatId = 0; } - else + else if (hatIdx != m_HatIdx) { - if(hatId!=m_HatId) - { - CLog::Log(LOGDEBUG, "Joystick %d hat %u Down", m_JoyId, hatId); - m_HatId = hatId; - m_pressTicksHat = SDL_GetTicks(); - } - SetHatActive(); + MapHat(hatIdx, joy, hatNum); + CLog::Log(LOGDEBUG, "Joystick %d hat %u value %d", JoystickIndex(joy), hatNum + 1, m_HatState); + m_pressTicksHat = SDL_GetTicks(); } + m_HatIdx = hatIdx; - if (buttonId==-1) + if (buttonIdx == -1 && m_ButtonIdx != -1) { - if (m_ButtonId!=0) - { - CLog::Log(LOGDEBUG, "Joystick %d button %d Up", m_JoyId, m_ButtonId); - } + MapButton(m_ButtonIdx, joy, buttonNum); + CLog::Log(LOGDEBUG, "Joystick %d button %d Up", JoystickIndex(joy), buttonNum + 1); m_pressTicksButton = 0; - SetButtonActive(false); - m_ButtonId = 0; + m_ButtonIdx = -1; } - else + else if (buttonIdx != m_ButtonIdx) { - if (buttonId!=m_ButtonId) - { - CLog::Log(LOGDEBUG, "Joystick %d button %d Down", m_JoyId, buttonId); - m_ButtonId = buttonId; - m_pressTicksButton = SDL_GetTicks(); - } - SetButtonActive(); + MapButton(buttonIdx, joy, buttonNum); + CLog::Log(LOGDEBUG, "Joystick %d button %d Down", JoystickIndex(joy), buttonNum + 1); + m_pressTicksButton = SDL_GetTicks(); } - + m_ButtonIdx = buttonIdx; } void CJoystick::Update(SDL_Event& joyEvent) @@ -279,185 +232,128 @@ void CJoystick::Update(SDL_Event& joyEvent) if (!IsEnabled()) return; - int buttonId = -1; - int axisId = -1; - int joyId = -1; - DECLARE_UNUSED(bool,ignore = false) - DECLARE_UNUSED(bool,axis = false); - switch(joyEvent.type) { - case SDL_JOYBUTTONDOWN: - m_JoyId = joyId = joyEvent.jbutton.which; - m_ButtonId = buttonId = joyEvent.jbutton.button + 1; - m_pressTicksButton = SDL_GetTicks(); - SetButtonActive(); - CLog::Log(LOGDEBUG, "Joystick %d button %d Down", joyId, buttonId); - break; - - case SDL_JOYAXISMOTION: - joyId = joyEvent.jaxis.which; - axisId = joyEvent.jaxis.axis + 1; - m_NumAxes = SDL_JoystickNumAxes(m_Joysticks[joyId]); - if (axisId<=0 || axisId>=MAX_AXES) - { - CLog::Log(LOGERROR, "Axis Id out of range. Maximum supported axis: %d", MAX_AXES); - ignore = true; - break; - } - axis = true; - m_JoyId = joyId; - if (joyEvent.jaxis.value==0) - { - ignore = true; - m_Amount[axisId] = 0; - } - else - { - m_Amount[axisId] = joyEvent.jaxis.value; //[-32768 to 32767] - } - m_AxisId = GetAxisWithMaxAmount(); - CLog::Log(LOGDEBUG, "Joystick %d Axis %d Amount %d", joyId, axisId, m_Amount[axisId]); - break; - - case SDL_JOYHATMOTION: - m_JoyId = joyId = joyEvent.jbutton.which; - m_HatId = joyEvent.jhat.hat + 1; - m_pressTicksHat = SDL_GetTicks(); - m_HatState = joyEvent.jhat.value; - SetHatActive(m_HatState != SDL_HAT_CENTERED); - CLog::Log(LOGDEBUG, "Joystick %d Hat %d Down with position %d", joyId, buttonId, m_HatState); + // we do not handle the button/axis/hat events here because + // only Update() is equipped to handle keyrepeats + case SDL_JOYDEVICEADDED: + AddJoystick(joyEvent.jdevice.which); break; - case SDL_JOYBALLMOTION: - ignore = true; - break; - - case SDL_JOYBUTTONUP: - m_pressTicksButton = 0; - SetButtonActive(false); - CLog::Log(LOGDEBUG, "Joystick %d button %d Up", joyEvent.jbutton.which, m_ButtonId); - - default: - ignore = true; + case SDL_JOYDEVICEREMOVED: + RemoveJoystick(joyEvent.jdevice.which); break; } } -bool CJoystick::GetHat(int &id, int &position,bool consider_repeat) +bool CJoystick::GetHat(std::string &joyName, int &id, int &position, bool consider_repeat) { if (!IsEnabled() || !IsHatActive()) - { - id = position = 0; return false; - } + + SDL_Joystick *joy; + MapHat(m_HatIdx, joy, id); + joyName = std::string(SDL_JoystickName(joy)); position = m_HatState; - id = m_HatId; + if (!consider_repeat) return true; - static uint32_t lastPressTicks = 0; - static uint32_t lastTicks = 0; - static uint32_t nowTicks = 0; - - if ((m_HatId>=0) && m_pressTicksHat) + static uint32_t lastPressTicksHat = 0; + // allow it if it is the first press + if (lastPressTicksHat < m_pressTicksHat) { - // return the id if it's the first press - if (lastPressTicks!=m_pressTicksHat) - { - lastPressTicks = m_pressTicksHat; - return true; - } - nowTicks = SDL_GetTicks(); - if ((nowTicks-m_pressTicksHat)<500) // 500ms delay before we repeat - return false; - if ((nowTicks-lastTicks)<100) // 100ms delay before successive repeats - return false; - - lastTicks = nowTicks; + lastPressTicksHat = m_pressTicksHat; + return true; } + uint32_t nowTicks = SDL_GetTicks(); + if (nowTicks - m_pressTicksHat < 500) // 500ms delay before we repeat + return false; + if (nowTicks - lastPressTicksHat < 100) // 100ms delay before successive repeats + return false; + lastPressTicksHat = nowTicks; return true; -} +} -bool CJoystick::GetButton(int &id, bool consider_repeat) +bool CJoystick::GetButton(std::string &joyName, int& id, bool consider_repeat) { if (!IsEnabled() || !IsButtonActive()) - { - id = 0; return false; - } + + SDL_Joystick *joy; + MapButton(m_ButtonIdx, joy, id); + joyName = SDL_JoystickName(joy); + if (!consider_repeat) - { - id = m_ButtonId; return true; - } - - static uint32_t lastPressTicks = 0; - static uint32_t lastTicks = 0; - static uint32_t nowTicks = 0; - if ((m_ButtonId>=0) && m_pressTicksButton) + static uint32_t lastPressTicksButton = 0; + // allow it if it is the first press + if (lastPressTicksButton < m_pressTicksButton) { - // return the id if it's the first press - if (lastPressTicks!=m_pressTicksButton) - { - lastPressTicks = m_pressTicksButton; - id = m_ButtonId; - return true; - } - nowTicks = SDL_GetTicks(); - if ((nowTicks-m_pressTicksButton)<500) // 500ms delay before we repeat - { - return false; - } - if ((nowTicks-lastTicks)<100) // 100ms delay before successive repeats - { - return false; - } - lastTicks = nowTicks; + lastPressTicksButton = m_pressTicksButton; + return true; } - id = m_ButtonId; + uint32_t nowTicks = SDL_GetTicks(); + if (nowTicks - m_pressTicksButton < 500) // 500ms delay before we repeat + return false; + if (nowTicks - lastPressTicksButton < 100) // 100ms delay before successive repeats + return false; + + lastPressTicksButton = nowTicks; return true; } -bool CJoystick::GetAxis (int &id) +bool CJoystick::GetAxis(std::string &joyName, int& id) const { if (!IsEnabled() || !IsAxisActive()) - { - id = 0; - return false; - } - id = m_AxisId; - return true; + return false; + + SDL_Joystick *joy; + MapAxis(m_AxisIdx, joy, id); + joyName = std::string(SDL_JoystickName(joy)); + + return true; } -int CJoystick::GetAxisWithMaxAmount() +int CJoystick::GetAxisWithMaxAmount() const { - static int maxAmount; - static int axis; - axis = 0; - maxAmount = 0; - int tempf; - for (int i = 1 ; i<=m_NumAxes ; i++) + int maxAmount= 0, axis = -1; + for (size_t i = 0; i < m_Axes.size(); i++) { - tempf = abs(m_Amount[i]); - if (tempf>m_DeadzoneRange && tempf>maxAmount) + int deadzone = m_Axes[i].trigger ? 0 : m_DeadzoneRange, + amount = abs(m_Axes[i].val - m_Axes[i].rest); + if (amount > deadzone && amount > maxAmount) { - maxAmount = tempf; + maxAmount = amount; axis = i; } } - SetAxisActive(0 != maxAmount); return axis; } -float CJoystick::GetAmount(int axis) +float CJoystick::GetAmount(std::string &joyName, int axisNum) const { - if (m_Amount[axis] > m_DeadzoneRange) - return (float)(m_Amount[axis]-m_DeadzoneRange)/(float)(MAX_AXISAMOUNT-m_DeadzoneRange); - if (m_Amount[axis] < -m_DeadzoneRange) - return (float)(m_Amount[axis]+m_DeadzoneRange)/(float)(MAX_AXISAMOUNT-m_DeadzoneRange); + // find matching SDL_Joystick* + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end(); ++it) + if (std::string(SDL_JoystickName(it->second)) == joyName) + break; + + if (it == m_Joysticks.end()) + return 0; // invalid joy name + + int axisIdx = MapAxis(it->second, axisNum); + int amount = m_Axes[axisIdx].val - m_Axes[axisIdx].rest; + int range = MAX_AXISAMOUNT - m_Axes[axisIdx].rest; + // deadzones on axes are undesirable + int deadzone = m_Axes[axisIdx].trigger ? 0 : m_DeadzoneRange; + if (amount > deadzone) + return (float)(amount - deadzone) / (float)(range - deadzone); + else if (amount < -deadzone) + return (float)(amount + deadzone) / (float)(range - deadzone); + return 0; } @@ -485,13 +381,12 @@ float CJoystick::SetDeadzone(float val) bool CJoystick::ReleaseJoysticks() { + // close open joysticks + for (std::map<int, SDL_Joystick*>::const_iterator it = m_Joysticks.begin(); it != m_Joysticks.end(); ++it) + SDL_JoystickClose(it->second); m_Joysticks.clear(); - m_JoystickNames.clear(); - m_HatId = 0; - m_ButtonId = 0; - m_HatState = SDL_HAT_CENTERED; - m_ActiveFlags = JACTIVE_NONE; - Reset(true); + m_Axes.clear(); + Reset(); // Restart SDL joystick subsystem SDL_QuitSubSystem(SDL_INIT_JOYSTICK); @@ -511,4 +406,150 @@ bool CJoystick::Reinitialize() return true; } +void CJoystick::LoadAxesConfigs(const std::map<boost::shared_ptr<CRegExp>, AxesConfig> &axesConfigs) +{ + m_AxesConfigs.clear(); + m_AxesConfigs.insert(axesConfigs.begin(), axesConfigs.end()); +} + +void CJoystick::ApplyAxesConfigs() +{ + // load axes configuration from keymap + int axesCount = 0; + for (std::map<int, SDL_Joystick*>::const_iterator it = m_Joysticks.begin(); it != m_Joysticks.end(); it++) + { + std::string joyName(SDL_JoystickName(it->second)); + std::map<boost::shared_ptr<CRegExp>, AxesConfig>::const_iterator axesCfg; + for (axesCfg = m_AxesConfigs.begin(); axesCfg != m_AxesConfigs.end(); axesCfg++) + { + if (axesCfg->first->RegFind(joyName) >= 0) + break; + } + if (axesCfg != m_AxesConfigs.end()) + { + for (AxesConfig::const_iterator it = axesCfg->second.begin(); it != axesCfg->second.end(); ++it) + { + int axis = axesCount + it->axis - 1; + m_Axes[axis].trigger = it->isTrigger; + m_Axes[axis].rest = it->rest; + } + } + axesCount += SDL_JoystickNumAxes(it->second); + } +} + +int CJoystick::JoystickIndex(const std::string &joyName) const +{ + int i = 0; + for (std::map<int, SDL_Joystick*>::const_iterator it = m_Joysticks.begin(); it != m_Joysticks.end(); ++it) + { + if (joyName == std::string(SDL_JoystickName(it->second))) + return i; + i++; + } + return -1; +} + +int CJoystick::JoystickIndex(SDL_Joystick *joy) const +{ + int i = 0; + for (std::map<int, SDL_Joystick*>::const_iterator it = m_Joysticks.begin(); it != m_Joysticks.end(); ++it) + { + if (it->second == joy) + return i; + i++; + } + return -1; +} + +int CJoystick::MapAxis(SDL_Joystick *joy, int axisNum) const +{ + int idx = 0; + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end() && it->second != joy; ++it) + idx += SDL_JoystickNumAxes(it->second); + if (it == m_Joysticks.end()) + return -1; + else + return idx + axisNum; +} + +void CJoystick::MapAxis(int axisIdx, SDL_Joystick *&joy, int &axisNum) const +{ + int axisCount = 0; + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end() && axisCount + SDL_JoystickNumAxes(it->second) <= axisIdx; ++it) + axisCount += SDL_JoystickNumAxes(it->second); + if (it != m_Joysticks.end()) + { + joy = it->second; + axisNum = axisIdx - axisCount; + } + else + { + joy = NULL; + axisNum = -1; + } +} + +int CJoystick::MapButton(SDL_Joystick *joy, int buttonNum) const +{ + int idx = 0; + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end() && it->second != joy; ++it) + idx += SDL_JoystickNumButtons(it->second); + if (it == m_Joysticks.end()) + return -1; + else + return idx + buttonNum; +} + +void CJoystick::MapButton(int buttonIdx, SDL_Joystick *&joy, int &buttonNum) const +{ + int buttonCount = 0; + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end() && buttonCount + SDL_JoystickNumButtons(it->second) <= buttonIdx; ++it) + buttonCount += SDL_JoystickNumButtons(it->second); + if (it != m_Joysticks.end()) + { + joy = it->second; + buttonNum = buttonIdx - buttonCount; + } + else + { + joy = NULL; + buttonNum = -1; + } +} + +int CJoystick::MapHat(SDL_Joystick *joy, int hatNum) const +{ + int idx = 0; + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end() && it->second != joy; ++it) + idx += SDL_JoystickNumHats(it->second); + if (it == m_Joysticks.end()) + return -1; + else + return idx + hatNum; +} + +void CJoystick::MapHat(int hatIdx, SDL_Joystick *&joy, int& hatNum) const +{ + int hatCount = 0; + std::map<int, SDL_Joystick*>::const_iterator it; + for (it = m_Joysticks.begin(); it != m_Joysticks.end() && hatCount + SDL_JoystickNumHats(it->second) <= hatIdx; ++it) + hatCount += SDL_JoystickNumHats(it->second); + if (it != m_Joysticks.end()) + { + joy = it->second; + hatNum = hatIdx - hatCount; + } + else + { + joy = NULL; + hatNum = -1; + } +} + #endif diff --git a/xbmc/input/SDLJoystick.h b/xbmc/input/SDLJoystick.h index b5fa48a520..0be0641e6d 100644 --- a/xbmc/input/SDLJoystick.h +++ b/xbmc/input/SDLJoystick.h @@ -25,6 +25,7 @@ #include "settings/lib/ISettingCallback.h" #include <vector> #include <string> +#include <map> #define JACTIVE_BUTTON 0x00000001 #define JACTIVE_AXIS 0x00000002 @@ -35,17 +36,37 @@ #define JACTIVE_HAT_DOWN 0x04 #define JACTIVE_HAT_LEFT 0x08 +#if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER) +struct AxisConfig { + int axis; + bool isTrigger; + int rest; + AxisConfig(int axis, bool isTrigger, int rest) : axis(axis), isTrigger(isTrigger), rest(rest) { } +}; +typedef std::vector<AxisConfig> AxesConfig; // [<axis, isTrigger, rest state value>] +#endif + #ifdef HAS_SDL_JOYSTICK -#include <SDL/SDL_joystick.h> -#include <SDL/SDL_events.h> +#include <SDL2/SDL_joystick.h> +#include <SDL2/SDL_events.h> -#define MAX_AXES 64 #define MAX_AXISAMOUNT 32768 +struct AxisState { + int val; + int rest; + bool trigger; + AxisState() : val(0), rest(0), trigger(false) { } + void reset() { val = rest; } +}; -// Class to manage all connected joysticks +class CRegExp; +namespace boost { template <typename T> class shared_ptr; } +// Class to manage all connected joysticks +// Note: 'index' always refers to indices specific to this class, +// whereas 'ids' always refer to SDL instance id's class CJoystick : public ISettingCallback { public: @@ -54,46 +75,52 @@ public: virtual void OnSettingChanged(const CSetting *setting); void Initialize(); - void Reset(bool axis=false); - void ResetAxis(int axisId) { m_Amount[axisId] = 0; } + void Reset(); void Update(); - void Update(SDL_Event& event); - bool GetButton (int& id, bool consider_repeat=true); - bool GetAxis (int &id); - bool GetHat (int &id, int &position, bool consider_repeat=true); - std::string GetJoystick() { return (m_JoyId>-1)?m_JoystickNames[m_JoyId]:""; } - int GetAxisWithMaxAmount(); - float GetAmount(int axis); - float GetAmount() { return GetAmount(m_AxisId); } + void Update(SDL_Event& joyEvent); + bool GetAxis(std::string &joyName, int &id) const; + bool GetButton(std::string &joyName, int &id, bool consider_repeat = true); + bool GetHat(std::string &joyName, int &id, int &position, bool consider_repeat = true); + float GetAmount(std::string &joyName, int axisNum) const; bool IsEnabled() const { return m_joystickEnabled; } void SetEnabled(bool enabled = true); float SetDeadzone(float val); bool Reinitialize(); + typedef std::vector<AxisConfig> AxesConfig; // [<axis, isTrigger, rest state value>] + void LoadAxesConfigs(const std::map<boost::shared_ptr<CRegExp>, AxesConfig>& axesConfigs); + void ApplyAxesConfigs(); private: - void SetAxisActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_AXIS):(m_ActiveFlags&(~JACTIVE_AXIS)); } - void SetButtonActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_BUTTON):(m_ActiveFlags&(~JACTIVE_BUTTON)); } - void SetHatActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_HAT):(m_ActiveFlags&(~JACTIVE_HAT)); } - bool IsButtonActive() { return (m_ActiveFlags & JACTIVE_BUTTON) == JACTIVE_BUTTON; } - bool IsAxisActive() { return (m_ActiveFlags & JACTIVE_AXIS) == JACTIVE_AXIS; } - bool IsHatActive() { return (m_ActiveFlags & JACTIVE_HAT) == JACTIVE_HAT; } + bool IsButtonActive() const { return m_ButtonIdx != -1; } + bool IsAxisActive() const { return m_AxisIdx != -1; } + bool IsHatActive() const { return m_HatIdx != -1; } + void AddJoystick(int joyIndex); + void RemoveJoystick(int id); bool ReleaseJoysticks(); - int m_Amount[MAX_AXES]; - int m_AxisId; - int m_ButtonId; - uint8_t m_HatState; - int m_HatId; - int m_JoyId; - int m_NumAxes; + int GetAxisWithMaxAmount() const; + int JoystickIndex(const std::string &joyName) const; + int JoystickIndex(SDL_Joystick *joy) const; + int MapAxis(SDL_Joystick *joy, int axisNum) const ; // <joy, axis> --> axisIdx + void MapAxis(int axisIdx, SDL_Joystick *&joy, int &axisNum) const; // axisIdx --> <joy, axis> + int MapButton(SDL_Joystick *joy, int buttonNum) const; // <joy, button> --> buttonIdx + void MapButton(int buttonIdx, SDL_Joystick *&joy, int &buttonNum) const; // buttonIdx --> <joy, button> + int MapHat(SDL_Joystick *joy, int hatNum) const; // <joy, hat> --> hatIdx + void MapHat(int hatIdx, SDL_Joystick *&joy, int &hatNum) const; // hatIdx --> <joy, hat> + + std::vector<AxisState> m_Axes; + int m_AxisIdx; // active axis + int m_ButtonIdx; // active button + uint8_t m_HatState; // state of active hat + int m_HatIdx; // active hat + int m_DeadzoneRange; bool m_joystickEnabled; uint32_t m_pressTicksButton; uint32_t m_pressTicksHat; - uint8_t m_ActiveFlags; - std::vector<SDL_Joystick*> m_Joysticks; - std::vector<std::string> m_JoystickNames; + std::map<int, SDL_Joystick*> m_Joysticks; + std::map<boost::shared_ptr<CRegExp>, AxesConfig> m_AxesConfigs; // <joy, <axis num, isTrigger, restState> > }; extern CJoystick g_Joystick; diff --git a/xbmc/input/windows/WINJoystick.cpp b/xbmc/input/windows/WINJoystick.cpp index 1677dd7d22..b2da2ac3d1 100644 --- a/xbmc/input/windows/WINJoystick.cpp +++ b/xbmc/input/windows/WINJoystick.cpp @@ -24,8 +24,10 @@ #include "settings/AdvancedSettings.h" #include "settings/lib/Setting.h" #include "utils/log.h" +#include "utils/RegExp.h" #include <math.h> +#include <boost/shared_ptr.hpp> #include <dinput.h> #include <dinputd.h> @@ -53,20 +55,9 @@ extern HWND g_hWnd; CJoystick::CJoystick() { CSingleLock lock(m_critSection); - Reset(true); m_joystickEnabled = false; - m_NumAxes = 0; - m_AxisId = 0; - m_JoyId = 0; - m_ButtonId = 0; - m_HatId = 0; - m_HatState = SDL_HAT_CENTERED; - m_ActiveFlags = JACTIVE_NONE; SetDeadzone(0); - - m_pDI = NULL; - m_lastPressTicks = 0; - m_lastTicks = 0; + Reset(); } CJoystick::~CJoystick() @@ -84,6 +75,16 @@ void CJoystick::OnSettingChanged(const CSetting *setting) SetEnabled(((CSettingBool*)setting)->GetValue() && PERIPHERALS::CPeripheralImon::GetCountOfImonsConflictWithDInput() == 0); } +void CJoystick::Reset() +{ + m_AxisIdx = -1; + m_ButtonIdx = -1; + m_HatIdx = -1; + m_HatState = SDL_HAT_CENTERED; + for (std::vector<AxisState>::iterator it = m_Axes.begin(); it != m_Axes.end(); ++it) + it->reset(); +} + void CJoystick::ReleaseJoysticks() { CSingleLock lock(m_critSection); @@ -97,14 +98,9 @@ void CJoystick::ReleaseJoysticks() } m_pJoysticks.clear(); m_JoystickNames.clear(); + m_Axes.clear(); m_devCaps.clear(); - m_HatId = 0; - m_ButtonId = 0; - m_HatState = SDL_HAT_CENTERED; - m_ActiveFlags = JACTIVE_NONE; - Reset(true); - m_lastPressTicks = 0; - m_lastTicks = 0; + Reset(); // Release any DirectInput objects. SAFE_RELEASE( m_pDI ); } @@ -137,8 +133,27 @@ BOOL CALLBACK CJoystick::EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInst CLog::Log(LOGNOTICE, __FUNCTION__" : Enabled Joystick: %s", pdidInstance->tszProductName); CLog::Log(LOGNOTICE, __FUNCTION__" : Total Axis: %d Total Hats: %d Total Buttons: %d", diDevCaps.dwAxes, diDevCaps.dwPOVs, diDevCaps.dwButtons); p_this->m_pJoysticks.push_back(pJoystick); - p_this->m_JoystickNames.push_back(pdidInstance->tszProductName); + std::string joyName(pdidInstance->tszProductName); + p_this->m_JoystickNames.push_back(joyName);; + p_this->m_Axes.resize(p_this->m_Axes.size() + 6); // dinput hardcodes to 6 axes p_this->m_devCaps.push_back(diDevCaps); + + // load axes configuration from keymap + std::map<boost::shared_ptr<CRegExp>, AxesConfig>::const_iterator axesCfg; + for (axesCfg = p_this->m_AxesConfigs.begin(); axesCfg != p_this->m_AxesConfigs.end(); axesCfg++) + { + if (axesCfg->first->RegFind(joyName) >= 0) + break; + } + if (axesCfg != p_this->m_AxesConfigs.end()) + { + for (AxesConfig::const_iterator it = axesCfg->second.begin(); it != axesCfg->second.end(); ++it) + { + int axis = p_this->MapAxis(pJoystick, it->axis - 1); + p_this->m_Axes[axis].trigger = it->isTrigger; + p_this->m_Axes[axis].rest = it->rest; + } + } } else CLog::Log(LOGDEBUG, __FUNCTION__" : Failed to GetCapabilities for: %s", pdidInstance->tszProductName); @@ -223,47 +238,26 @@ void CJoystick::Initialize() CLog::Log(LOGDEBUG, __FUNCTION__" : Failed to enumerate objects"); } - m_JoyId = -1; - // Set deadzone range SetDeadzone(g_advancedSettings.m_controllerDeadzone); } -void CJoystick::Reset(bool axis /*=true*/) -{ - if (axis) - { - SetAxisActive(false); - for (int i = 0 ; i<MAX_AXES ; i++) - { - ResetAxis(i); - } - } -} - void CJoystick::Update() { if (!IsEnabled()) return; - int buttonId = -1; - int axisId = -1; - int hatId = -1; - int numhat = -1; - int numj = m_pJoysticks.size(); - if (numj <= 0) - return; + int axisNum; + int buttonIdx = -1, buttonNum; + int hatIdx = -1, hatNum; // go through all joysticks - for (int j = 0; j<numj; j++) + for (size_t j = 0; j < m_pJoysticks.size(); j++) { LPDIRECTINPUTDEVICE8 pjoy = m_pJoysticks[j]; + DIDEVCAPS caps = m_devCaps[j]; HRESULT hr; DIJOYSTATE2 js; // DInput joystick state - - m_NumAxes = (m_devCaps[j].dwAxes > MAX_AXES) ? MAX_AXES : m_devCaps[j].dwAxes; - numhat = (m_devCaps[j].dwPOVs > 4) ? 4 : m_devCaps[j].dwPOVs; - hr = pjoy->Poll(); if( FAILED( hr ) ) { @@ -279,217 +273,208 @@ void CJoystick::Update() // hr may be DIERR_OTHERAPPHASPRIO or other errors. This // may occur when the app is minimized or in the process of // switching, so just try again later + Reset(); return; } // Get the input's device state if( FAILED( hr = pjoy->GetDeviceState( sizeof( DIJOYSTATE2 ), &js ) ) ) + { + Reset(); return; // The device should have been acquired during the Poll() + } // get button states first, they take priority over axis - for( int b = 0; b < 128; b++ ) + for (int b = 0; b < caps.dwButtons; b++) { - if( js.rgbButtons[b] & 0x80 ) + if (js.rgbButtons[b] & 0x80) { - m_JoyId = j; - buttonId = b+1; - j = numj-1; + buttonIdx = MapButton(pjoy, b); + j = m_pJoysticks.size(); break; } } // get hat position - m_HatState = SDL_HAT_CENTERED; - for (int h = 0; h < numhat; h++) + for (int h = 0; h < caps.dwPOVs; h++) { - if((LOWORD(js.rgdwPOV[h]) == 0xFFFF) != true) + if ((LOWORD(js.rgdwPOV[h]) == 0xFFFF) != true) { - m_JoyId = j; - hatId = h + 1; - j = numj-1; - if ( (js.rgdwPOV[0] > JOY_POVLEFT) || (js.rgdwPOV[0] < JOY_POVRIGHT) ) - m_HatState |= SDL_HAT_UP; + uint8_t hatval = SDL_HAT_CENTERED; - if ( (js.rgdwPOV[0] > JOY_POVFORWARD) && (js.rgdwPOV[0] < JOY_POVBACKWARD) ) - m_HatState |= SDL_HAT_RIGHT; + if ((js.rgdwPOV[0] > JOY_POVLEFT) || (js.rgdwPOV[0] < JOY_POVRIGHT)) + hatval |= SDL_HAT_UP; - if ( (js.rgdwPOV[0] > JOY_POVRIGHT) && (js.rgdwPOV[0] < JOY_POVLEFT) ) - m_HatState |= SDL_HAT_DOWN; + if ((js.rgdwPOV[0] > JOY_POVFORWARD) && (js.rgdwPOV[0] < JOY_POVBACKWARD)) + hatval |= SDL_HAT_RIGHT; - if ( js.rgdwPOV[0] > JOY_POVBACKWARD ) - m_HatState |= SDL_HAT_LEFT; - break; + if ((js.rgdwPOV[0] > JOY_POVRIGHT) && (js.rgdwPOV[0] < JOY_POVLEFT)) + hatval |= SDL_HAT_DOWN; + + if (js.rgdwPOV[0] > JOY_POVBACKWARD) + hatval |= SDL_HAT_LEFT; + + if (hatval != SDL_HAT_CENTERED) + { + hatIdx = MapHat(pjoy, h); + j = m_pJoysticks.size(); + m_HatState = hatval; + } } } // get axis states - m_Amount[0] = 0; - m_Amount[1] = js.lX; - m_Amount[2] = js.lY; - m_Amount[3] = js.lZ; - m_Amount[4] = js.lRx; - m_Amount[5] = js.lRy; - m_Amount[6] = js.lRz; - - m_AxisId = GetAxisWithMaxAmount(); - if (m_AxisId) - { - m_JoyId = j; - j = numj-1; - break; - } + int axisIdx = MapAxis(pjoy, 0); + m_Axes[axisIdx + 0].val = js.lX; + m_Axes[axisIdx + 1].val = js.lY; + m_Axes[axisIdx + 2].val = js.lZ; + m_Axes[axisIdx + 3].val = js.lRx; + m_Axes[axisIdx + 4].val = js.lRy; + m_Axes[axisIdx + 5].val = js.lRz; + } + + LPDIRECTINPUTDEVICE8 pjoy; + m_AxisIdx = GetAxisWithMaxAmount(); + if (m_AxisIdx >= 0) + { + MapAxis(m_AxisIdx, pjoy, axisNum); + // CLog::Log(LOGDEBUG, "Joystick %d Axis %d Amount %d", JoystickIndex(pjoy), axisNum + 1, m_Axes[m_AxisIdx].val); } - if(hatId==-1) + if (hatIdx == -1 && m_HatIdx != -1) { - if(m_HatId!=0) - CLog::Log(LOGDEBUG, "Joystick %d hat %d Centered", m_JoyId, abs(hatId)); + // now centered + MapHat(m_HatIdx, pjoy, hatNum); + CLog::Log(LOGDEBUG, "Joystick %d hat %u hat centered", JoystickIndex(pjoy), hatNum + 1); m_pressTicksHat = 0; - SetHatActive(false); - m_HatId = 0; } - else + else if (hatIdx != m_HatIdx) { - if(hatId!=m_HatId) - { - CLog::Log(LOGDEBUG, "Joystick %d hat %u Down", m_JoyId, hatId); - m_HatId = hatId; - m_pressTicksHat = XbmcThreads::SystemClockMillis(); - } - SetHatActive(); + MapHat(hatIdx, pjoy, hatNum); + CLog::Log(LOGDEBUG, "Joystick %d hat %u value %d", JoystickIndex(pjoy), hatNum + 1, m_HatState); + m_pressTicksHat = XbmcThreads::SystemClockMillis(); } + m_HatIdx = hatIdx; - if (buttonId==-1) + if (buttonIdx == -1 && m_ButtonIdx != -1) { - if (m_ButtonId!=0) - { - CLog::Log(LOGDEBUG, "Joystick %d button %d Up", m_JoyId, m_ButtonId); - } + MapButton(m_ButtonIdx, pjoy, buttonNum); + CLog::Log(LOGDEBUG, "Joystick %d button %d Up", JoystickIndex(pjoy), buttonNum + 1); m_pressTicksButton = 0; - SetButtonActive(false); - m_ButtonId = 0; + m_ButtonIdx = -1; } - else + else if (buttonIdx != m_ButtonIdx) { - if (buttonId!=m_ButtonId) - { - CLog::Log(LOGDEBUG, "Joystick %d button %d Down", m_JoyId, buttonId); - m_ButtonId = buttonId; - m_pressTicksButton = XbmcThreads::SystemClockMillis(); - } - SetButtonActive(); + MapButton(buttonIdx, pjoy, buttonNum); + CLog::Log(LOGDEBUG, "Joystick %d button %d Down", JoystickIndex(pjoy), buttonNum + 1); + m_pressTicksButton = XbmcThreads::SystemClockMillis(); } + m_ButtonIdx = buttonIdx; } -bool CJoystick::GetHat(int &id, int &position,bool consider_repeat) +bool CJoystick::GetHat(std::string &joyName, int &id, int &position, bool consider_repeat) { if (!IsEnabled() || !IsHatActive()) - { - id = position = 0; return false; - } + LPDIRECTINPUTDEVICE8 joy; + MapHat(m_HatIdx, joy, id); + joyName = m_JoystickNames[JoystickIndex(joy)]; position = m_HatState; - id = m_HatId; + if (!consider_repeat) return true; - uint32_t nowTicks = 0; - - if ((m_HatId>=0) && m_pressTicksHat) + static uint32_t lastPressTicksHat = 0; + // allow it if it is the first press + if (lastPressTicksHat < m_pressTicksHat) { - // return the id if it's the first press - if (m_lastPressTicks!=m_pressTicksHat) - { - m_lastPressTicks = m_pressTicksHat; - return true; - } - nowTicks = XbmcThreads::SystemClockMillis(); - if ((nowTicks-m_pressTicksHat)<500) // 500ms delay before we repeat - return false; - if ((nowTicks-m_lastTicks)<100) // 100ms delay before successive repeats - return false; - - m_lastTicks = nowTicks; + lastPressTicksHat = m_pressTicksHat; + return true; } + uint32_t nowTicks = XbmcThreads::SystemClockMillis(); + if (nowTicks - m_pressTicksHat < 500) // 500ms delay before we repeat + return false; + if (nowTicks - lastPressTicksHat < 100) // 100ms delay before successive repeats + return false; + lastPressTicksHat = nowTicks; return true; } -bool CJoystick::GetButton(int &id, bool consider_repeat) +bool CJoystick::GetButton(std::string &joyName, int &id, bool consider_repeat) { if (!IsEnabled() || !IsButtonActive()) - { - id = 0; return false; - } + + LPDIRECTINPUTDEVICE8 joy; + MapButton(m_ButtonIdx, joy, id); + joyName = m_JoystickNames[JoystickIndex(joy)]; + if (!consider_repeat) - { - id = m_ButtonId; return true; - } - uint32_t nowTicks = 0; - - if ((m_ButtonId>=0) && m_pressTicksButton) + static uint32_t lastPressTicksButton = 0; + // allow it if it is the first press + if (lastPressTicksButton < m_pressTicksButton) { - // return the id if it's the first press - if (m_lastPressTicks!=m_pressTicksButton) - { - m_lastPressTicks = m_pressTicksButton; - id = m_ButtonId; - return true; - } - nowTicks = XbmcThreads::SystemClockMillis(); - if ((nowTicks-m_pressTicksButton)<500) // 500ms delay before we repeat - { - return false; - } - if ((nowTicks-m_lastTicks)<100) // 100ms delay before successive repeats - { - return false; - } - m_lastTicks = nowTicks; + lastPressTicksButton = m_pressTicksButton; + return true; } - id = m_ButtonId; + uint32_t nowTicks = XbmcThreads::SystemClockMillis(); + if (nowTicks - m_pressTicksButton < 500) // 500ms delay before we repeat + return false; + if (nowTicks - lastPressTicksButton < 100) // 100ms delay before successive repeats + return false; + + lastPressTicksButton = nowTicks; return true; } -bool CJoystick::GetAxis (int &id) -{ - if (!IsEnabled() || !IsAxisActive()) - { - id = 0; - return false; - } - id = m_AxisId; - return true; +bool CJoystick::GetAxis(std::string &joyName, int &id) +{ + if (!IsEnabled() || !IsAxisActive()) + return false; + + LPDIRECTINPUTDEVICE8 joy; + MapAxis(m_AxisIdx, joy, id); + joyName = m_JoystickNames[JoystickIndex(joy)]; + + return true; } -int CJoystick::GetAxisWithMaxAmount() +int CJoystick::GetAxisWithMaxAmount() const { - int maxAmount = 0; - int axis = 0; - int tempf; - for (int i = 1 ; i<=m_NumAxes ; i++) + int maxAmount = 0, axis = -1; + for (size_t i = 0; i < m_Axes.size(); i++) { - tempf = abs(m_Amount[i]); - if (tempf>m_DeadzoneRange && tempf>maxAmount) + int deadzone = m_Axes[i].trigger ? 0 : m_DeadzoneRange, + amount = abs(m_Axes[i].val - m_Axes[i].rest); + if (amount > deadzone && amount > maxAmount) { - maxAmount = tempf; + maxAmount = amount; axis = i; } } - SetAxisActive(0 != maxAmount); return axis; } -float CJoystick::GetAmount(int axis) +float CJoystick::GetAmount(const std::string &joyName, int axisNum) const { - if (m_Amount[axis] > m_DeadzoneRange) - return (float)(m_Amount[axis]-m_DeadzoneRange)/(float)(MAX_AXISAMOUNT-m_DeadzoneRange); - if (m_Amount[axis] < -m_DeadzoneRange) - return (float)(m_Amount[axis]+m_DeadzoneRange)/(float)(MAX_AXISAMOUNT-m_DeadzoneRange); + int joyIdx = JoystickIndex(joyName); + if (joyIdx == -1) + return 0; + + int axisIdx = MapAxis(m_pJoysticks[joyIdx], axisNum); + int amount = m_Axes[axisIdx].val - m_Axes[axisIdx].rest; + int range = MAX_AXISAMOUNT - m_Axes[axisIdx].rest; + // deadzones on axes are undesirable + int deadzone = m_Axes[axisIdx].trigger ? 0 : m_DeadzoneRange; + if (amount > deadzone) + return (float)(amount - deadzone) / (float)(range - deadzone); + else if (amount < -deadzone) + return (float)(amount + deadzone) / (float)(range - deadzone); + return 0; } @@ -535,3 +520,119 @@ void CJoystick::Acquire() } } } + +void CJoystick::LoadAxesConfigs(const std::map<boost::shared_ptr<CRegExp>, AxesConfig> &axesConfigs) +{ + m_AxesConfigs.clear(); + m_AxesConfigs.insert(axesConfigs.begin(), axesConfigs.end()); +} + +int CJoystick::JoystickIndex(const std::string &joyName) const +{ + for (size_t i = 0; i < m_JoystickNames.size(); ++i) + { + if (joyName == m_JoystickNames[i]) + return i; + } + return -1; +} + +int CJoystick::JoystickIndex(LPDIRECTINPUTDEVICE8 joy) const +{ + for (size_t i = 0; i < m_pJoysticks.size(); ++i) + { + if (joy == m_pJoysticks[i]) + return i; + } + return -1; +} + +int CJoystick::MapAxis(LPDIRECTINPUTDEVICE8 joy, int axisNum) const +{ + int idx = 0; + size_t i; + for (i = 0; i != m_pJoysticks.size() && m_pJoysticks[i] != joy; ++i) + idx += m_devCaps[i].dwAxes; + if (i == m_pJoysticks.size()) + return -1; + else + return idx + axisNum; +} + +void CJoystick::MapAxis(int axisIdx, LPDIRECTINPUTDEVICE8 &joy, int &axisNum) const +{ + int axisCount = 0; + size_t i; + for (i = 0; i != m_pJoysticks.size() && m_pJoysticks[i] != joy && axisCount + m_devCaps[i].dwAxes <= axisIdx; ++i) + axisCount += m_devCaps[i].dwAxes; + if (i != m_pJoysticks.size()) + { + joy = m_pJoysticks[i]; + axisNum = axisIdx - axisCount; + } + else + { + joy = NULL; + axisNum = -1; + } +} + +int CJoystick::MapButton(LPDIRECTINPUTDEVICE8 joy, int buttonNum) const +{ + int idx = 0; + size_t i; + for (i = 0; i != m_pJoysticks.size() && m_pJoysticks[i] != joy; ++i) + idx += m_devCaps[i].dwButtons; + if (i == m_pJoysticks.size()) + return -1; + else + return idx + buttonNum; +} + +void CJoystick::MapButton(int buttonIdx, LPDIRECTINPUTDEVICE8 &joy, int &buttonNum) const +{ + int buttonCount = 0; + size_t i; + for (i = 0; i != m_pJoysticks.size() && m_pJoysticks[i] != joy && buttonCount + m_devCaps[i].dwButtons <= buttonIdx; ++i) + buttonCount += m_devCaps[i].dwButtons; + if (i != m_pJoysticks.size()) + { + joy = m_pJoysticks[i]; + buttonNum = buttonIdx - buttonCount; + } + else + { + joy = NULL; + buttonNum = -1; + } +} + +int CJoystick::MapHat(LPDIRECTINPUTDEVICE8 joy, int hatNum) const +{ + int idx = 0; + size_t i; + for (i = 0; i != m_pJoysticks.size() && m_pJoysticks[i] != joy; ++i) + idx += m_devCaps[i].dwPOVs; + if (i == m_pJoysticks.size()) + return -1; + else + return idx + hatNum; +} + +void CJoystick::MapHat(int hatIdx, LPDIRECTINPUTDEVICE8 &joy, int &hatNum) const +{ + int hatCount = 0; + size_t i; + for (i = 0; i != m_pJoysticks.size() && m_pJoysticks[i] != joy && hatCount + m_devCaps[i].dwPOVs <= hatIdx; ++i) + hatCount += m_devCaps[i].dwPOVs; + if (i != m_pJoysticks.size()) + { + joy = m_pJoysticks[i]; + hatNum = hatIdx - hatCount; + } + else + { + joy = NULL; + hatNum = -1; + } +} diff --git a/xbmc/input/windows/WINJoystick.h b/xbmc/input/windows/WINJoystick.h index b0232505fb..a6475a884d 100644 --- a/xbmc/input/windows/WINJoystick.h +++ b/xbmc/input/windows/WINJoystick.h @@ -21,6 +21,7 @@ #include <vector> #include <string> +#include <map> #include <stdint.h> #include "settings/lib/ISettingCallback.h" #include "threads/CriticalSection.h" @@ -34,10 +35,26 @@ #define JACTIVE_HAT_DOWN 0x04 #define JACTIVE_HAT_LEFT 0x08 -#define MAX_AXES 8 +struct AxisState { + int val; + int rest; + bool trigger; + AxisState() : val(0), rest(0), trigger(false) { } + void reset() { val = rest; } +}; -// Class to manage all connected joysticks +struct AxisConfig { + int axis; + bool isTrigger; + int rest; + AxisConfig(int axis, bool isTrigger, int rest) : axis(axis), isTrigger(isTrigger), rest(rest) { } +}; +typedef std::vector<AxisConfig> AxesConfig; // [<axis, isTrigger, rest state value>] +class CRegExp; +namespace boost { template <typename T> class shared_ptr; } + +// Class to manage all connected joysticks class CJoystick : public ISettingCallback { public: @@ -45,56 +62,60 @@ public: ~CJoystick(); virtual void OnSettingChanged(const CSetting *setting); - void Initialize(); - void Reset(bool axis=false); - void ResetAxis(int axisId) { m_Amount[axisId] = 0; } + void Reset(); void Update(); - bool GetButton (int& id, bool consider_repeat=true); - bool GetAxis (int &id); - bool GetHat (int &id, int &position, bool consider_repeat=true); - std::string GetJoystick() { return (m_JoyId>-1)?m_JoystickNames[m_JoyId]:""; } - int GetAxisWithMaxAmount(); - float GetAmount(int axis); - float GetAmount() { return GetAmount(m_AxisId); } + + bool GetButton(std::string &joyName, int &id, bool consider_repeat = true); + bool GetAxis(std::string &joyName, int &id); + bool GetHat(std::string &joyName, int &id, int &position, bool consider_repeat = true); + float GetAmount(const std::string &joyName, int axisNum) const; + bool IsEnabled() const { return m_joystickEnabled; } void SetEnabled(bool enabled = true); float SetDeadzone(float val); bool Reinitialize(); void Acquire(); + typedef std::vector<AxisConfig> AxesConfig; // [<axis, isTrigger, rest state value>] + void LoadAxesConfigs(const std::map<boost::shared_ptr<CRegExp>, AxesConfig> &axesConfigs); private: - void SetAxisActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_AXIS):(m_ActiveFlags&(~JACTIVE_AXIS)); } - void SetButtonActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_BUTTON):(m_ActiveFlags&(~JACTIVE_BUTTON)); } - void SetHatActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_HAT):(m_ActiveFlags&(~JACTIVE_HAT)); } - bool IsButtonActive() { return (m_ActiveFlags & JACTIVE_BUTTON) == JACTIVE_BUTTON; } - bool IsAxisActive() { return (m_ActiveFlags & JACTIVE_AXIS) == JACTIVE_AXIS; } - bool IsHatActive() { return (m_ActiveFlags & JACTIVE_HAT) == JACTIVE_HAT; } + bool IsButtonActive() const { return m_ButtonIdx != -1; } + bool IsAxisActive() const { return m_AxisIdx != -1; } + bool IsHatActive() const { return m_HatIdx != -1; } void ReleaseJoysticks(); + + int GetAxisWithMaxAmount() const; + int JoystickIndex(const std::string &joyName) const; + int JoystickIndex(LPDIRECTINPUTDEVICE8 joy) const; + int MapAxis(LPDIRECTINPUTDEVICE8 joy, int axisNum) const; // <joy, axis> --> axisIdx + void MapAxis(int axisIdx, LPDIRECTINPUTDEVICE8 &joy, int &axisNum) const; // axisIdx --> <joy, axis> + int MapButton(LPDIRECTINPUTDEVICE8 joy, int buttonNum) const; // <joy, button> --> buttonIdx + void MapButton(int buttonIdx, LPDIRECTINPUTDEVICE8 &joy, int &buttonNum) const; // buttonIdx --> <joy, button> + int MapHat(LPDIRECTINPUTDEVICE8 joy, int hatNum) const; // <joy, hat> --> hatIdx + void MapHat(int hatIdx, LPDIRECTINPUTDEVICE8 &joy, int &hatNum) const; // hatIdx --> <joy, hat> + static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ); static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext ); - int m_Amount[MAX_AXES]; - int m_AxisId; - int m_ButtonId; - uint8_t m_HatState; - int m_HatId; - int m_JoyId; - int m_NumAxes; + std::vector<AxisState> m_Axes; + int m_AxisIdx; // active axis + int m_ButtonIdx; // active button + uint8_t m_HatState; // state of active hat + int m_HatIdx; // active hat + int m_DeadzoneRange; bool m_joystickEnabled; uint32_t m_pressTicksButton; uint32_t m_pressTicksHat; - uint8_t m_ActiveFlags; - uint32_t m_lastPressTicks; - uint32_t m_lastTicks; CCriticalSection m_critSection; LPDIRECTINPUT8 m_pDI; std::vector<LPDIRECTINPUTDEVICE8> m_pJoysticks; std::vector<std::string> m_JoystickNames; std::vector<DIDEVCAPS> m_devCaps; + std::map<boost::shared_ptr<CRegExp>, AxesConfig> m_AxesConfigs; // <joy, <axis num, isTrigger, restState> > }; extern CJoystick g_Joystick; diff --git a/xbmc/interfaces/Builtins.cpp b/xbmc/interfaces/Builtins.cpp index 610c3db825..f80698c5e5 100644 --- a/xbmc/interfaces/Builtins.cpp +++ b/xbmc/interfaces/Builtins.cpp @@ -118,14 +118,14 @@ const BUILT_IN commands[] = { { "Restart", false, "Restart the system (same as reboot)" }, { "ShutDown", false, "Shutdown the system" }, { "Powerdown", false, "Powerdown system" }, - { "Quit", false, "Quit XBMC" }, + { "Quit", false, "Quit Kodi" }, { "Hibernate", false, "Hibernates the system" }, { "Suspend", false, "Suspends the system" }, { "InhibitIdleShutdown", false, "Inhibit idle shutdown" }, { "AllowIdleShutdown", false, "Allow idle shutdown" }, { "ActivateScreensaver", false, "Activate Screensaver" }, - { "RestartApp", false, "Restart XBMC" }, - { "Minimize", false, "Minimize XBMC" }, + { "RestartApp", false, "Restart Kodi" }, + { "Minimize", false, "Minimize Kodi" }, { "Reset", false, "Reset the system (same as reboot)" }, { "Mastermode", false, "Control master mode" }, { "SetGUILanguage", true, "Set GUI Language" }, @@ -147,8 +147,8 @@ const BUILT_IN commands[] = { { "ShowPicture", true, "Display a picture by file path" }, { "SlideShow", true, "Run a slideshow from the specified directory" }, { "RecursiveSlideShow", true, "Run a slideshow from the specified directory, including all subdirs" }, - { "ReloadSkin", false, "Reload XBMC's skin" }, - { "UnloadSkin", false, "Unload XBMC's skin" }, + { "ReloadSkin", false, "Reload Kodi's skin" }, + { "UnloadSkin", false, "Unload Kodi's skin" }, { "RefreshRSS", false, "Reload RSS feeds from RSSFeeds.xml"}, { "PlayerControl", true, "Control the music or video player" }, { "Playlist.PlayOffset", true, "Start playing from a particular offset in the playlist" }, @@ -177,8 +177,8 @@ const BUILT_IN commands[] = { { "Dialog.Close", true, "Close a dialog" }, { "System.LogOff", false, "Log off current user" }, { "System.Exec", true, "Execute shell commands" }, - { "System.ExecWait", true, "Execute shell commands and freezes XBMC until shell is closed" }, - { "Resolution", true, "Change XBMC's Resolution" }, + { "System.ExecWait", true, "Execute shell commands and freezes Kodi until shell is closed" }, + { "Resolution", true, "Change Kodi's Resolution" }, { "SetFocus", true, "Change current focus to a different control id" }, { "UpdateLibrary", true, "Update the selected library (music or video)" }, { "CleanLibrary", true, "Clean the video/music library" }, @@ -217,8 +217,8 @@ const BUILT_IN commands[] = { { "Weather.LocationPrevious", false, "Switch to previous weather location"}, { "Weather.LocationSet", true, "Switch to given weather location (parameter can be 1-3)"}, #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE) - { "LIRC.Stop", false, "Removes XBMC as LIRC client" }, - { "LIRC.Start", false, "Adds XBMC as LIRC client" }, + { "LIRC.Stop", false, "Removes Kodi as LIRC client" }, + { "LIRC.Start", false, "Adds Kodi as LIRC client" }, { "LIRC.Send", true, "Sends a command to LIRC" }, #endif { "VideoLibrary.Search", false, "Brings up a search dialog which will search the library" }, @@ -258,7 +258,7 @@ void CBuiltins::GetHelp(std::string &help) int CBuiltins::Execute(const std::string& execString) { - // Get the text after the "XBMC." + // Deprecated. Get the text after the "XBMC." std::string execute; vector<string> params; CUtil::SplitExecFunction(execString, execute, params); @@ -392,7 +392,17 @@ int CBuiltins::Execute(const std::string& execString) int iWindow = CButtonTranslator::TranslateWindow(strWindow); if (iWindow != WINDOW_INVALID) { - if (iWindow != g_windowManager.GetActiveWindow()) + // compate the given directory param with the current active directory + bool bIsSameStartFolder = true; + if (!params.empty()) + { + CGUIWindow *activeWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow()); + if (activeWindow && activeWindow->IsMediaWindow()) + bIsSameStartFolder = ((CGUIMediaWindow*) activeWindow)->IsSameStartFolder(params[0]); + } + + // activate window only if window and path differ from the current active window + if (iWindow != g_windowManager.GetActiveWindow() || !bIsSameStartFolder) { // disable the screensaver g_application.WakeUpScreenSaverAndDPMS(); @@ -455,10 +465,21 @@ int CBuiltins::Execute(const std::string& execString) else #endif { - AddonPtr script; - std::string scriptpath(params[0]); - if (CAddonMgr::Get().GetAddon(params[0], script)) - scriptpath = script->LibPath(); + AddonPtr addon; + std::string scriptpath; + if (CAddonMgr::Get().GetAddon(params[0], addon)) + { + //Get the correct extension point to run + if (CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT) || + CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_WEATHER) || + CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_LYRICS) || + CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_LIBRARY)) + scriptpath = addon->LibPath(); + else + CLog::Log(LOGERROR, "RunScript called for invalid add-on id '%s'. Not a script.", params[0].c_str()); + } + else + scriptpath = params[0]; // split the path up to find the filename vector<string> argv = params; @@ -466,7 +487,7 @@ int CBuiltins::Execute(const std::string& execString) if (!filename.empty()) argv[0] = filename; - CScriptInvocationManager::Get().Execute(scriptpath, script, argv); + CScriptInvocationManager::Get().Execute(scriptpath, addon, argv); } } #if defined(TARGET_DARWIN_OSX) @@ -533,7 +554,7 @@ int CBuiltins::Execute(const std::string& execString) g_RarManager.ExtractArchive(params[0],strDestDirect); #endif else - CLog::Log(LOGERROR, "XBMC.Extract, No archive given"); + CLog::Log(LOGERROR, "Extract, No archive given"); } else if (execute == "runplugin") { @@ -548,7 +569,7 @@ int CBuiltins::Execute(const std::string& execString) } else { - CLog::Log(LOGERROR, "XBMC.RunPlugin called with no arguments."); + CLog::Log(LOGERROR, "RunPlugin called with no arguments."); } } else if (execute == "runaddon") @@ -593,7 +614,8 @@ int CBuiltins::Execute(const std::string& execString) } else if (CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT) || CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_WEATHER) || - CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_LYRICS)) + CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_LYRICS) || + CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_LIBRARY)) // Pass the script name (params[0]) and all the parameters // (params[1] ... params[x]) separated by a comma to RunScript cmd = StringUtils::Format("RunScript(%s)", StringUtils::Join(params, ",").c_str()); @@ -602,7 +624,7 @@ int CBuiltins::Execute(const std::string& execString) } else { - CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments."); + CLog::Log(LOGERROR, "RunAddon called with no arguments."); } } else if (execute == "notifyall") @@ -616,13 +638,13 @@ int CBuiltins::Execute(const std::string& execString) ANNOUNCEMENT::CAnnouncementManager::Get().Announce(ANNOUNCEMENT::Other, params[0].c_str(), params[1].c_str(), data); } else - CLog::Log(LOGERROR, "XBMC.NotifyAll needs two parameters"); + CLog::Log(LOGERROR, "NotifyAll needs two parameters"); } else if (execute == "playmedia") { if (!params.size()) { - CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter"); + CLog::Log(LOGERROR, "PlayMedia called with empty parameter"); return -3; } @@ -721,7 +743,7 @@ int CBuiltins::Execute(const std::string& execString) // play media if (!g_application.PlayMedia(item, playlist)) { - CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str()); + CLog::Log(LOGERROR, "PlayMedia could not play media: %s", params[0].c_str()); return false; } } @@ -730,7 +752,7 @@ int CBuiltins::Execute(const std::string& execString) { if (!params.size()) { - CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter"); + CLog::Log(LOGERROR, "ShowPicture called with empty parameter"); return -2; } CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0); @@ -742,7 +764,7 @@ int CBuiltins::Execute(const std::string& execString) { if (!params.size()) { - CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter"); + CLog::Log(LOGERROR, "SlideShow called with empty parameter"); return -2; } std::string beginSlidePath; @@ -798,7 +820,7 @@ int CBuiltins::Execute(const std::string& execString) g_application.WakeUpScreenSaverAndDPMS(); if (!params.size()) { - CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter"); + CLog::Log(LOGERROR, "PlayerControl called with empty parameter"); return -3; } if (paramlow == "play") @@ -1429,7 +1451,7 @@ int CBuiltins::Execute(const std::string& execString) if (!g_application.IsVideoScanning()) g_application.StartVideoCleanup(userInitiated); else - CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning"); + CLog::Log(LOGERROR, "CleanLibrary is not possible while scanning or cleaning"); } else if (StringUtils::EqualsNoCase(params[0], "music")) { @@ -1442,7 +1464,7 @@ int CBuiltins::Execute(const std::string& execString) musicdatabase.Close(); } else - CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info"); + CLog::Log(LOGERROR, "CleanLibrary is not possible while scanning for media info"); } } else if (execute == "exportlibrary" && !params.empty()) diff --git a/xbmc/interfaces/json-rpc/ApplicationOperations.cpp b/xbmc/interfaces/json-rpc/ApplicationOperations.cpp index 514e317ca5..266bc44aab 100644 --- a/xbmc/interfaces/json-rpc/ApplicationOperations.cpp +++ b/xbmc/interfaces/json-rpc/ApplicationOperations.cpp @@ -116,7 +116,7 @@ JSONRPC_STATUS CApplicationOperations::GetPropertyValue(const std::string &prope else if (property == "muted") result = g_application.IsMuted(); else if (property == "name") - result = "XBMC"; + result = CCompileInfo::GetAppName(); else if (property == "version") { result = CVariant(CVariant::VariantTypeObject); diff --git a/xbmc/interfaces/json-rpc/schema/types.json b/xbmc/interfaces/json-rpc/schema/types.json index 8912630503..50d1e4ceff 100644 --- a/xbmc/interfaces/json-rpc/schema/types.json +++ b/xbmc/interfaces/json-rpc/schema/types.json @@ -768,7 +768,7 @@ "PVR.Fields.Channel": { "extends": "Item.Fields.Base", "items": { "type": "string", - "enum": [ "thumbnail", "channeltype", "hidden", "locked", "channel", "lastplayed" ] + "enum": [ "thumbnail", "channeltype", "hidden", "locked", "channel", "lastplayed", "broadcastnow", "broadcastnext" ] } }, "PVR.Details.Channel": { @@ -780,7 +780,9 @@ "hidden": { "type": "boolean" }, "locked": { "type": "boolean" }, "thumbnail": { "type": "string" }, - "lastplayed": { "type": "string" } + "lastplayed": { "type": "string" }, + "broadcastnow": { "$ref": "PVR.Details.Broadcast" }, + "broadcastnext": { "$ref": "PVR.Details.Broadcast" } } }, "PVR.Details.ChannelGroup": { diff --git a/xbmc/interfaces/json-rpc/schema/version.txt b/xbmc/interfaces/json-rpc/schema/version.txt index 74c926af47..a7c176ac7f 100644 --- a/xbmc/interfaces/json-rpc/schema/version.txt +++ b/xbmc/interfaces/json-rpc/schema/version.txt @@ -1 +1 @@ -6.19.0 +6.20.0 diff --git a/xbmc/interfaces/legacy/File.cpp b/xbmc/interfaces/legacy/File.cpp index 19c4477b0e..93f9ff0e05 100644 --- a/xbmc/interfaces/legacy/File.cpp +++ b/xbmc/interfaces/legacy/File.cpp @@ -39,8 +39,8 @@ namespace XBMCAddon while(ret.remaining() > 0) { - int bytesRead = file->Read(ret.curPosition(), ret.remaining()); - if (bytesRead == 0) // we consider this a failure or a EOF, can't tell which, + ssize_t bytesRead = file->Read(ret.curPosition(), ret.remaining()); + if (bytesRead <= 0) // we consider this a failure or a EOF, can't tell which, { // return whatever we have already. ret.flip(); return ret; @@ -56,7 +56,7 @@ namespace XBMCAddon DelayedCallGuard dg(languageHook); while (buffer.remaining() > 0) { - int bytesWritten = file->Write( buffer.curPosition(), buffer.remaining()); + ssize_t bytesWritten = file->Write( buffer.curPosition(), buffer.remaining()); if (bytesWritten == 0) // this could be a failure (see HDFile, and XFileUtils) or // it could mean something else when a negative number means an error // (see CCurlFile). There is no consistency so we can only assume we're diff --git a/xbmc/interfaces/legacy/ListItem.h b/xbmc/interfaces/legacy/ListItem.h index 535e4b07c9..588b855b0c 100644 --- a/xbmc/interfaces/legacy/ListItem.h +++ b/xbmc/interfaces/legacy/ListItem.h @@ -288,7 +288,7 @@ namespace XBMCAddon * Once you use a keyword, all following arguments require the keyword.\n * \n * example: - * - listitem.addContextMenuItems([('Theater Showtimes', 'XBMC.RunScript(special://home/scripts/showtimes/default.py,Iron Man)',)])n + * - listitem.addContextMenuItems([('Theater Showtimes', 'RunScript(special://home/scripts/showtimes/default.py,Iron Man)',)])n */ void addContextMenuItems(const std::vector<Tuple<String,String> >& items, bool replaceItems = false) throw (ListItemException); diff --git a/xbmc/interfaces/legacy/ModuleXbmc.h b/xbmc/interfaces/legacy/ModuleXbmc.h index 30620a7942..b534741ff4 100644 --- a/xbmc/interfaces/legacy/ModuleXbmc.h +++ b/xbmc/interfaces/legacy/ModuleXbmc.h @@ -89,7 +89,7 @@ namespace XBMCAddon * List of functions - http://wiki.xbmc.org/?title=List_of_Built_In_Functions * * example: - * - xbmc.executebuiltin('XBMC.RunXBE(c:\\avalaunch.xbe)') + * - xbmc.executebuiltin('RunXBE(c:\\avalaunch.xbe)') */ void executebuiltin(const char* function, bool wait = false); @@ -227,14 +227,14 @@ namespace XBMCAddon void playSFX(const char* filename, bool useCached = true); /** - * stopSFX() -- Stops wav file
- *
- * example:
- * - xbmc.stopSFX()
- */
- void stopSFX();
-
- /**
+ * stopSFX() -- Stops wav file + * + * example: + * - xbmc.stopSFX() + */ + void stopSFX(); + + /** * enableNavSounds(yesNo) -- Enables/Disables nav sounds * * yesNo : integer - enable (True) or disable (False) nav sounds diff --git a/xbmc/linux/DBusMessage.cpp b/xbmc/linux/DBusMessage.cpp index 7176dc77f9..67d4339f4d 100644 --- a/xbmc/linux/DBusMessage.cpp +++ b/xbmc/linux/DBusMessage.cpp @@ -28,7 +28,8 @@ CDBusMessage::CDBusMessage(const char *destination, const char *object, const ch m_message = dbus_message_new_method_call (destination, object, interface, method); m_haveArgs = false; - CLog::Log(LOGDEBUG|LOGDBUS, "DBus: Creating message to %s on %s with interface %s and method %s\n", destination, object, interface, method); + if (g_advancedSettings.CanLogComponent(LOGDBUS)) + CLog::Log(LOGDEBUG, "DBus: Creating message to %s on %s with interface %s and method %s\n", destination, object, interface, method); } CDBusMessage::~CDBusMessage() diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp index 73a42c4481..ba1a3d0ee6 100644 --- a/xbmc/linux/RBP.cpp +++ b/xbmc/linux/RBP.cpp @@ -32,6 +32,7 @@ CRBP::CRBP() m_omx_initialized = false; m_DllBcmHost = new DllBcmHost(); m_OMX = new COMXCore(); + m_element = 0; } CRBP::~CRBP() @@ -53,6 +54,9 @@ bool CRBP::Initialize() m_DllBcmHost->bcm_host_init(); + uint32_t vc_image_ptr; + m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); + m_omx_initialized = m_OMX->Initialize(); if(!m_omx_initialized) return false; @@ -156,6 +160,36 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw return image; } +void CRBP::WaitVsync(void) +{ + DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); + DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); + + VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; + VC_RECT_T src_rect; + VC_RECT_T dst_rect; + vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); + vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); + + if (m_element) + vc_dispmanx_element_remove( update, m_element ); + + m_element = vc_dispmanx_element_add( update, + display, + 2000, // layer + &dst_rect, + m_resource, + &src_rect, + DISPMANX_PROTECTION_NONE, + &alpha, + NULL, // clamp + (DISPMANX_TRANSFORM_T)0 ); + + vc_dispmanx_update_submit_sync(update); + vc_dispmanx_display_close( display ); +} + + void CRBP::Deinitialize() { if (m_omx_image_init) diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h index e9a2d5ab00..4fd18f3542 100644 --- a/xbmc/linux/RBP.h +++ b/xbmc/linux/RBP.h @@ -57,6 +57,7 @@ public: // stride can be null for packed output unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } + void WaitVsync(); private: DllBcmHost *m_DllBcmHost; @@ -69,6 +70,8 @@ private: bool m_codec_mpg2_enabled; bool m_codec_wvc1_enabled; COMXCore *m_OMX; + DISPMANX_RESOURCE_HANDLE_T m_resource; + DISPMANX_ELEMENT_HANDLE_T m_element; class DllLibOMXCore; CCriticalSection m_critSection; }; diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp index ceb3e2a97e..d6267a2527 100644 --- a/xbmc/music/MusicDatabase.cpp +++ b/xbmc/music/MusicDatabase.cpp @@ -5070,7 +5070,8 @@ void CMusicDatabase::ExportKaraokeInfo(const CStdString & outFile, bool asHTML) outdoc = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta></head>\n" "<body>\n<table>\n"; - file.Write( outdoc, outdoc.size() ); + if (file.Write(outdoc, outdoc.size()) != outdoc.size()) + return; // error } while (!m_pDS->eof()) @@ -5083,7 +5084,8 @@ void CMusicDatabase::ExportKaraokeInfo(const CStdString & outFile, bool asHTML) else outdoc = songnum + '\t' + (CStdString)StringUtils::Join(song.artist, g_advancedSettings.m_musicItemSeparator) + '\t' + song.strTitle + '\t' + song.strFileName + "\r\n"; - file.Write( outdoc, outdoc.size() ); + if (file.Write(outdoc, outdoc.size()) != outdoc.size()) + return; // error if ((current % 50) == 0 && progress) { @@ -5105,7 +5107,8 @@ void CMusicDatabase::ExportKaraokeInfo(const CStdString & outFile, bool asHTML) if ( asHTML ) { outdoc = "</table>\n</body>\n</html>\n"; - file.Write( outdoc, outdoc.size() ); + if (file.Write(outdoc, outdoc.size()) != outdoc.size()) + return; // error } file.Close(); diff --git a/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp b/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp index 7a3d23e9ba..95bf003121 100644 --- a/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp +++ b/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp @@ -68,12 +68,9 @@ bool CGUIDialogVisualisationPresetList::OnMessage(CGUIMessage &message) } } break; - case GUI_MSG_WINDOW_DEINIT: case GUI_MSG_VISUALISATION_UNLOADING: { m_viz = NULL; - CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_LIST); - OnMessage(msg); Update(); } break; @@ -121,6 +118,15 @@ void CGUIDialogVisualisationPresetList::OnInitWindow() CGUIDialog::OnInitWindow(); } +void CGUIDialogVisualisationPresetList::OnDeinitWindow(int nextWindowID) +{ + CGUIDialog::OnDeinitWindow(nextWindowID); + CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_LIST); + OnMessage(msg); + SET_CONTROL_LABEL(CONTROL_PRESETS_LABEL, ""); + m_vecPresets->Clear(); +} + void CGUIDialogVisualisationPresetList::Update() { m_vecPresets->Clear(); @@ -145,7 +151,7 @@ void CGUIDialogVisualisationPresetList::Update() pItem->SetLabel2(" "); m_vecPresets->Add(pItem); } - CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_LIST, 0, 0, m_vecPresets); + CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_LIST, m_currentPreset, 0, m_vecPresets); OnMessage(msg); } } diff --git a/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h b/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h index 142ef41ecc..fc98d54e56 100644 --- a/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h +++ b/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h @@ -39,6 +39,7 @@ public: protected: virtual void OnInitWindow(); + virtual void OnDeinitWindow(int nextWindowID); void SetVisualisation(ADDON::CVisualisation *addon); void Update(); ADDON::CVisualisation* m_viz; //TODO get rid diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp index 2c6849f254..5e39b73294 100644 --- a/xbmc/music/infoscanner/MusicInfoScanner.cpp +++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp @@ -130,6 +130,7 @@ void CMusicInfoScanner::Process() * the entire source is offline we totally empty the music database in one go. */ CLog::Log(LOGWARNING, "%s directory '%s' does not exist - skipping scan.", __FUNCTION__, it->c_str()); + m_seenPaths.insert(*it); continue; } else if (!DoScan(*it)) @@ -254,6 +255,7 @@ void CMusicInfoScanner::Start(const CStdString& strDirectory, int flags) m_fileCountReader.StopThread(); StopThread(); m_pathsToScan.clear(); + m_seenPaths.clear(); m_flags = flags; if (strDirectory.empty()) @@ -392,6 +394,12 @@ bool CMusicInfoScanner::DoScan(const CStdString& strDirectory) if (m_handle) m_handle->SetText(Prettify(strDirectory)); + std::set<std::string>::const_iterator it = m_seenPaths.find(strDirectory); + if (it != m_seenPaths.end()) + return true; + + m_seenPaths.insert(strDirectory); + // Discard all excluded files defined by m_musicExcludeRegExps vector<string> regexps = g_advancedSettings.m_audioExcludeFromScanRegExps; if (CUtil::ExcludeFileOrFolder(strDirectory, regexps)) diff --git a/xbmc/music/infoscanner/MusicInfoScanner.h b/xbmc/music/infoscanner/MusicInfoScanner.h index 87dce55d4f..b7bfd1fb73 100644 --- a/xbmc/music/infoscanner/MusicInfoScanner.h +++ b/xbmc/music/infoscanner/MusicInfoScanner.h @@ -216,6 +216,7 @@ protected: std::map<CArtistCredit, CArtist> m_artistCache; std::set<std::string> m_pathsToScan; + std::set<std::string> m_seenPaths; int m_flags; CThread m_fileCountReader; }; diff --git a/xbmc/music/tags/MusicInfoTagLoaderSPC.cpp b/xbmc/music/tags/MusicInfoTagLoaderSPC.cpp index 98ee9df6e3..90e1718dab 100644 --- a/xbmc/music/tags/MusicInfoTagLoaderSPC.cpp +++ b/xbmc/music/tags/MusicInfoTagLoaderSPC.cpp @@ -40,27 +40,47 @@ SPC_ID666 *SPC_get_id666FP (CFile& file) file.Seek(0x23,SEEK_SET); char c; - file.Read(&c,1); - if (c == 27) { + if (file.Read(&c,1) != 1 || c == 27) + { free(id); return NULL; } file.Seek(0x2E,SEEK_SET); - file.Read(id->songname,32); + if (file.Read(id->songname, 32) != 32) + { + free(id); + return NULL; + } id->songname[32] = '\0'; - file.Read(id->gametitle,32); + if (file.Read(id->gametitle, 32) != 32) + { + free(id); + return NULL; + } id->gametitle[32] = '\0'; - file.Read(id->dumper,16); + if (file.Read(id->dumper, 16) != 16) + { + free(id); + return NULL; + } id->dumper[16] = '\0'; - file.Read(id->comments,32); + if (file.Read(id->comments, 32) != 32) + { + free(id); + return NULL; + } id->comments[32] = '\0'; file.Seek(0xA9,SEEK_SET); - file.Read(playtime_str,3); + if (file.Read(playtime_str, 3) != 3) + { + free(id); + return NULL; + } playtime_str[3] = '\0'; id->playtime = atoi((char*)playtime_str); @@ -80,7 +100,11 @@ SPC_ID666 *SPC_get_id666FP (CFile& file) } file.Seek(0xB0,SEEK_SET); - file.Read(id->author,32); + if (file.Read(id->author, 32) != 32) + { + free(id); + return NULL; + } id->author[32] = '\0'; return id; diff --git a/xbmc/music/tags/TagLibVFSStream.cpp b/xbmc/music/tags/TagLibVFSStream.cpp index e2abcd5b2a..db4499942a 100644 --- a/xbmc/music/tags/TagLibVFSStream.cpp +++ b/xbmc/music/tags/TagLibVFSStream.cpp @@ -76,7 +76,12 @@ FileName TagLibVFSStream::name() const ByteVector TagLibVFSStream::readBlock(TagLib::ulong length) { ByteVector byteVector(static_cast<TagLib::uint>(length)); - byteVector.resize(m_file.Read(byteVector.data(), length)); + ssize_t read = m_file.Read(byteVector.data(), length); + if (read > 0) + byteVector.resize(read); + else + byteVector.clear(); + return byteVector; } @@ -142,7 +147,9 @@ void TagLibVFSStream::insert(const ByteVector &data, TagLib::ulong start, TagLib // special case. We're also using File::writeBlock() just for the tag. // That's a bit slower than using char *'s so, we're only doing it here. seek(readPosition); - int bytesRead = m_file.Read(aboutToOverwrite.data(), bufferLength); + ssize_t bytesRead = m_file.Read(aboutToOverwrite.data(), bufferLength); + if (bytesRead <= 0) + return; // error readPosition += bufferLength; seek(writePosition); @@ -160,6 +167,8 @@ void TagLibVFSStream::insert(const ByteVector &data, TagLib::ulong start, TagLib // to overwrite. Appropriately increment the readPosition. seek(readPosition); bytesRead = m_file.Read(aboutToOverwrite.data(), bufferLength); + if (bytesRead <= 0) + return; // error aboutToOverwrite.resize(bytesRead); readPosition += bufferLength; @@ -171,7 +180,8 @@ void TagLibVFSStream::insert(const ByteVector &data, TagLib::ulong start, TagLib // Seek to the write position and write our buffer. Increment the // writePosition. seek(writePosition); - m_file.Write(buffer.data(), buffer.size()); + if (m_file.Write(buffer.data(), buffer.size()) < buffer.size()) + return; // error writePosition += buffer.size(); buffer = aboutToOverwrite; @@ -209,7 +219,8 @@ void TagLibVFSStream::removeBlock(TagLib::ulong start, TagLib::ulong length) clear(); seek(writePosition); - m_file.Write(buffer.data(), bytesRead); + if (m_file.Write(buffer.data(), bytesRead) != bytesRead) + return; // error writePosition += bytesRead; } truncate(writePosition); diff --git a/xbmc/network/AirPlayServer.cpp b/xbmc/network/AirPlayServer.cpp index f9e04a0d0a..ffe7dcf377 100644 --- a/xbmc/network/AirPlayServer.cpp +++ b/xbmc/network/AirPlayServer.cpp @@ -134,7 +134,7 @@ const char *eventStrings[] = {"playing", "paused", "loading", "stopped"}; "<key>features</key>\r\n"\ "<integer>119</integer>\r\n"\ "<key>model</key>\r\n"\ -"<string>Xbmc,1</string>\r\n"\ +"<string>Kodi,1</string>\r\n"\ "<key>protovers</key>\r\n"\ "<string>1.0</string>\r\n"\ "<key>srcvers</key>\r\n"\ diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp index 4f52e2d872..e38a2d415f 100644 --- a/xbmc/network/AirTunesServer.cpp +++ b/xbmc/network/AirTunesServer.cpp @@ -171,10 +171,8 @@ void CAirTunesServer::SetCoverArtFromBuffer(const char *buffer, unsigned int siz writtenBytes = tmpFile.Write(buffer, size); tmpFile.Close(); - if(writtenBytes) - { + if (writtenBytes > 0) RefreshCoverArt(); - } } } @@ -213,7 +211,7 @@ void CAirTunesServer::AudioOutputFunctions::audio_set_coverart(void *cls, void * CAirTunesServer::SetCoverArtFromBuffer((char *)buffer, buflen); } -char *session="XBMC-AirTunes"; +char *session="Kodi-AirTunes"; void* CAirTunesServer::AudioOutputFunctions::audio_init(void *cls, int bits, int channels, int samplerate) { @@ -390,7 +388,7 @@ bool CAirTunesServer::StartServer(int port, bool nonlocal, bool usePassword, con txt.push_back(std::make_pair("vn", "3")); txt.push_back(std::make_pair("da", "true")); txt.push_back(std::make_pair("md", "0,1,2")); - txt.push_back(std::make_pair("am", "Xbmc,1")); + txt.push_back(std::make_pair("am", "Kodi,1")); txt.push_back(std::make_pair("vs", "130.14")); CZeroconf::GetInstance()->PublishService("servers.airtunes", "_raop._tcp", appName, port, txt); diff --git a/xbmc/network/EventClient.cpp b/xbmc/network/EventClient.cpp index 927ae0aca0..85b291495b 100644 --- a/xbmc/network/EventClient.cpp +++ b/xbmc/network/EventClient.cpp @@ -322,12 +322,7 @@ bool CEventClient::OnPacketHELO(CEventPacket *packet) break; } XFILE::CFile file; - if (file.OpenForWrite(iconfile, true)) - { - file.Write((const void *)payload, psize); - file.Close(); - } - else + if (!file.OpenForWrite(iconfile, true) || file.Write((const void *)payload, psize) != psize) { CLog::Log(LOGERROR, "ES: Could not write icon file"); m_eLogoType = LT_NONE; @@ -596,12 +591,7 @@ bool CEventClient::OnPacketNOTIFICATION(CEventPacket *packet) } XFILE::CFile file; - if (file.OpenForWrite(iconfile, true)) - { - file.Write((const void *)payload, psize); - file.Close(); - } - else + if (!file.OpenForWrite(iconfile, true) || file.Write((const void *)payload, psize) != psize) { CLog::Log(LOGERROR, "ES: Could not write icon file"); m_eLogoType = LT_NONE; diff --git a/xbmc/network/WebServer.cpp b/xbmc/network/WebServer.cpp index c0b0fdaf9b..dd5a6e1fea 100644 --- a/xbmc/network/WebServer.cpp +++ b/xbmc/network/WebServer.cpp @@ -705,8 +705,8 @@ int CWebServer::ContentReaderCallback(void *cls, size_t pos, char *buf, int max) context->file->Seek(context->writePosition); // read data from the file - unsigned int res = context->file->Read(buf, maximum); - if (res == 0) + ssize_t res = context->file->Read(buf, maximum); + if (res <= 0) return -1; // add the number of read bytes to the number of written bytes diff --git a/xbmc/network/cddb.cpp b/xbmc/network/cddb.cpp index 084be7b643..133ecc9e26 100644 --- a/xbmc/network/cddb.cpp +++ b/xbmc/network/cddb.cpp @@ -32,6 +32,7 @@ #include <taglib/id3v1genres.h> #include "cddb.h" +#include "CompileInfo.h" #include "network/DNSNameCache.h" #include "settings/AdvancedSettings.h" #include "utils/StringUtils.h" @@ -871,10 +872,12 @@ bool Xcddb::queryCDinfo(CCdInfo* pInfo) //########################################################## // Send the Hello message - CStdString version = g_infoManager.GetLabel(SYSTEM_BUILD_VERSION); + std::string version = g_infoManager.GetLabel(SYSTEM_BUILD_VERSION); + std::string lcAppName = CCompileInfo::GetAppName(); + StringUtils::ToLower(lcAppName); if (version.find(" ") != std::string::npos) version = version.substr(0, version.find(" ")); - CStdString strGreeting = "cddb hello xbmc xbmc.org XBMC " + version; + std::string strGreeting = "cddb hello " + lcAppName + " kodi.tv " + CCompileInfo::GetAppName() + " " + version; if ( ! Send(strGreeting.c_str()) ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", strGreeting.c_str()); diff --git a/xbmc/network/upnp/UPnP.cpp b/xbmc/network/upnp/UPnP.cpp index 20e5d97cbc..61911eb68f 100644 --- a/xbmc/network/upnp/UPnP.cpp +++ b/xbmc/network/upnp/UPnP.cpp @@ -184,20 +184,30 @@ public: // PLT_MediaBrowser methods virtual bool OnMSAdded(PLT_DeviceDataReference& device) { + // update any open upnp:// path CGUIMessage message(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_PATH); message.SetStringParam("upnp://"); g_windowManager.SendThreadMessage(message); + // update any open source view + CGUIMessage updateSourcesMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_SOURCES); + g_windowManager.SendThreadMessage(updateSourcesMessage); + return PLT_SyncMediaBrowser::OnMSAdded(device); } virtual void OnMSRemoved(PLT_DeviceDataReference& device) { PLT_SyncMediaBrowser::OnMSRemoved(device); + // update any open upnp:// path CGUIMessage message(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_PATH); message.SetStringParam("upnp://"); g_windowManager.SendThreadMessage(message); + // update any open source view + CGUIMessage updateSourcesMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_SOURCES); + g_windowManager.SendThreadMessage(updateSourcesMessage); + PLT_SyncMediaBrowser::OnMSRemoved(device); } diff --git a/xbmc/osx/CocoaInterface.mm b/xbmc/osx/CocoaInterface.mm index ef2f0e946c..b500c7ce32 100644 --- a/xbmc/osx/CocoaInterface.mm +++ b/xbmc/osx/CocoaInterface.mm @@ -23,6 +23,7 @@ #define BOOL XBMC_BOOL #include "utils/log.h" +#include "CompileInfo.h" #undef BOOL #import <Cocoa/Cocoa.h> @@ -178,9 +179,19 @@ void Cocoa_DoAppleScript(const char* scriptSource) void Cocoa_DoAppleScriptFile(const char* filePath) { NSString* scriptFile = [NSString stringWithUTF8String:filePath]; - NSString* userScriptsPath = [@"~/Library/Application Support/XBMC/scripts" stringByExpandingTildeInPath]; - NSString* bundleScriptsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents/Resources/XBMC/scripts"]; - NSString* bundleSysScriptsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents/Resources/XBMC/system/AppleScripts"]; + NSString* appName = [NSString stringWithUTF8String:CCompileInfo::GetAppName()]; + NSMutableString *tmpStr = [NSMutableString stringWithString:@"~/Library/Application Support/"]; + [tmpStr appendString:appName]; + [tmpStr appendString:@"/scripts"]; + NSString* userScriptsPath = [tmpStr stringByExpandingTildeInPath]; + [tmpStr setString:@"Contents/Resources/"]; + [tmpStr appendString:appName]; + [tmpStr appendString:@"/scripts"]; + NSString* bundleScriptsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:tmpStr]; + [tmpStr setString:@"Contents/Resources/"]; + [tmpStr appendString:appName]; + [tmpStr appendString:@"/system/AppleScripts"]; + NSString* bundleSysScriptsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:tmpStr]; // Check whether a script exists in the app bundle's AppleScripts folder if ([[NSFileManager defaultManager] fileExistsAtPath:[bundleSysScriptsPath stringByAppendingPathComponent:scriptFile]]) @@ -214,7 +225,11 @@ const char* Cocoa_GetIconFromBundle(const char *_bundlePath, const char* _iconNa if (![[NSFileManager defaultManager] fileExistsAtPath:iconPath]) return NULL; // Get the path to the target PNG icon - NSString* pngFile = [[NSString stringWithFormat:@"~/Library/Application Support/XBMC/userdata/Thumbnails/%@-%@.png", + NSString* appName = [NSString stringWithUTF8String:CCompileInfo::GetAppName()]; + NSMutableString *tmpStr = [NSMutableString stringWithString:@"~/Library/Application Support/"]; + [tmpStr appendString:appName]; + [tmpStr appendString:@"/userdata/Thumbnails/%@-%@.png"]; + NSString* pngFile = [[NSString stringWithFormat:tmpStr, bundleIdentifier, iconName] stringByExpandingTildeInPath]; // If no PNG has been created, open the ICNS file & convert diff --git a/xbmc/osx/Credits.html b/xbmc/osx/Credits.html index e3a8241dca..7d45e356b1 100644 --- a/xbmc/osx/Credits.html +++ b/xbmc/osx/Credits.html @@ -18,7 +18,7 @@ th { text-align: right; } </style> </head> <body> -<center><a href="http://xbmc.org/about/">Team XBMC</a></center> +<center><a href="http://xbmc.org/about/">Team Kodi</a></center> <br> <table style="font-family:Verdana;"> diff --git a/xbmc/osx/DarwinUtils.h b/xbmc/osx/DarwinUtils.h index 29bbe94ab7..2b1f6a0bd6 100644 --- a/xbmc/osx/DarwinUtils.h +++ b/xbmc/osx/DarwinUtils.h @@ -34,7 +34,7 @@ public: static bool IsAppleTV2(void); static bool IsMavericks(void); static bool IsSnowLeopard(void); - static bool DeviceHasRetina(void); + static bool DeviceHasRetina(double &scale); static const char *GetOSReleaseString(void); static const char *GetOSVersionString(void); static float GetIOSVersion(void); diff --git a/xbmc/osx/DarwinUtils.mm b/xbmc/osx/DarwinUtils.mm index 1e3272e903..7f82f82f02 100644 --- a/xbmc/osx/DarwinUtils.mm +++ b/xbmc/osx/DarwinUtils.mm @@ -24,6 +24,7 @@ #include "DllPaths.h" #include "GUIUserMessages.h" #include "utils/log.h" +#include "CompileInfo.h" #undef BOOL @@ -91,6 +92,12 @@ enum iosPlatform iPadAirCellular, iPadMini2Wifi, iPadMini2Cellular, + iPhone6, + iPadAir2Wifi, + iPadAir2Cellular, + iPadMini3Wifi, + iPadMini3Cellular, + iPhone6Plus, //from here on list devices with retina support which have scale == 3.0 }; // platform strings are based on http://theiphonewiki.com/wiki/Models @@ -139,6 +146,8 @@ enum iosPlatform getIosPlatform() else if (devStr == "iPhone5,4") eDev = iPhone5CGlobal; else if (devStr == "iPhone6,1") eDev = iPhone5SGSM; else if (devStr == "iPhone6,2") eDev = iPhone5SGlobal; + else if (devStr == "iPhone7,1") eDev = iPhone6Plus; + else if (devStr == "iPhone7,2") eDev = iPhone6; else if (devStr == "iPod1,1") eDev = iPodTouch1G; else if (devStr == "iPod2,1") eDev = iPodTouch2G; else if (devStr == "iPod3,1") eDev = iPodTouch3G; @@ -163,6 +172,11 @@ enum iosPlatform getIosPlatform() else if (devStr == "iPad4,2") eDev = iPadAirCellular; else if (devStr == "iPad4,4") eDev = iPadMini2Wifi; else if (devStr == "iPad4,5") eDev = iPadMini2Cellular; + else if (devStr == "iPad4,7") eDev = iPadMini3Wifi; + else if (devStr == "iPad4,8") eDev = iPadMini3Cellular; + else if (devStr == "iPad4,9") eDev = iPadMini3Cellular; + else if (devStr == "iPad5,3") eDev = iPadAir2Wifi; + else if (devStr == "iPad5,4") eDev = iPadAir2Cellular; else if (devStr == "AppleTV2,1") eDev = AppleTV2; } #endif @@ -211,7 +225,7 @@ bool CDarwinUtils::IsSnowLeopard(void) return isSnowLeopard == 1; } -bool CDarwinUtils::DeviceHasRetina(void) +bool CDarwinUtils::DeviceHasRetina(double &scale) { static enum iosPlatform platform = iDeviceUnknown; @@ -221,6 +235,19 @@ bool CDarwinUtils::DeviceHasRetina(void) platform = getIosPlatform(); } #endif + scale = 1.0; //no retina + + // see http://www.paintcodeapp.com/news/iphone-6-screens-demystified + if (platform >= iPhone4 && platform < iPhone6Plus) + { + scale = 2.0; // 2x render retina + } + + if (platform >= iPhone6Plus) + { + scale = 3.0; //3x render retina + downscale + } + return (platform >= iPhone4); } @@ -299,20 +326,21 @@ int CDarwinUtils::GetFrameworkPath(bool forPython, char* path, uint32_t *pathsi path[0] = 0; *pathsize = 0; - // a) XBMC frappliance running under ATV2 - Class XBMCfrapp = NSClassFromString(@"XBMCATV2Detector"); - if (XBMCfrapp != NULL) + // a) Kodi frappliance running under ATV2 + Class Frapp = NSClassFromString(@"AppATV2Detector"); + if (Frapp != NULL) { - pathname = [[NSBundle bundleForClass:XBMCfrapp] pathForResource:@"Frameworks" ofType:@""]; + pathname = [[NSBundle bundleForClass:Frapp] pathForResource:@"Frameworks" ofType:@""]; strcpy(path, [pathname UTF8String]); *pathsize = strlen(path); //CLog::Log(LOGDEBUG, "DarwinFrameworkPath(a) -> %s", path); return 0; } - // b) XBMC application running under IOS + // b) Kodi application running under IOS pathname = [[NSBundle mainBundle] executablePath]; - if (pathname && strstr([pathname UTF8String], "XBMC.app/XBMC")) + std::string appName = std::string(CCompileInfo::GetAppName()) + ".app/" + std::string(CCompileInfo::GetAppName()); + if (pathname && strstr([pathname UTF8String], appName.c_str())) { strcpy(path, [pathname UTF8String]); // Move backwards to last "/" @@ -324,7 +352,7 @@ int CDarwinUtils::GetFrameworkPath(bool forPython, char* path, uint32_t *pathsi return 0; } - // d) XBMC application running under OSX + // d) Kodi application running under OSX pathname = [[NSBundle mainBundle] executablePath]; if (pathname && strstr([pathname UTF8String], "Contents")) { @@ -345,7 +373,7 @@ int CDarwinUtils::GetFrameworkPath(bool forPython, char* path, uint32_t *pathsi return 0; } - // e) XBMC OSX binary running under xcode or command-line + // e) Kodi OSX binary running under xcode or command-line // but only if it's not for python. In this case, let python // use it's internal compiled paths. if (!forPython) @@ -366,19 +394,20 @@ int CDarwinUtils::GetExecutablePath(char* path, uint32_t *pathsize) // see if we can figure out who we are NSString *pathname; - // a) XBMC frappliance running under ATV2 - Class XBMCfrapp = NSClassFromString(@"XBMCATV2Detector"); - if (XBMCfrapp != NULL) + // a) Kodi frappliance running under ATV2 + Class Frapp = NSClassFromString(@"AppATV2Detector"); + if (Frapp != NULL) { - pathname = [[NSBundle bundleForClass:XBMCfrapp] pathForResource:@"XBMC" ofType:@""]; + NSString *appName = [NSString stringWithUTF8String:CCompileInfo::GetAppName()]; + pathname = [[NSBundle bundleForClass:Frapp] pathForResource:appName ofType:@""]; strcpy(path, [pathname UTF8String]); *pathsize = strlen(path); //CLog::Log(LOGDEBUG, "DarwinExecutablePath(a) -> %s", path); return 0; } - // b) XBMC application running under IOS - // c) XBMC application running under OSX + // b) Kodi application running under IOS + // c) Kodi application running under OSX pathname = [[NSBundle mainBundle] executablePath]; strcpy(path, [pathname UTF8String]); *pathsize = strlen(path); @@ -438,7 +467,7 @@ bool CDarwinUtils::HasVideoToolboxDecoder(void) if (DecoderAvailable == -1) { - Class XBMCfrapp = NSClassFromString(@"XBMCATV2Detector"); + Class XBMCfrapp = NSClassFromString(@"AppATV2Detector"); if (XBMCfrapp != NULL) { // atv2 has seatbelt profile key removed so nothing to do here diff --git a/xbmc/osx/IOSEAGLView.h b/xbmc/osx/IOSEAGLView.h index d821c92a2f..6440300d71 100644 --- a/xbmc/osx/IOSEAGLView.h +++ b/xbmc/osx/IOSEAGLView.h @@ -41,6 +41,7 @@ BOOL animating; BOOL xbmcAlive; + BOOL readyToRun; BOOL pause; NSConditionLock* animationThreadLock; NSThread* animationThread; @@ -55,6 +56,7 @@ } @property (readonly, nonatomic, getter=isAnimating) BOOL animating; @property (readonly, nonatomic, getter=isXBMCAlive) BOOL xbmcAlive; +@property (readonly, nonatomic, getter=isReadyToRun) BOOL readyToRun; @property (readonly, nonatomic, getter=isPause) BOOL pause; @property (readonly, getter=getCurrentScreen) UIScreen *currentScreen; @property BOOL framebufferResizeRequested; diff --git a/xbmc/osx/IOSEAGLView.mm b/xbmc/osx/IOSEAGLView.mm index 6a2cb66dec..50cdf80986 100644 --- a/xbmc/osx/IOSEAGLView.mm +++ b/xbmc/osx/IOSEAGLView.mm @@ -36,6 +36,7 @@ #include "utils/TimeUtils.h" #include "Util.h" #include "XbmcContext.h" +#include "WindowingFactory.h" #undef BOOL #import <QuartzCore/QuartzCore.h> @@ -44,7 +45,7 @@ #import <OpenGLES/ES2/glext.h> #import "IOSEAGLView.h" #if defined(TARGET_DARWIN_IOS_ATV2) -#import "xbmc/osx/atv2/XBMCController.h" +#import "xbmc/osx/atv2/KodiController.h" #elif defined(TARGET_DARWIN_IOS) #import "xbmc/osx/ios/XBMCController.h" #endif @@ -64,6 +65,7 @@ @implementation IOSEAGLView @synthesize animating; @synthesize xbmcAlive; +@synthesize readyToRun; @synthesize pause; @synthesize currentScreen; @synthesize framebufferResizeRequested; @@ -123,9 +125,16 @@ //if no retina display scale detected yet - //ensure retina resolution on supported devices mainScreen //even on older iOS SDKs - if (ret == 1.0 && screen == [UIScreen mainScreen] && CDarwinUtils::DeviceHasRetina()) + double screenScale = 1.0; + if (ret == 1.0 && screen == [UIScreen mainScreen] && CDarwinUtils::DeviceHasRetina(screenScale)) + { + ret = screenScale;//set scale factor from our static list in case older SDKs report 1.0 + } + + // fix for ip6 plus which seems to report 2.0 when not compiled with ios8 sdk + if (CDarwinUtils::DeviceHasRetina(screenScale) && screenScale == 3.0) { - ret = 2.0;//all retina devices have a scale factor of 2.0 + ret = screenScale; } } return ret; @@ -370,7 +379,7 @@ CCocoaAutoPool outerpool; // set up some xbmc specific relationships XBMC::Context context; - bool readyToRun = true; + readyToRun = true; // signal we are alive NSConditionLock* myLock = arg; @@ -449,7 +458,7 @@ if (animationThread && [animationThread isExecuting] == YES) { if (g_VideoReferenceClock.IsRunning()) - g_VideoReferenceClock.VblankHandler(CurrentHostCounter(), displayFPS); + g_Windowing.VblankHandler(CurrentHostCounter(), displayFPS); } [pool release]; } diff --git a/xbmc/osx/IOSExternalTouchController.mm b/xbmc/osx/IOSExternalTouchController.mm index a4b5d0d243..c528eb8c65 100644 --- a/xbmc/osx/IOSExternalTouchController.mm +++ b/xbmc/osx/IOSExternalTouchController.mm @@ -28,7 +28,11 @@ #undef BOOL #import "IOSExternalTouchController.h" +#if defined(TARGET_DARWIN_IOS_ATV2) +#import "KodiController.h" +#else #import "XBMCController.h" +#endif //dim the touchscreen after 15 secs without touch event const CGFloat touchScreenDimTimeoutSecs = 15.0; diff --git a/xbmc/osx/IOSScreenManager.mm b/xbmc/osx/IOSScreenManager.mm index a1647181a8..f27d58cab5 100644 --- a/xbmc/osx/IOSScreenManager.mm +++ b/xbmc/osx/IOSScreenManager.mm @@ -38,7 +38,7 @@ #import "IOSScreenManager.h" #if defined(TARGET_DARWIN_IOS_ATV2) -#import "xbmc/osx/atv2/XBMCController.h" +#import "xbmc/osx/atv2/KodiController.h" #elif defined(TARGET_DARWIN_IOS) #import "xbmc/osx/ios/XBMCController.h" #endif diff --git a/xbmc/osx/Info.plist.in b/xbmc/osx/Info.plist.in index f3ec1897c7..79f37b3591 100644 --- a/xbmc/osx/Info.plist.in +++ b/xbmc/osx/Info.plist.in @@ -7,15 +7,15 @@ <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> - <string>XBMC</string> + <string>@APP_NAME@</string> <key>CFBundleGetInfoString</key> <string>@APP_VERSION_MAJOR@.@APP_VERSION_MINOR@.@APP_VERSION_TAG_LC@</string> <key>CFBundleIconFile</key> - <string>xbmc.icns</string> + <string>@APP_NAME_LC@.icns</string> <key>CFBundleIdentifier</key> - <string>com.teamxbmc.xbmc</string> + <string>org.xbmc.@APP_NAME_LC@</string> <key>CFBundleName</key> - <string>XBMC</string> + <string>@APP_NAME@</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> @@ -23,6 +23,6 @@ <key>CFBundleVersion</key> <string>r####</string> <key>CFBundleSignature</key> - <string>xbmc</string> + <string>@APP_NAME@</string> </dict> </plist> diff --git a/xbmc/osx/XBMCHelper.cpp b/xbmc/osx/XBMCHelper.cpp index a4b749417d..d587be0bd8 100644 --- a/xbmc/osx/XBMCHelper.cpp +++ b/xbmc/osx/XBMCHelper.cpp @@ -27,6 +27,7 @@ #include "XBMCHelper.h" #include "PlatformDefs.h" #include "Util.h" +#include "CompileInfo.h" #include "dialogs/GUIDialogOK.h" #include "dialogs/GUIDialogYesNo.h" @@ -66,7 +67,7 @@ XBMCHelper::XBMCHelper() , m_port(0) , m_errorStarting(false) { - // Compute the XBMC_HOME path. + // Compute the APP_HOME path. CStdString homePath; CUtil::GetHomePath(homePath); m_homepath = homePath; @@ -87,7 +88,7 @@ XBMCHelper::XBMCHelper() // Compute the configuration file name. m_configFile = getenv("HOME"); - m_configFile += "/Library/Application Support/XBMC/XBMCHelper.conf"; + m_configFile += "/Library/Application Support/" + std::string(CCompileInfo::GetAppName()) + "/XBMCHelper.conf"; } ///////////////////////////////////////////////////////////////////////////// diff --git a/xbmc/osx/atv2/English.lproj/InfoPlist.strings b/xbmc/osx/atv2/English.lproj/InfoPlist.strings Binary files differindex 20b6d4b8de..35f59f9a24 100644 --- a/xbmc/osx/atv2/English.lproj/InfoPlist.strings +++ b/xbmc/osx/atv2/English.lproj/InfoPlist.strings diff --git a/xbmc/osx/atv2/XBMCAppliance.h b/xbmc/osx/atv2/KodiAppliance.h index 6942a83de7..26474ecc48 100644 --- a/xbmc/osx/atv2/XBMCAppliance.h +++ b/xbmc/osx/atv2/KodiAppliance.h @@ -20,12 +20,12 @@ #import <BackRow/BackRow.h> -@class XBMCTopShelfController; +@class KodiTopShelfController; //-------------------------------------------------------------- -@interface XBMCAppliance : BRBaseAppliance { +@interface KodiAppliance : BRBaseAppliance { NSArray *_applianceCategories; - XBMCTopShelfController *_topShelfController; + KodiTopShelfController *_topShelfController; } @property(nonatomic, readonly, retain) id topShelfController; diff --git a/xbmc/osx/atv2/XBMCAppliance.mm b/xbmc/osx/atv2/KodiAppliance.mm index c8c6c38f28..a6297f5c33 100644 --- a/xbmc/osx/atv2/XBMCAppliance.mm +++ b/xbmc/osx/atv2/KodiAppliance.mm @@ -25,9 +25,9 @@ * functions for subclassing and adding methods to our instances during runtime (hooking). * * 1. For implementing a method of a base class: - * a) declare it in the form <XBMCAppliance$nameOfMethod> like the others - * b) these methods need to be static and have XBMCAppliance* self, SEL _cmd (replace XBMCAppliance with the class the method gets implemented for) as minimum params. - * c) add the method to the XBMCAppliance.h for getting rid of the compiler warnings of unresponsive selectors (declare the method like done in the baseclass). + * a) declare it in the form <KodiAppliance$nameOfMethod> like the others + * b) these methods need to be static and have KodiAppliance* self, SEL _cmd (replace KodiAppliance with the class the method gets implemented for) as minimum params. + * c) add the method to the KodiAppliance.h for getting rid of the compiler warnings of unresponsive selectors (declare the method like done in the baseclass). * d) in initApplianceRuntimeClasses exchange the base class implementation with ours by calling MSHookMessageEx * e) if we need to call the base class implementation as well we have to save the original implementation (see initWithApplianceInfo$Orig for reference) * @@ -51,8 +51,8 @@ #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> -#import "XBMCAppliance.h" -#import "XBMCController.h" +#import "KodiAppliance.h" +#import "KodiController.h" #include "substrate.h" // SECTIONCOMMENT @@ -60,22 +60,22 @@ static Class BRApplianceCategoryCls; // category for ios5.x and higher is just a short text before xbmc auto starts -#define XBMCAppliance_CAT_5andhigher [BRApplianceCategoryCls categoryWithName:@"XBMC is starting..." identifier:@"xbmc" preferredOrder:0] +#define KodiAppliance_CAT_5andhigher [BRApplianceCategoryCls categoryWithName:@"Kodi is starting..." identifier:@"kodi" preferredOrder:0] // category for ios4.x is the menu entry -#define XBMCAppliance_CAT_4 [BRApplianceCategoryCls categoryWithName:@"XBMC" identifier:@"xbmc" preferredOrder:0] +#define KodiAppliance_CAT_4 [BRApplianceCategoryCls categoryWithName:@"Kodi" identifier:@"kodi" preferredOrder:0] // SECTIONCOMMENT // forward declaration all referenced classes -@class XBMCAppliance; +@class KodiAppliance; @class BRTopShelfView; -@class XBMCApplianceInfo; +@class KodiApplianceInfo; @class BRMainMenuImageControl; // SECTIONCOMMENT // orig method handlers we wanna call in hooked methods -static id (*XBMCAppliance$initWithApplianceInfo$Orig)(XBMCAppliance*, SEL, id); -static id (*XBMCAppliance$init$Orig)(XBMCAppliance*, SEL); -static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); +static id (*KodiAppliance$initWithApplianceInfo$Orig)(KodiAppliance*, SEL, id); +static id (*KodiAppliance$init$Orig)(KodiAppliance*, SEL); +static id (*KodiAppliance$applianceInfo$Orig)(KodiAppliance*, SEL); //-------------------------------------------------------------- //-------------------------------------------------------------- @@ -87,7 +87,7 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); @end -@interface XBMCATV2Detector : NSObject{} +@interface AppATV2Detector : NSObject{} + (BOOL) hasOldGui; + (BOOL) isIos5; + (BOOL) needsApplianceInfoHack; @@ -97,10 +97,10 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); //-------------------------------------------------------------- // We need a real implementation (not a runtime generated one) // for getting our NSBundle instance by calling -// [[NSBundle bundleForClass:objc_getClass("XBMCATV2Detector")] +// [[NSBundle bundleForClass:objc_getClass("AppATV2Detector")] // so we just implement some usefull helpers here // and use those -@implementation XBMCATV2Detector : NSObject{} +@implementation AppATV2Detector : NSObject{} + (BOOL) hasOldGui { Class cls = NSClassFromString(@"ATVVersionInfo"); @@ -122,7 +122,7 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); + (BOOL) needsApplianceInfoHack { // if the runtime base class (BRBaseAppliance) doesn't have the initWithApplianceInfo selector - // we need to hack the appliance info in (id) applianceInfo (XBMCAppliance$applianceInfo) + // we need to hack the appliance info in (id) applianceInfo (KodiAppliance$applianceInfo) if (class_respondsToSelector(objc_getClass("BRBaseAppliance"),@selector(initWithApplianceInfo:))) return FALSE; return TRUE; @@ -140,7 +140,7 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); //-------------------------------------------------------------- //-------------------------------------------------------------- -@interface XBMCTopShelfController : NSObject +@interface KodiTopShelfController : NSObject { } - (void) selectCategoryWithIdentifier:(id)identifier; @@ -152,7 +152,7 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); //-------------------------------------------------------------- //-------------------------------------------------------------- -@implementation XBMCTopShelfController +@implementation KodiTopShelfController - (void) selectCategoryWithIdentifier:(id)identifier { @@ -164,11 +164,11 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); id topShelf = [[cls alloc] init]; // diddle the topshelf logo on old gui - if ([XBMCATV2Detector hasOldGui]) + if ([AppATV2Detector hasOldGui]) { Class cls = objc_getClass("BRImage"); BRImageControl *imageControl = (BRImageControl *)MSHookIvar<id>(topShelf, "_productImage");// hook the productImage so we can diddle with it - BRImage *gpImage = [cls imageWithPath:[[NSBundle bundleForClass:[XBMCATV2Detector class]] pathForResource:@"XBMC" ofType:@"png"]]; + BRImage *gpImage = [cls imageWithPath:[[NSBundle bundleForClass:[AppATV2Detector class]] pathForResource:@"TopShelf" ofType:@"png"]]; [imageControl setImage:gpImage]; } @@ -193,7 +193,7 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); BRImageControl *imageControl = (BRImageControl *)MSHookIvar<id>(mainMenuImageControl, "_content");// hook the image so we can diddle with it // load our logo into it - BRImage *gpImage = [BRImageCls imageWithPath:[[NSBundle bundleForClass:[XBMCATV2Detector class]] pathForResource:@"XBMC" ofType:@"png"]]; + BRImage *gpImage = [BRImageCls imageWithPath:[[NSBundle bundleForClass:[AppATV2Detector class]] pathForResource:@"Kodi" ofType:@"png"]]; [imageControl setImage:gpImage]; return topShelf; } @@ -207,32 +207,32 @@ static id (*XBMCAppliance$applianceInfo$Orig)(XBMCAppliance*, SEL); //-------------------------------------------------------------- // SECTIONCOMMENT // since we can't inject ivars we need to use associated objects -// these are the keys for XBMCAppliance -//implementation XBMCAppliance +// these are the keys for KodiAppliance +//implementation KodiAppliance static char topShelfControllerKey; static char applianceCategoriesKey; -static NSString* XBMCApplianceInfo$key(XBMCApplianceInfo* self, SEL _cmd) +static NSString* KodiApplianceInfo$key(KodiApplianceInfo* self, SEL _cmd) { - return [[[NSBundle bundleForClass:objc_getClass("XBMCATV2Detector")] infoDictionary] objectForKey:(NSString*)kCFBundleIdentifierKey]; + return [[[NSBundle bundleForClass:objc_getClass("AppATV2Detector")] infoDictionary] objectForKey:(NSString*)kCFBundleIdentifierKey]; } -static NSString* XBMCApplianceInfo$name(XBMCApplianceInfo* self, SEL _cmd) +static NSString* KodiApplianceInfo$name(KodiApplianceInfo* self, SEL _cmd) { - return [[[NSBundle bundleForClass:objc_getClass("XBMCATV2Detector")] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + return [[[NSBundle bundleForClass:objc_getClass("AppATV2Detector")] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; } -static id XBMCApplianceInfo$localizedStringsFileName(XBMCApplianceInfo* self, SEL _cmd) +static id KodiApplianceInfo$localizedStringsFileName(KodiApplianceInfo* self, SEL _cmd) { - return @"xbmc"; + return @"kodi"; } -static void XBMCAppliance$XBMCfixUIDevice(XBMCAppliance* self, SEL _cmd) +static void KodiAppliance$XBMCfixUIDevice(KodiAppliance* self, SEL _cmd) { // iOS 5.x has removed the internal load of UIKit in AppleTV app // and there is an overlap of some UIKit and AppleTV methods. // This voodoo seems to clear up the wonkiness. :) - if ([XBMCATV2Detector isIos5]) + if ([AppATV2Detector isIos5]) { id cd = nil; @@ -256,18 +256,18 @@ static void XBMCAppliance$XBMCfixUIDevice(XBMCAppliance* self, SEL _cmd) } -static id XBMCAppliance$init(XBMCAppliance* self, SEL _cmd) +static id KodiAppliance$init(KodiAppliance* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); - if ([XBMCATV2Detector needsApplianceInfoHack]) + if ([AppATV2Detector needsApplianceInfoHack]) { NSLog(@"%s for ios 4", __PRETTY_FUNCTION__); - if ((self = XBMCAppliance$init$Orig(self, _cmd))!= nil) + if ((self = KodiAppliance$init$Orig(self, _cmd))!= nil) { - id topShelfControl = [[XBMCTopShelfController alloc] init]; + id topShelfControl = [[KodiTopShelfController alloc] init]; [self setTopShelfController:topShelfControl]; - NSArray *catArray = [[NSArray alloc] initWithObjects:XBMCAppliance_CAT_4,nil]; + NSArray *catArray = [[NSArray alloc] initWithObjects:KodiAppliance_CAT_4,nil]; [self setApplianceCategories:catArray]; return self; } @@ -280,31 +280,31 @@ static id XBMCAppliance$init(XBMCAppliance* self, SEL _cmd) return self; } -static id XBMCAppliance$identifierForContentAlias(XBMCAppliance* self, SEL _cmd, id contentAlias) +static id KodiAppliance$identifierForContentAlias(KodiAppliance* self, SEL _cmd, id contentAlias) { - return@"xbmc"; + return@"kodi"; } -static BOOL XBMCAppliance$handleObjectSelection(XBMCAppliance* self, SEL _cmd, id fp8, id fp12) +static BOOL KodiAppliance$handleObjectSelection(KodiAppliance* self, SEL _cmd, id fp8, id fp12) { //NSLog(@"%s", __PRETTY_FUNCTION__); return YES; } -static id XBMCAppliance$applianceInfo(XBMCAppliance* self, SEL _cmd) +static id KodiAppliance$applianceInfo(KodiAppliance* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION) // load our plist into memory and merge it with // the dict from the baseclass if needed // cause ios seems to fail on that somehow (at least on 4.x) - if ([XBMCATV2Detector needsApplianceInfoHack] && self != nil) + if ([AppATV2Detector needsApplianceInfoHack] && self != nil) { - id original = XBMCAppliance$applianceInfo$Orig(self, _cmd); + id original = KodiAppliance$applianceInfo$Orig(self, _cmd); id info = MSHookIvar<id>(original, "_info");// hook the infoDictionary so we can diddle with it - NSString *plistPath = [[NSBundle bundleForClass:objc_getClass("XBMCATV2Detector")] pathForResource:@"Info" ofType:@"plist"]; - NSString *bundlePath = [[NSBundle bundleForClass:objc_getClass("XBMCATV2Detector")] bundlePath]; + NSString *plistPath = [[NSBundle bundleForClass:objc_getClass("AppATV2Detector")] pathForResource:@"Info" ofType:@"plist"]; + NSString *bundlePath = [[NSBundle bundleForClass:objc_getClass("AppATV2Detector")] bundlePath]; NSMutableDictionary *ourInfoDict = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath]; if (ourInfoDict != nil && bundlePath != nil) @@ -320,57 +320,57 @@ static id XBMCAppliance$applianceInfo(XBMCAppliance* self, SEL _cmd) } else { - Class cls = objc_getClass("XBMCApplianceInfo"); + Class cls = objc_getClass("KodiApplianceInfo"); return [[[cls alloc] init] autorelease]; } return nil; } -static id XBMCAppliance$topShelfController(XBMCAppliance* self, SEL _cmd) +static id KodiAppliance$topShelfController(KodiAppliance* self, SEL _cmd) { return objc_getAssociatedObject(self, &topShelfControllerKey); } -static void XBMCAppliance$setTopShelfController(XBMCAppliance* self, SEL _cmd, id topShelfControl) +static void KodiAppliance$setTopShelfController(KodiAppliance* self, SEL _cmd, id topShelfControl) { objc_setAssociatedObject(self, &topShelfControllerKey, topShelfControl, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -static id XBMCAppliance$applianceCategories(XBMCAppliance* self, SEL _cmd) +static id KodiAppliance$applianceCategories(KodiAppliance* self, SEL _cmd) { return objc_getAssociatedObject(self, &applianceCategoriesKey); } -static void XBMCAppliance$setApplianceCategories(XBMCAppliance* self, SEL _cmd, id applianceCategories) +static void KodiAppliance$setApplianceCategories(KodiAppliance* self, SEL _cmd, id applianceCategories) { objc_setAssociatedObject(self, &applianceCategoriesKey, applianceCategories, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -static id XBMCAppliance$initWithApplianceInfo(XBMCAppliance* self, SEL _cmd, id applianceInfo) +static id KodiAppliance$initWithApplianceInfo(KodiAppliance* self, SEL _cmd, id applianceInfo) { //NSLog(@"%s", __PRETTY_FUNCTION__); - if((self = XBMCAppliance$initWithApplianceInfo$Orig(self, _cmd, applianceInfo)) != nil) + if((self = KodiAppliance$initWithApplianceInfo$Orig(self, _cmd, applianceInfo)) != nil) { - id topShelfControl = [[XBMCTopShelfController alloc] init]; + id topShelfControl = [[KodiTopShelfController alloc] init]; [self setTopShelfController:topShelfControl]; - NSArray *catArray = [[NSArray alloc] initWithObjects:XBMCAppliance_CAT_5andhigher,nil]; + NSArray *catArray = [[NSArray alloc] initWithObjects:KodiAppliance_CAT_5andhigher,nil]; [self setApplianceCategories:catArray]; } return self; } -static id XBMCAppliance$controllerForIdentifier(XBMCAppliance* self, SEL _cmd, id identifier, id args) +static id KodiAppliance$controllerForIdentifier(KodiAppliance* self, SEL _cmd, id identifier, id args) { //NSLog(@"%s", __PRETTY_FUNCTION__); id menuController = nil; Class cls = objc_getClass("BRApplication"); - if ([identifier isEqualToString:@"xbmc"]) + if ([identifier isEqualToString:@"kodi"]) { [self XBMCfixUIDevice]; - menuController = [[objc_getClass("XBMCController") alloc] init]; + menuController = [[objc_getClass("KodiController") alloc] init]; if (menuController == nil) NSLog(@"initialise controller - fail"); } @@ -382,7 +382,7 @@ static id XBMCAppliance$controllerForIdentifier(XBMCAppliance* self, SEL _cmd, i static void XBMCPopUpManager$_displayPopUp(BRPopUpManager *self, SEL _cmd, id up) { // suppress all popups - NSLog(@"%s suppressing popup - for the sake of XBMC.", __PRETTY_FUNCTION__); + NSLog(@"%s suppressing popup.", __PRETTY_FUNCTION__); } // helper function. If the given class responds to the selector @@ -419,48 +419,48 @@ static __attribute__((constructor)) void initApplianceRuntimeClasses() // XBMC does so too. safeHook(objc_getClass("BRPopUpManager"), @selector(_displayPopUp:), (IMP)&XBMCPopUpManager$_displayPopUp, nil, NO); - // subclass BRApplianceInfo into XBMCApplianceInfo - Class XBMCApplianceInfoCls = objc_allocateClassPair(objc_getClass("BRApplianceInfo"), "XBMCApplianceInfo", 0); + // subclass BRApplianceInfo into KodiApplianceInfo + Class KodiApplianceInfoCls = objc_allocateClassPair(objc_getClass("BRApplianceInfo"), "KodiApplianceInfo", 0); // and hook up our methods (implementation of the base class methods) - // XBMCApplianceInfo::key - safeHook(XBMCApplianceInfoCls,@selector(key), (IMP)&XBMCApplianceInfo$key, nil); - // XBMCApplianceInfo::name - safeHook(XBMCApplianceInfoCls,@selector(name), (IMP)&XBMCApplianceInfo$name, nil); - // XBMCApplianceInfo::localizedStringsFileName - safeHook(XBMCApplianceInfoCls,@selector(localizedStringsFileName), (IMP)&XBMCApplianceInfo$localizedStringsFileName, nil); + // KodiApplianceInfo::key + safeHook(KodiApplianceInfoCls,@selector(key), (IMP)&KodiApplianceInfo$key, nil); + // KodiApplianceInfo::name + safeHook(KodiApplianceInfoCls,@selector(name), (IMP)&KodiApplianceInfo$name, nil); + // KodiApplianceInfo::localizedStringsFileName + safeHook(KodiApplianceInfoCls,@selector(localizedStringsFileName), (IMP)&KodiApplianceInfo$localizedStringsFileName, nil); // and register the class to the runtime - objc_registerClassPair(XBMCApplianceInfoCls); + objc_registerClassPair(KodiApplianceInfoCls); - // subclass BRBaseAppliance into XBMCAppliance - Class XBMCApplianceCls = objc_allocateClassPair(objc_getClass("BRBaseAppliance"), "XBMCAppliance", 0); + // subclass BRBaseAppliance into KodiAppliance + Class KodiApplianceCls = objc_allocateClassPair(objc_getClass("BRBaseAppliance"), "KodiAppliance", 0); // add our custom methods which are not part of the baseclass - // XBMCAppliance::XBMCfixUIDevice - class_addMethod(XBMCApplianceCls,@selector(XBMCfixUIDevice), (IMP)XBMCAppliance$XBMCfixUIDevice, "v@:"); - class_addMethod(XBMCApplianceCls,@selector(setTopShelfController:), (IMP)&XBMCAppliance$setTopShelfController, "v@:@"); - class_addMethod(XBMCApplianceCls,@selector(setApplianceCategories:), (IMP)&XBMCAppliance$setApplianceCategories, "v@:@"); + // KodiAppliance::XBMCfixUIDevice + class_addMethod(KodiApplianceCls,@selector(XBMCfixUIDevice), (IMP)KodiAppliance$XBMCfixUIDevice, "v@:"); + class_addMethod(KodiApplianceCls,@selector(setTopShelfController:), (IMP)&KodiAppliance$setTopShelfController, "v@:@"); + class_addMethod(KodiApplianceCls,@selector(setApplianceCategories:), (IMP)&KodiAppliance$setApplianceCategories, "v@:@"); // and hook up our methods (implementation of the base class methods) - // XBMCAppliance::init - safeHook(XBMCApplianceCls,@selector(init), (IMP)&XBMCAppliance$init, (IMP*)&XBMCAppliance$init$Orig); - // XBMCAppliance::identifierForContentAlias - safeHook(XBMCApplianceCls,@selector(identifierForContentAlias:), (IMP)&XBMCAppliance$identifierForContentAlias, nil); - // XBMCAppliance::handleObjectSelection - safeHook(XBMCApplianceCls,@selector(handleObjectSelection:userInfo:), (IMP)&XBMCAppliance$handleObjectSelection, nil); - // XBMCAppliance::applianceInfo - safeHook(XBMCApplianceCls,@selector(applianceInfo), (IMP)&XBMCAppliance$applianceInfo, (IMP *)&XBMCAppliance$applianceInfo$Orig); - // XBMCAppliance::topShelfController - safeHook(XBMCApplianceCls,@selector(topShelfController), (IMP)&XBMCAppliance$topShelfController, nil); - // XBMCAppliance::applianceCategories - safeHook(XBMCApplianceCls,@selector(applianceCategories), (IMP)&XBMCAppliance$applianceCategories, nil); - // XBMCAppliance::initWithApplianceInfo - safeHook(XBMCApplianceCls,@selector(initWithApplianceInfo:), (IMP)&XBMCAppliance$initWithApplianceInfo, (IMP*)&XBMCAppliance$initWithApplianceInfo$Orig); - // XBMCAppliance::controllerForIdentifier - safeHook(XBMCApplianceCls,@selector(controllerForIdentifier:args:), (IMP)&XBMCAppliance$controllerForIdentifier, nil); + // KodiAppliance::init + safeHook(KodiApplianceCls,@selector(init), (IMP)&KodiAppliance$init, (IMP*)&KodiAppliance$init$Orig); + // KodiAppliance::identifierForContentAlias + safeHook(KodiApplianceCls,@selector(identifierForContentAlias:), (IMP)&KodiAppliance$identifierForContentAlias, nil); + // KodiAppliance::handleObjectSelection + safeHook(KodiApplianceCls,@selector(handleObjectSelection:userInfo:), (IMP)&KodiAppliance$handleObjectSelection, nil); + // KodiAppliance::applianceInfo + safeHook(KodiApplianceCls,@selector(applianceInfo), (IMP)&KodiAppliance$applianceInfo, (IMP *)&KodiAppliance$applianceInfo$Orig); + // KodiAppliance::topShelfController + safeHook(KodiApplianceCls,@selector(topShelfController), (IMP)&KodiAppliance$topShelfController, nil); + // KodiAppliance::applianceCategories + safeHook(KodiApplianceCls,@selector(applianceCategories), (IMP)&KodiAppliance$applianceCategories, nil); + // KodiAppliance::initWithApplianceInfo + safeHook(KodiApplianceCls,@selector(initWithApplianceInfo:), (IMP)&KodiAppliance$initWithApplianceInfo, (IMP*)&KodiAppliance$initWithApplianceInfo$Orig); + // KodiAppliance::controllerForIdentifier + safeHook(KodiApplianceCls,@selector(controllerForIdentifier:args:), (IMP)&KodiAppliance$controllerForIdentifier, nil); // and register the class to the runtime - objc_registerClassPair(XBMCApplianceCls); + objc_registerClassPair(KodiApplianceCls); // save this as static for referencing it in the macro at the top of the file BRApplianceCategoryCls = objc_getClass("BRApplianceCategory"); diff --git a/xbmc/osx/atv2/XBMCController.h b/xbmc/osx/atv2/KodiController.h index 29614141ad..3902fbf619 100644 --- a/xbmc/osx/atv2/XBMCController.h +++ b/xbmc/osx/atv2/KodiController.h @@ -24,7 +24,7 @@ #import "IOSSCreenManager.h" #include "XBMC_keysym.h" -@interface XBMCController : BRController +@interface KodiController : BRController { int padding[16]; // credit is due here to SapphireCompatibilityClasses!! @@ -38,7 +38,7 @@ } // message from which our instance is obtained -//+ (XBMCController*) sharedInstance; +//+ (KodiController*) sharedInstance; - (void) applicationDidExit; - (void) initDisplayLink; @@ -74,4 +74,4 @@ @end -extern XBMCController *g_xbmcController; +extern KodiController *g_xbmcController; diff --git a/xbmc/osx/atv2/XBMCController.mm b/xbmc/osx/atv2/KodiController.mm index 0ad21356f5..1f3be7b2f0 100644 --- a/xbmc/osx/atv2/XBMCController.mm +++ b/xbmc/osx/atv2/KodiController.mm @@ -25,9 +25,9 @@ * functions for subclassing and adding methods to our instances during runtime (hooking). * * 1. For implementing a method of a base class: - * a) declare it in the form <XBMCController$nameOfMethod> like the others - * b) these methods need to be static and have XBMCController* self, SEL _cmd (replace XBMCAppliance with the class the method gets implemented for) as minimum params. - * c) add the method to the XBMCController.h for getting rid of the compiler warnings of unresponsive selectors (declare the method like done in the baseclass). + * a) declare it in the form <KodiController$nameOfMethod> like the others + * b) these methods need to be static and have KodiController* self, SEL _cmd (replace ATV2Appliance with the class the method gets implemented for) as minimum params. + * c) add the method to the KodiController.h for getting rid of the compiler warnings of unresponsive selectors (declare the method like done in the baseclass). * d) in initControllerRuntimeClasses exchange the base class implementation with ours by calling MSHookMessageEx * e) if we need to call the base class implementation as well we have to save the original implementation (see brEventAction$Orig for reference) * @@ -63,7 +63,7 @@ #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> -#import "XBMCController.h" +#import "KodiController.h" #import "XBMCDebugHelpers.h" #import "IOSEAGLView.h" @@ -214,7 +214,7 @@ typedef enum { }BREventOriginiator; -XBMCController *g_xbmcController; +KodiController *g_xbmcController; //-------------------------------------------------------------- // so we don't have to include AppleTV.frameworks/PrivateHeaders/ATVSettingsFacade.h @@ -234,11 +234,11 @@ extern NSString* kBRScreenSaverDismissed; //-------------------------------------------------------------- // SECTIONCOMMENT // orig method handlers we wanna call in hooked methods ([super method]) -static BOOL (*XBMCController$brEventAction$Orig)(XBMCController*, SEL, BREvent*); -static id (*XBMCController$init$Orig)(XBMCController*, SEL); -static void (*XBMCController$dealloc$Orig)(XBMCController*, SEL); -static void (*XBMCController$controlWasActivated$Orig)(XBMCController*, SEL); -static void (*XBMCController$controlWasDeactivated$Orig)(XBMCController*, SEL); +static BOOL (*KodiController$brEventAction$Orig)(KodiController*, SEL, BREvent*); +static id (*KodiController$init$Orig)(KodiController*, SEL); +static void (*KodiController$dealloc$Orig)(KodiController*, SEL); +static void (*KodiController$controlWasActivated$Orig)(KodiController*, SEL); +static void (*KodiController$controlWasDeactivated$Orig)(KodiController*, SEL); // SECTIONCOMMENT // classes we need multiple times @@ -250,7 +250,7 @@ int padding[16];//obsolete? - was commented with "credit is due here to Sapphire //-------------------------------------------------------------- // SECTIONCOMMENT // since we can't inject ivars we need to use associated objects -// these are the keys for XBMCController +// these are the keys for KodiController static char timerKey; static char glviewKey; static char screensaverKey; @@ -259,49 +259,49 @@ static char systemsleepKey; // // // SECTIONCOMMENT -//implementation XBMCController +//implementation KodiController -static id XBMCController$keyTimer(XBMCController* self, SEL _cmd) +static id KodiController$keyTimer(KodiController* self, SEL _cmd) { return objc_getAssociatedObject(self, &timerKey); } -static void XBMCController$setKeyTimer(XBMCController* self, SEL _cmd, id timer) +static void KodiController$setKeyTimer(KodiController* self, SEL _cmd, id timer) { objc_setAssociatedObject(self, &timerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -static id XBMCController$glView(XBMCController* self, SEL _cmd) +static id KodiController$glView(KodiController* self, SEL _cmd) { return objc_getAssociatedObject(self, &glviewKey); } -static void XBMCController$setGlView(XBMCController* self, SEL _cmd, id view) +static void KodiController$setGlView(KodiController* self, SEL _cmd, id view) { objc_setAssociatedObject(self, &glviewKey, view, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -static id XBMCController$systemScreenSaverTimeout(XBMCController* self, SEL _cmd) +static id KodiController$systemScreenSaverTimeout(KodiController* self, SEL _cmd) { return objc_getAssociatedObject(self, &screensaverKey); } -static void XBMCController$setSystemScreenSaverTimeout(XBMCController* self, SEL _cmd, id timeout) +static void KodiController$setSystemScreenSaverTimeout(KodiController* self, SEL _cmd, id timeout) { objc_setAssociatedObject(self, &screensaverKey, timeout, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -static id XBMCController$systemSleepTimeout(XBMCController* self, SEL _cmd) +static id KodiController$systemSleepTimeout(KodiController* self, SEL _cmd) { return objc_getAssociatedObject(self, &systemsleepKey); } -static void XBMCController$setSystemSleepTimeout(XBMCController* self, SEL _cmd, id timeout) +static void KodiController$setSystemSleepTimeout(KodiController* self, SEL _cmd, id timeout) { objc_setAssociatedObject(self, &systemsleepKey, timeout, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -static void XBMCController$applicationDidExit(XBMCController* self, SEL _cmd) +static void KodiController$applicationDidExit(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); @@ -311,38 +311,38 @@ static void XBMCController$applicationDidExit(XBMCController* self, SEL _cmd) [[self stack] popController]; } -static void XBMCController$initDisplayLink(XBMCController* self, SEL _cmd) +static void KodiController$initDisplayLink(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); [[self glView] initDisplayLink]; } -static void XBMCController$deinitDisplayLink(XBMCController* self, SEL _cmd) +static void KodiController$deinitDisplayLink(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); [[self glView] deinitDisplayLink]; } -static double XBMCController$getDisplayLinkFPS(XBMCController* self, SEL _cmd) +static double KodiController$getDisplayLinkFPS(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); return [[self glView] getDisplayLinkFPS]; } -static void XBMCController$setFramebuffer(XBMCController* self, SEL _cmd) +static void KodiController$setFramebuffer(KodiController* self, SEL _cmd) { [[self glView] setFramebuffer]; } -static bool XBMCController$presentFramebuffer(XBMCController* self, SEL _cmd) +static bool KodiController$presentFramebuffer(KodiController* self, SEL _cmd) { return [[self glView] presentFramebuffer]; } -static CGSize XBMCController$getScreenSize(XBMCController* self, SEL _cmd) +static CGSize KodiController$getScreenSize(KodiController* self, SEL _cmd) { CGSize screensize; screensize.width = [BRWindowCls interfaceFrame].size.width; @@ -352,15 +352,15 @@ static CGSize XBMCController$getScreenSize(XBMCController* self, SEL _cmd) return screensize; } -static void XBMCController$sendKey(XBMCController* self, SEL _cmd, XBMCKey key) +static void KodiController$sendKey(KodiController* self, SEL _cmd, XBMCKey key) { //empty because its not used here. Only implemented for getting rid //of "may not respond to selector" compile warnings in IOSExternalTouchController } -static id XBMCController$init(XBMCController* self, SEL _cmd) +static id KodiController$init(KodiController* self, SEL _cmd) { - if((self = XBMCController$init$Orig(self, _cmd)) != nil) + if((self = KodiController$init$Orig(self, _cmd)) != nil) { //NSLog(@"%s", __PRETTY_FUNCTION__); @@ -383,7 +383,7 @@ static id XBMCController$init(XBMCController* self, SEL _cmd) return self; } -static void XBMCController$dealloc(XBMCController* self, SEL _cmd) +static void KodiController$dealloc(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); [[self glView] stopAnimation]; @@ -394,14 +394,14 @@ static void XBMCController$dealloc(XBMCController* self, SEL _cmd) center = [NSNotificationCenter defaultCenter]; [center removeObserver: self]; - XBMCController$dealloc$Orig(self, _cmd); + KodiController$dealloc$Orig(self, _cmd); } -static void XBMCController$controlWasActivated(XBMCController* self, SEL _cmd) +static void KodiController$controlWasActivated(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); - XBMCController$controlWasActivated$Orig(self, _cmd); + KodiController$controlWasActivated$Orig(self, _cmd); [self disableSystemSleep]; [self disableScreenSaver]; @@ -413,9 +413,9 @@ static void XBMCController$controlWasActivated(XBMCController* self, SEL _cmd) [[self glView] startAnimation]; } -static void XBMCController$controlWasDeactivated(XBMCController* self, SEL _cmd) +static void KodiController$controlWasDeactivated(KodiController* self, SEL _cmd) { - NSLog(@"XBMC was forced by FrontRow to exit via controlWasDeactivated"); + NSLog(@"forced by FrontRow to exit via controlWasDeactivated"); [[self glView] stopAnimation]; [[[self glView] layer] removeFromSuperlayer]; @@ -423,23 +423,23 @@ static void XBMCController$controlWasDeactivated(XBMCController* self, SEL _cmd) [self enableScreenSaver]; [self enableSystemSleep]; - XBMCController$controlWasDeactivated$Orig(self, _cmd); + KodiController$controlWasDeactivated$Orig(self, _cmd); } -static BOOL XBMCController$recreateOnReselect(XBMCController* self, SEL _cmd) +static BOOL KodiController$recreateOnReselect(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); return YES; } -static void XBMCController$ATVClientEventFromBREvent(XBMCController* self, SEL _cmd, BREvent* f_event, bool * isRepeatable, bool * isPressed, int * result) +static void KodiController$ATVClientEventFromBREvent(KodiController* self, SEL _cmd, BREvent* f_event, bool * isRepeatable, bool * isPressed, int * result) { if(f_event == nil)// paranoia return; int remoteAction = [f_event remoteAction]; unsigned int originator = [f_event originator]; - CLog::Log(LOGDEBUG,"XBMCPureController: Button press remoteAction = %i originator = %i", remoteAction, originator); + CLog::Log(LOGDEBUG,"KodiController: Button press remoteAction = %i originator = %i", remoteAction, originator); *isRepeatable = false; *isPressed = false; @@ -714,12 +714,12 @@ static void XBMCController$ATVClientEventFromBREvent(XBMCController* self, SEL _ return; default: - ELOG(@"XBMCPureController: Unknown button press remoteAction = %i", remoteAction); + ELOG(@"KodiController: Unknown button press remoteAction = %i", remoteAction); *result = ATV_INVALID_BUTTON; } } -static void XBMCController$setUserEvent(XBMCController* self, SEL _cmd, int eventId, unsigned int holdTime) +static void KodiController$setUserEvent(KodiController* self, SEL _cmd, int eventId, unsigned int holdTime) { XBMC_Event newEvent; @@ -731,7 +731,7 @@ static void XBMCController$setUserEvent(XBMCController* self, SEL _cmd, int even CWinEvents::MessagePush(&newEvent); } -static unsigned int XBMCController$appleModKeyToXbmcModKey(XBMCController* self, SEL _cmd, unsigned int appleModifier) +static unsigned int KodiController$appleModKeyToXbmcModKey(KodiController* self, SEL _cmd, unsigned int appleModifier) { unsigned int xbmcModifier = XBMCKMOD_NONE; // shift left @@ -759,7 +759,7 @@ static unsigned int XBMCController$appleModKeyToXbmcModKey(XBMCController* self, return xbmcModifier; } -static BOOL XBMCController$brEventAction(XBMCController* self, SEL _cmd, BREvent* event) +static BOOL KodiController$brEventAction(KodiController* self, SEL _cmd, BREvent* event) { //NSLog(@"%s", __PRETTY_FUNCTION__); @@ -877,13 +877,13 @@ static BOOL XBMCController$brEventAction(XBMCController* self, SEL _cmd, BREvent } else { - return XBMCController$brEventAction$Orig(self, _cmd, event); + return KodiController$brEventAction$Orig(self, _cmd, event); } } #pragma mark - #pragma mark private helper methods -static void XBMCController$startKeyPressTimer(XBMCController* self, SEL _cmd, int keyId) +static void KodiController$startKeyPressTimer(KodiController* self, SEL _cmd, int keyId) { NSNumber *number = [NSNumber numberWithInt:keyId]; NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSDate date], @"StartDate", @@ -907,7 +907,7 @@ static void XBMCController$startKeyPressTimer(XBMCController* self, SEL _cmd, in [self setKeyTimer:timer]; } -static void XBMCController$stopKeyPressTimer(XBMCController* self, SEL _cmd) +static void KodiController$stopKeyPressTimer(KodiController* self, SEL _cmd) { if([self keyTimer] != nil) { @@ -917,7 +917,7 @@ static void XBMCController$stopKeyPressTimer(XBMCController* self, SEL _cmd) } } -static void XBMCController$keyPressTimerCallback(XBMCController* self, SEL _cmd, NSTimer* theTimer) +static void KodiController$keyPressTimerCallback(KodiController* self, SEL _cmd, NSTimer* theTimer) { //if queue is empty - skip this timer event //for letting it process @@ -933,12 +933,12 @@ static void XBMCController$keyPressTimerCallback(XBMCController* self, SEL _cmd, [self setUserEvent:keyId withHoldTime:(unsigned int)holdTime]; } -static void XBMCController$observeDefaultCenterStuff(XBMCController* self, SEL _cmd, NSNotification * notification) +static void KodiController$observeDefaultCenterStuff(KodiController* self, SEL _cmd, NSNotification * notification) { //NSLog(@"default: %@", [notification name]); if ([notification name] == UIApplicationDidReceiveMemoryWarningNotification) - NSLog(@"XBMC: %@", [notification name]); + NSLog(@"Kodi: %@", [notification name]); //if ([notification name] == kBRScreenSaverActivated) // [m_glView stopAnimation]; @@ -947,7 +947,7 @@ static void XBMCController$observeDefaultCenterStuff(XBMCController* self, SEL _ // [m_glView startAnimation]; } -static void XBMCController$disableSystemSleep(XBMCController* self, SEL _cmd) +static void KodiController$disableSystemSleep(KodiController* self, SEL _cmd) { Class ATVSettingsFacadeCls = objc_getClass("ATVSettingsFacade"); XBMCSettingsFacade *single = (XBMCSettingsFacade *)[ATVSettingsFacadeCls singleton]; @@ -959,7 +959,7 @@ static void XBMCController$disableSystemSleep(XBMCController* self, SEL _cmd) [single flushDiskChanges]; } -static void XBMCController$enableSystemSleep(XBMCController* self, SEL _cmd) +static void KodiController$enableSystemSleep(KodiController* self, SEL _cmd) { Class ATVSettingsFacadeCls = objc_getClass("ATVSettingsFacade"); int timeoutInt = [[self systemSleepTimeout] intValue]; @@ -967,7 +967,7 @@ static void XBMCController$enableSystemSleep(XBMCController* self, SEL _cmd) [[ATVSettingsFacadeCls singleton] flushDiskChanges]; } -static void XBMCController$disableScreenSaver(XBMCController* self, SEL _cmd) +static void KodiController$disableScreenSaver(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); //store screen saver state and disable it @@ -984,7 +984,7 @@ static void XBMCController$disableScreenSaver(XBMCController* self, SEL _cmd) // breaks in 4.2.1 [[BRBackgroundTaskManager singleton] holdOffBackgroundTasks]; } -static void XBMCController$enableScreenSaver(XBMCController* self, SEL _cmd) +static void KodiController$enableScreenSaver(KodiController* self, SEL _cmd) { //NSLog(@"%s", __PRETTY_FUNCTION__); //reset screen saver to user settings @@ -1287,7 +1287,7 @@ static void XBMCController$enableScreenSaver(XBMCController* self, SEL _cmd) }*/ //-------------------------------------------------------------- -static void XBMCController$pauseAnimation(XBMCController* self, SEL _cmd) +static void KodiController$pauseAnimation(KodiController* self, SEL _cmd) { XBMC_Event newEvent; memset(&newEvent, 0, sizeof(XBMC_Event)); @@ -1300,7 +1300,7 @@ static void XBMCController$pauseAnimation(XBMCController* self, SEL _cmd) [[self glView] pauseAnimation]; } //-------------------------------------------------------------- -static void XBMCController$resumeAnimation(XBMCController* self, SEL _cmd) +static void KodiController$resumeAnimation(KodiController* self, SEL _cmd) { NSLog(@"%s", __PRETTY_FUNCTION__); @@ -1314,26 +1314,26 @@ static void XBMCController$resumeAnimation(XBMCController* self, SEL _cmd) [[self glView] resumeAnimation]; } //-------------------------------------------------------------- -static void XBMCController$startAnimation(XBMCController* self, SEL _cmd) +static void KodiController$startAnimation(KodiController* self, SEL _cmd) { NSLog(@"%s", __PRETTY_FUNCTION__); [[self glView] startAnimation]; } //-------------------------------------------------------------- -static void XBMCController$stopAnimation(XBMCController* self, SEL _cmd) +static void KodiController$stopAnimation(KodiController* self, SEL _cmd) { NSLog(@"%s", __PRETTY_FUNCTION__); [[self glView] stopAnimation]; } //-------------------------------------------------------------- -static bool XBMCController$changeScreen(XBMCController* self, SEL _cmd, unsigned int screenIdx, UIScreenMode * mode) +static bool KodiController$changeScreen(KodiController* self, SEL _cmd, unsigned int screenIdx, UIScreenMode * mode) { return [[IOSScreenManager sharedInstance] changeScreen: screenIdx withMode: mode]; } //-------------------------------------------------------------- -static void XBMCController$activateScreen(XBMCController* self, SEL _cmd, UIScreen * screen, UIInterfaceOrientation newOrientation) +static void KodiController$activateScreen(KodiController* self, SEL _cmd, UIScreen * screen, UIInterfaceOrientation newOrientation) { } @@ -1348,61 +1348,61 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() char _typeEncoding[1024]; unsigned int i = 0; - // subclass BRController into XBMCController - Class XBMCControllerCls = objc_allocateClassPair(objc_getClass("BRController"), "XBMCController", 0); + // subclass BRController into KodiController + Class KodiControllerCls = objc_allocateClassPair(objc_getClass("BRController"), "KodiController", 0); // add our custom methods which are not part of the baseclass - // XBMCController::keyTimer - class_addMethod(XBMCControllerCls, @selector(keyTimer), (IMP)&XBMCController$keyTimer, "@@:"); - // XBMCController::setKeyTimer - class_addMethod(XBMCControllerCls, @selector(setKeyTimer:), (IMP)&XBMCController$setKeyTimer, "v@:@"); - // XBMCController::glView - class_addMethod(XBMCControllerCls, @selector(glView), (IMP)&XBMCController$glView, "@@:"); - // XBMCController::setGlView - class_addMethod(XBMCControllerCls, @selector(setGlView:), (IMP)&XBMCController$setGlView, "v@:@"); - // XBMCController::systemScreenSaverTimeout - class_addMethod(XBMCControllerCls, @selector(systemScreenSaverTimeout), (IMP)&XBMCController$systemScreenSaverTimeout, "@@:"); - // XBMCController::setSystemScreenSaverTimeout - class_addMethod(XBMCControllerCls, @selector(setSystemScreenSaverTimeout:), (IMP)&XBMCController$setSystemScreenSaverTimeout, "v@:@"); - // XBMCController::systemSleepTimeout - class_addMethod(XBMCControllerCls, @selector(systemSleepTimeout), (IMP)&XBMCController$systemSleepTimeout, "@@:"); - // XBMCController::setSystemSleepTimeout - class_addMethod(XBMCControllerCls, @selector(setSystemSleepTimeout:), (IMP)&XBMCController$setSystemSleepTimeout, "v@:@"); - // XBMCController::applicationDidExit - class_addMethod(XBMCControllerCls, @selector(applicationDidExit), (IMP)&XBMCController$applicationDidExit, "v@:"); - // XBMCController::initDisplayLink - class_addMethod(XBMCControllerCls, @selector(initDisplayLink), (IMP)&XBMCController$initDisplayLink, "v@:"); - // XBMCController::deinitDisplayLink - class_addMethod(XBMCControllerCls, @selector(deinitDisplayLink), (IMP)&XBMCController$deinitDisplayLink, "v@:"); - // XBMCController::getDisplayLinkFPS - class_addMethod(XBMCControllerCls, @selector(getDisplayLinkFPS), (IMP)&XBMCController$getDisplayLinkFPS, "d@:"); - // XBMCController::setFramebuffer - class_addMethod(XBMCControllerCls, @selector(setFramebuffer), (IMP)&XBMCController$setFramebuffer, "v@:"); - // XBMCController::presentFramebuffer - class_addMethod(XBMCControllerCls, @selector(presentFramebuffer), (IMP)&XBMCController$presentFramebuffer, "B@:"); - // XBMCController::setUserEvent - class_addMethod(XBMCControllerCls, @selector(setUserEvent:withHoldTime:), (IMP)&XBMCController$setUserEvent, "v@:iI"); - // XBMCController::appleModKeyToXbmcModKey - class_addMethod(XBMCControllerCls, @selector(appleModKeyToXbmcModKey:), (IMP)&XBMCController$appleModKeyToXbmcModKey, "I@:I"); - // XBMCController::startKeyPressTimer - class_addMethod(XBMCControllerCls, @selector(startKeyPressTimer:), (IMP)&XBMCController$startKeyPressTimer, "v@:i"); - // XBMCController::stopKeyPressTimer - class_addMethod(XBMCControllerCls, @selector(stopKeyPressTimer), (IMP)&XBMCController$stopKeyPressTimer, "v@:"); - // XBMCController::disableSystemSleep - class_addMethod(XBMCControllerCls, @selector(disableSystemSleep), (IMP)&XBMCController$disableSystemSleep, "v@:"); - // XBMCController__enableSystemSleep - class_addMethod(XBMCControllerCls, @selector(enableSystemSleep), (IMP)&XBMCController$enableSystemSleep, "v@:"); - // XBMCController::disableScreenSaver - class_addMethod(XBMCControllerCls, @selector(disableScreenSaver), (IMP)&XBMCController$disableScreenSaver, "v@:"); - // XBMCController::enableScreenSaver - class_addMethod(XBMCControllerCls, @selector(enableScreenSaver), (IMP)&XBMCController$enableScreenSaver, "v@:"); - // XBMCController::pauseAnimation - class_addMethod(XBMCControllerCls, @selector(pauseAnimation), (IMP)&XBMCController$pauseAnimation, "v@:"); - // XBMCController::resumeAnimation - class_addMethod(XBMCControllerCls, @selector(resumeAnimation), (IMP)&XBMCController$resumeAnimation, "v@:"); - // XBMCController::startAnimation - class_addMethod(XBMCControllerCls, @selector(startAnimation), (IMP)&XBMCController$startAnimation, "v@:"); - // XBMCController::stopAnimation - class_addMethod(XBMCControllerCls, @selector(stopAnimation), (IMP)&XBMCController$stopAnimation, "v@:"); + // KodiController::keyTimer + class_addMethod(KodiControllerCls, @selector(keyTimer), (IMP)&KodiController$keyTimer, "@@:"); + // KodiController::setKeyTimer + class_addMethod(KodiControllerCls, @selector(setKeyTimer:), (IMP)&KodiController$setKeyTimer, "v@:@"); + // KodiController::glView + class_addMethod(KodiControllerCls, @selector(glView), (IMP)&KodiController$glView, "@@:"); + // KodiController::setGlView + class_addMethod(KodiControllerCls, @selector(setGlView:), (IMP)&KodiController$setGlView, "v@:@"); + // KodiController::systemScreenSaverTimeout + class_addMethod(KodiControllerCls, @selector(systemScreenSaverTimeout), (IMP)&KodiController$systemScreenSaverTimeout, "@@:"); + // KodiController::setSystemScreenSaverTimeout + class_addMethod(KodiControllerCls, @selector(setSystemScreenSaverTimeout:), (IMP)&KodiController$setSystemScreenSaverTimeout, "v@:@"); + // KodiController::systemSleepTimeout + class_addMethod(KodiControllerCls, @selector(systemSleepTimeout), (IMP)&KodiController$systemSleepTimeout, "@@:"); + // KodiController::setSystemSleepTimeout + class_addMethod(KodiControllerCls, @selector(setSystemSleepTimeout:), (IMP)&KodiController$setSystemSleepTimeout, "v@:@"); + // KodiController::applicationDidExit + class_addMethod(KodiControllerCls, @selector(applicationDidExit), (IMP)&KodiController$applicationDidExit, "v@:"); + // KodiController::initDisplayLink + class_addMethod(KodiControllerCls, @selector(initDisplayLink), (IMP)&KodiController$initDisplayLink, "v@:"); + // KodiController::deinitDisplayLink + class_addMethod(KodiControllerCls, @selector(deinitDisplayLink), (IMP)&KodiController$deinitDisplayLink, "v@:"); + // KodiController::getDisplayLinkFPS + class_addMethod(KodiControllerCls, @selector(getDisplayLinkFPS), (IMP)&KodiController$getDisplayLinkFPS, "d@:"); + // KodiController::setFramebuffer + class_addMethod(KodiControllerCls, @selector(setFramebuffer), (IMP)&KodiController$setFramebuffer, "v@:"); + // KodiController::presentFramebuffer + class_addMethod(KodiControllerCls, @selector(presentFramebuffer), (IMP)&KodiController$presentFramebuffer, "B@:"); + // KodiController::setUserEvent + class_addMethod(KodiControllerCls, @selector(setUserEvent:withHoldTime:), (IMP)&KodiController$setUserEvent, "v@:iI"); + // KodiController::appleModKeyToXbmcModKey + class_addMethod(KodiControllerCls, @selector(appleModKeyToXbmcModKey:), (IMP)&KodiController$appleModKeyToXbmcModKey, "I@:I"); + // KodiController::startKeyPressTimer + class_addMethod(KodiControllerCls, @selector(startKeyPressTimer:), (IMP)&KodiController$startKeyPressTimer, "v@:i"); + // KodiController::stopKeyPressTimer + class_addMethod(KodiControllerCls, @selector(stopKeyPressTimer), (IMP)&KodiController$stopKeyPressTimer, "v@:"); + // KodiController::disableSystemSleep + class_addMethod(KodiControllerCls, @selector(disableSystemSleep), (IMP)&KodiController$disableSystemSleep, "v@:"); + // KodiController__enableSystemSleep + class_addMethod(KodiControllerCls, @selector(enableSystemSleep), (IMP)&KodiController$enableSystemSleep, "v@:"); + // KodiController::disableScreenSaver + class_addMethod(KodiControllerCls, @selector(disableScreenSaver), (IMP)&KodiController$disableScreenSaver, "v@:"); + // KodiController::enableScreenSaver + class_addMethod(KodiControllerCls, @selector(enableScreenSaver), (IMP)&KodiController$enableScreenSaver, "v@:"); + // KodiController::pauseAnimation + class_addMethod(KodiControllerCls, @selector(pauseAnimation), (IMP)&KodiController$pauseAnimation, "v@:"); + // KodiController::resumeAnimation + class_addMethod(KodiControllerCls, @selector(resumeAnimation), (IMP)&KodiController$resumeAnimation, "v@:"); + // KodiController::startAnimation + class_addMethod(KodiControllerCls, @selector(startAnimation), (IMP)&KodiController$startAnimation, "v@:"); + // KodiController::stopAnimation + class_addMethod(KodiControllerCls, @selector(stopAnimation), (IMP)&KodiController$stopAnimation, "v@:"); i = 0; memcpy(_typeEncoding + i, @encode(CGSize), strlen(@encode(CGSize))); @@ -1412,8 +1412,8 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() _typeEncoding[i] = ':'; i += 1; _typeEncoding[i] = '\0'; - // XBMCController::getScreenSize - class_addMethod(XBMCControllerCls, @selector(getScreenSize), (IMP)&XBMCController$getScreenSize, _typeEncoding); + // KodiController::getScreenSize + class_addMethod(KodiControllerCls, @selector(getScreenSize), (IMP)&KodiController$getScreenSize, _typeEncoding); i = 0; _typeEncoding[i] = 'v'; @@ -1425,8 +1425,8 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() memcpy(_typeEncoding + i, @encode(XBMCKey), strlen(@encode(XBMCKey))); i += strlen(@encode(XBMCKey)); _typeEncoding[i] = '\0'; - // XBMCController::sendKey - class_addMethod(XBMCControllerCls, @selector(sendKey:), (IMP)&XBMCController$sendKey, _typeEncoding); + // KodiController::sendKey + class_addMethod(KodiControllerCls, @selector(sendKey:), (IMP)&KodiController$sendKey, _typeEncoding); i = 0; _typeEncoding[i] = 'v'; @@ -1447,8 +1447,8 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() _typeEncoding[i + 1] = 'i'; i += 2; _typeEncoding[i] = '\0'; - // XBMCController::ATVClientEventFromBREvent - class_addMethod(XBMCControllerCls, @selector(ATVClientEventFromBREvent:Repeatable:ButtonState:Result:), (IMP)&XBMCController$ATVClientEventFromBREvent, _typeEncoding); + // KodiController::ATVClientEventFromBREvent + class_addMethod(KodiControllerCls, @selector(ATVClientEventFromBREvent:Repeatable:ButtonState:Result:), (IMP)&KodiController$ATVClientEventFromBREvent, _typeEncoding); i = 0; _typeEncoding[i] = 'v'; @@ -1460,8 +1460,8 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() memcpy(_typeEncoding + i, @encode(NSTimer*), strlen(@encode(NSTimer*))); i += strlen(@encode(NSTimer*)); _typeEncoding[i] = '\0'; - // XBMCController::keyPressTimerCallback - class_addMethod(XBMCControllerCls, @selector(keyPressTimerCallback:), (IMP)&XBMCController$keyPressTimerCallback, _typeEncoding); + // KodiController::keyPressTimerCallback + class_addMethod(KodiControllerCls, @selector(keyPressTimerCallback:), (IMP)&KodiController$keyPressTimerCallback, _typeEncoding); i = 0; _typeEncoding[i] = 'v'; @@ -1473,8 +1473,8 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() memcpy(_typeEncoding + i, @encode(NSNotification *), strlen(@encode(NSNotification *))); i += strlen(@encode(NSNotification *)); _typeEncoding[i] = '\0'; - // XBMCController:observeDefaultCenterStuff - class_addMethod(XBMCControllerCls, @selector(observeDefaultCenterStuff:), (IMP)&XBMCController$observeDefaultCenterStuff, _typeEncoding); + // KodiController:observeDefaultCenterStuff + class_addMethod(KodiControllerCls, @selector(observeDefaultCenterStuff:), (IMP)&KodiController$observeDefaultCenterStuff, _typeEncoding); i = 0; _typeEncoding[i] = 'B'; @@ -1488,8 +1488,8 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() memcpy(_typeEncoding + i, @encode(UIScreenMode *), strlen(@encode(UIScreenMode *))); i += strlen(@encode(UIScreenMode *)); _typeEncoding[i] = '\0'; - // XBMCController::changeScreen - class_addMethod(XBMCControllerCls, @selector(changeScreen:withMode:), (IMP)&XBMCController$changeScreen, _typeEncoding); + // KodiController::changeScreen + class_addMethod(KodiControllerCls, @selector(changeScreen:withMode:), (IMP)&KodiController$changeScreen, _typeEncoding); i = 0; _typeEncoding[i] = 'v'; @@ -1503,25 +1503,25 @@ static __attribute__((constructor)) void initControllerRuntimeClasses() _typeEncoding[i] = 'I'; i += 1; _typeEncoding[i] = '\0'; - // XBMCController::activateScreen$ - class_addMethod(XBMCControllerCls, @selector(activateScreen:withOrientation:), (IMP)&XBMCController$activateScreen, _typeEncoding); + // KodiController::activateScreen$ + class_addMethod(KodiControllerCls, @selector(activateScreen:withOrientation:), (IMP)&KodiController$activateScreen, _typeEncoding); // and hook up our methods (implementation of the base class methods) - // XBMCController::brEventAction - MSHookMessageEx(XBMCControllerCls, @selector(brEventAction:), (IMP)&XBMCController$brEventAction, (IMP*)&XBMCController$brEventAction$Orig); - // XBMCController::init - MSHookMessageEx(XBMCControllerCls, @selector(init), (IMP)&XBMCController$init, (IMP*)&XBMCController$init$Orig); - // XBMCController::dealloc - MSHookMessageEx(XBMCControllerCls, @selector(dealloc), (IMP)&XBMCController$dealloc, (IMP*)&XBMCController$dealloc$Orig); - // XBMCController::controlWasActivated - MSHookMessageEx(XBMCControllerCls, @selector(controlWasActivated), (IMP)&XBMCController$controlWasActivated, (IMP*)&XBMCController$controlWasActivated$Orig); - // XBMCController::controlWasDeactivated - MSHookMessageEx(XBMCControllerCls, @selector(controlWasDeactivated), (IMP)&XBMCController$controlWasDeactivated, (IMP*)&XBMCController$controlWasDeactivated$Orig); - // XBMCController::recreateOnReselect - MSHookMessageEx(XBMCControllerCls, @selector(recreateOnReselect), (IMP)&XBMCController$recreateOnReselect, nil); + // KodiController::brEventAction + MSHookMessageEx(KodiControllerCls, @selector(brEventAction:), (IMP)&KodiController$brEventAction, (IMP*)&KodiController$brEventAction$Orig); + // KodiController::init + MSHookMessageEx(KodiControllerCls, @selector(init), (IMP)&KodiController$init, (IMP*)&KodiController$init$Orig); + // KodiController::dealloc + MSHookMessageEx(KodiControllerCls, @selector(dealloc), (IMP)&KodiController$dealloc, (IMP*)&KodiController$dealloc$Orig); + // KodiController::controlWasActivated + MSHookMessageEx(KodiControllerCls, @selector(controlWasActivated), (IMP)&KodiController$controlWasActivated, (IMP*)&KodiController$controlWasActivated$Orig); + // KodiController::controlWasDeactivated + MSHookMessageEx(KodiControllerCls, @selector(controlWasDeactivated), (IMP)&KodiController$controlWasDeactivated, (IMP*)&KodiController$controlWasDeactivated$Orig); + // KodiController::recreateOnReselect + MSHookMessageEx(KodiControllerCls, @selector(recreateOnReselect), (IMP)&KodiController$recreateOnReselect, nil); // and register the class to the runtime - objc_registerClassPair(XBMCControllerCls); + objc_registerClassPair(KodiControllerCls); // save this as static for referencing it in multiple methods BRWindowCls = objc_getClass("BRWindow"); diff --git a/xbmc/osx/atv2/XBMCATV2-Info.plist b/xbmc/osx/atv2/XBMCATV2-Info.plist.in index 3105d27fa5..6d8d60583e 100644 --- a/xbmc/osx/atv2/XBMCATV2-Info.plist +++ b/xbmc/osx/atv2/XBMCATV2-Info.plist.in @@ -3,15 +3,15 @@ <plist version="1.0"> <dict> <key>CFBundleName</key> - <string>XBMC</string> + <string>@APP_NAME@</string> <key>DTXcode</key> <string>0324</string> <key>FRApplianceDataSourceType</key> <string>All</string> <key>CFBundleExecutable</key> - <string>XBMC</string> + <string>@APP_NAME@</string> <key>CFBundleIdentifier</key> - <string>com.apple.frontrow.appliance.xbmc</string> + <string>com.apple.frontrow.appliance.@APP_NAME_LC@</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> @@ -39,8 +39,8 @@ <key>MinimumOSVersion</key> <string>4.1</string> <key>NSPrincipalClass</key> - <string>XBMCAppliance</string> + <string>KodiAppliance</string> <key>FRApplianceName</key> - <string>XBMC</string> + <string>@APP_NAME@</string> </dict> </plist> diff --git a/xbmc/osx/atv2/xbmcclient.h b/xbmc/osx/atv2/kodiclient.h index 93dbba507d..93dbba507d 100644 --- a/xbmc/osx/atv2/xbmcclient.h +++ b/xbmc/osx/atv2/kodiclient.h diff --git a/xbmc/osx/atv2/xbmcclientwrapper.h b/xbmc/osx/atv2/kodiclientwrapper.h index 792cc5985b..57e06ed43c 100644 --- a/xbmc/osx/atv2/xbmcclientwrapper.h +++ b/xbmc/osx/atv2/kodiclientwrapper.h @@ -58,8 +58,8 @@ typedef enum{ ATV_INVALID_BUTTON } eATVClientEvent; -@interface XBMCClientWrapper : NSObject{ - struct XBMCClientWrapperImpl* mp_impl; +@interface KodiClientWrapper : NSObject{ + struct KodiClientWrapperImpl* mp_impl; } - (id) initWithUniversalMode:(bool) f_yes_no serverAddress:(NSString*) fp_server; - (void) setUniversalModeTimeout:(double) f_timeout; diff --git a/xbmc/osx/atv2/xbmcclientwrapper.mm b/xbmc/osx/atv2/kodiclientwrapper.mm index 12e5b4ed46..bf053a679a 100644 --- a/xbmc/osx/atv2/xbmcclientwrapper.mm +++ b/xbmc/osx/atv2/kodiclientwrapper.mm @@ -29,9 +29,9 @@ #include <sys/sysctl.h> #import <Foundation/Foundation.h> -#include "xbmcclient.h" +#include "kodiclient.h" #include "XBMCDebugHelpers.h" -#include "xbmcclientwrapper.h" +#include "KodiClientWrapper.h" //helper class for easy EventSequence handling class XBMCClientEventSequence{ @@ -83,7 +83,7 @@ private: typedef std::map<eATVClientEvent, CPacketBUTTON*> tEventMap; typedef std::map<XBMCClientEventSequence, CPacketBUTTON*> tSequenceMap; -class XBMCClientWrapperImpl{ +class KodiClientWrapperImpl{ tEventMap m_event_map; tSequenceMap m_sequence_map; @@ -103,15 +103,15 @@ class XBMCClientWrapperImpl{ bool isStartToken(eATVClientEvent f_event); static void timerCallBack (CFRunLoopTimerRef timer, void *info); public: - XBMCClientWrapperImpl(bool f_universal_mode, const std::string& fcr_address = "localhost"); - ~XBMCClientWrapperImpl(); + KodiClientWrapperImpl(bool f_universal_mode, const std::string& fcr_address = "localhost"); + ~KodiClientWrapperImpl(); void setUniversalModeTimeout(double f_timeout){ m_sequence_timeout = f_timeout; } void handleEvent(eATVClientEvent f_event); }; -void XBMCClientWrapperImpl::timerCallBack (CFRunLoopTimerRef timer, void *info) +void KodiClientWrapperImpl::timerCallBack (CFRunLoopTimerRef timer, void *info) { if (!info) { @@ -119,12 +119,12 @@ void XBMCClientWrapperImpl::timerCallBack (CFRunLoopTimerRef timer, void *info) return; } - XBMCClientWrapperImpl *p_impl = (XBMCClientWrapperImpl *)info; + KodiClientWrapperImpl *p_impl = (KodiClientWrapperImpl *)info; p_impl->sendSequence(); p_impl->resetTimer(); } -void XBMCClientWrapperImpl::resetTimer(){ +void KodiClientWrapperImpl::resetTimer(){ if (m_timer) { CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), m_timer, kCFRunLoopCommonModes); @@ -134,7 +134,7 @@ void XBMCClientWrapperImpl::resetTimer(){ } } -void XBMCClientWrapperImpl::restartTimer(){ +void KodiClientWrapperImpl::restartTimer(){ if (m_timer) resetTimer(); @@ -143,19 +143,19 @@ void XBMCClientWrapperImpl::restartTimer(){ CFRunLoopAddTimer(CFRunLoopGetCurrent(), m_timer, kCFRunLoopCommonModes); } -XBMCClientWrapperImpl::XBMCClientWrapperImpl(bool f_universal_mode, const std::string& fcr_address): m_address(fcr_address), m_universal_mode(f_universal_mode), m_timer(0), m_sequence_timeout(0.5){ +KodiClientWrapperImpl::KodiClientWrapperImpl(bool f_universal_mode, const std::string& fcr_address): m_address(fcr_address), m_universal_mode(f_universal_mode), m_timer(0), m_sequence_timeout(0.5){ //PRINT_SIGNATURE(); populateEventMap(); if (m_universal_mode) { - //DLOG(@"XBMCClientWrapperImpl started in universal mode sending to address %s", fcr_address.c_str()); + //DLOG(@"KodiClientWrapperImpl started in universal mode sending to address %s", fcr_address.c_str()); populateSequenceMap(); } /* else { - DLOG(@"XBMCClientWrapperImpl started in normal mode sending to address %s", fcr_address.c_str()); + DLOG(@"KodiClientWrapperImpl started in normal mode sending to address %s", fcr_address.c_str()); } */ @@ -168,20 +168,20 @@ XBMCClientWrapperImpl::XBMCClientWrapperImpl(bool f_universal_mode, const std::s } } -XBMCClientWrapperImpl::~XBMCClientWrapperImpl(){ +KodiClientWrapperImpl::~KodiClientWrapperImpl(){ //PRINT_SIGNATURE(); resetTimer(); shutdown(m_socket, SHUT_RDWR); } -bool XBMCClientWrapperImpl::isStartToken(eATVClientEvent f_event){ +bool KodiClientWrapperImpl::isStartToken(eATVClientEvent f_event){ return f_event==ATV_BUTTON_MENU_H; } -void XBMCClientWrapperImpl::sendButton(eATVClientEvent f_event){ +void KodiClientWrapperImpl::sendButton(eATVClientEvent f_event){ tEventMap::iterator it = m_event_map.find(f_event); if(it == m_event_map.end()){ - ELOG(@"XBMCClientWrapperImpl::sendButton: No mapping defined for button %i", f_event); + ELOG(@"KodiClientWrapperImpl::sendButton: No mapping defined for button %i", f_event); return; } CPacketBUTTON& packet = *(it->second); @@ -189,20 +189,20 @@ void XBMCClientWrapperImpl::sendButton(eATVClientEvent f_event){ packet.Send(m_socket, addr); } -void XBMCClientWrapperImpl::sendSequence(){ +void KodiClientWrapperImpl::sendSequence(){ tSequenceMap::const_iterator it = m_sequence_map.find(m_sequence); if(it != m_sequence_map.end()){ CPacketBUTTON& packet = *(it->second); CAddress addr(m_address.c_str()); packet.Send(m_socket, addr); - DLOG(@"XBMCClientWrapperImpl::sendSequence: sent sequence %s as button %i", m_sequence.str().c_str(), it->second->GetButtonCode()); + DLOG(@"KodiClientWrapperImpl::sendSequence: sent sequence %s as button %i", m_sequence.str().c_str(), it->second->GetButtonCode()); } else { - ELOG(@"XBMCClientWrapperImpl::sendSequence: No mapping defined for sequence %s", m_sequence.str().c_str()); + ELOG(@"KodiClientWrapperImpl::sendSequence: No mapping defined for sequence %s", m_sequence.str().c_str()); } m_sequence.clear(); } -void XBMCClientWrapperImpl::handleEvent(eATVClientEvent f_event){ +void KodiClientWrapperImpl::handleEvent(eATVClientEvent f_event){ if(!m_universal_mode){ sendButton(f_event); } else { @@ -230,7 +230,7 @@ void XBMCClientWrapperImpl::handleEvent(eATVClientEvent f_event){ } } -void XBMCClientWrapperImpl::populateEventMap(){ +void KodiClientWrapperImpl::populateEventMap(){ tEventMap& lr_map = m_event_map; lr_map.insert(std::make_pair(ATV_BUTTON_PLAY, new CPacketBUTTON(5, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -270,7 +270,7 @@ void XBMCClientWrapperImpl::populateEventMap(){ lr_map.insert(std::make_pair(ATV_GESTURE_SWIPE_DOWN, new CPacketBUTTON(83, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); } -void XBMCClientWrapperImpl::populateSequenceMap(){ +void KodiClientWrapperImpl::populateSequenceMap(){ XBMCClientEventSequence sequence_prefix; sequence_prefix << ATV_BUTTON_MENU_H; m_sequence_map.insert(std::make_pair(sequence_prefix, new CPacketBUTTON(8, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -327,7 +327,7 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_MENU, new CPacketBUTTON(55, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); } -@implementation XBMCClientWrapper +@implementation KodiClientWrapper - (id) init { return [self initWithUniversalMode:false serverAddress:@"localhost"]; } @@ -335,7 +335,7 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ //PRINT_SIGNATURE(); if( ![super init] ) return nil; - mp_impl = new XBMCClientWrapperImpl(f_yes_no, [fp_server UTF8String]); + mp_impl = new KodiClientWrapperImpl(f_yes_no, [fp_server UTF8String]); return self; } diff --git a/xbmc/osx/ios/Default-568h@2x.png b/xbmc/osx/ios/Default-568h@2x.png Binary files differindex 88f2a95d78..41b9a6d37e 100644 --- a/xbmc/osx/ios/Default-568h@2x.png +++ b/xbmc/osx/ios/Default-568h@2x.png diff --git a/xbmc/osx/ios/Default-667h@2x.png b/xbmc/osx/ios/Default-667h@2x.png Binary files differnew file mode 100644 index 0000000000..2c3dad3ec5 --- /dev/null +++ b/xbmc/osx/ios/Default-667h@2x.png diff --git a/xbmc/osx/ios/Default-736h@3x.png b/xbmc/osx/ios/Default-736h@3x.png Binary files differnew file mode 100644 index 0000000000..07b5970e8e --- /dev/null +++ b/xbmc/osx/ios/Default-736h@3x.png diff --git a/xbmc/osx/ios/Default-Landscape-736h@3x.png b/xbmc/osx/ios/Default-Landscape-736h@3x.png Binary files differnew file mode 100644 index 0000000000..62cecfff04 --- /dev/null +++ b/xbmc/osx/ios/Default-Landscape-736h@3x.png diff --git a/xbmc/osx/ios/IOSKeyboardView.mm b/xbmc/osx/ios/IOSKeyboardView.mm index 2553981e7d..7b730e62c4 100644 --- a/xbmc/osx/ios/IOSKeyboardView.mm +++ b/xbmc/osx/ios/IOSKeyboardView.mm @@ -132,6 +132,10 @@ static CEvent keyboardFinishedEvent; -(void)keyboardWillShow:(NSNotification *) notification{ NSDictionary* info = [notification userInfo]; CGRect kbRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; +#if !__IPHONE_8_0 + if (CDarwinUtils::GetIOSVersion() >= 8.0) + kbRect = [self convertRect:kbRect fromView:nil]; +#endif LOG(@"keyboardWillShow: keyboard frame: %@", NSStringFromCGRect(kbRect)); _kbRect = kbRect; [self setNeedsLayout]; diff --git a/xbmc/osx/ios/XBMCController.mm b/xbmc/osx/ios/XBMCController.mm index f24c03d20d..9b6c943049 100644 --- a/xbmc/osx/ios/XBMCController.mm +++ b/xbmc/osx/ios/XBMCController.mm @@ -674,7 +674,9 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL; //-------------------------------------------------------------- - (IBAction)handleSingleFingerSingleTap:(UIGestureRecognizer *)sender { - if( [m_glView isXBMCAlive] )//NO GESTURES BEFORE WE ARE UP AND RUNNING + //Allow the tap gesture during init + //(for allowing the user to tap away any messagboxes during init) + if( [m_glView isReadyToRun] ) { CGPoint point = [sender locationOfTouch:0 inView:m_glView]; point.x *= screenScale; diff --git a/xbmc/osx/ios/XBMCIOS-Info.plist b/xbmc/osx/ios/XBMCIOS-Info.plist.in index 6ac9c84bf6..a7909d83ee 100644 --- a/xbmc/osx/ios/XBMCIOS-Info.plist +++ b/xbmc/osx/ios/XBMCIOS-Info.plist.in @@ -9,7 +9,7 @@ <key>CFBundleDocumentTypes</key> <array/> <key>CFBundleExecutable</key> - <string>XBMC</string> + <string>@APP_NAME@</string> <key>CFBundleIcons</key> <dict> <key>CFBundlePrimaryIcon</key> @@ -40,11 +40,11 @@ </dict> </dict> <key>CFBundleIdentifier</key> - <string>org.xbmc.xbmc-ios</string> + <string>org.xbmc.@APP_NAME_LC@-ios</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> - <string>XBMC</string> + <string>@APP_NAME@</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> @@ -82,5 +82,48 @@ </array> <key>UIViewControllerBasedStatusBarAppearance</key> <false/> + <key>UILaunchImages</key> + <array> + <dict> + <key>UILaunchImageMinimumOSVersion</key> + <string>8.0</string> + <key>UILaunchImageName</key> + <string>Default-667h</string> + <key>UILaunchImageOrientation</key> + <string>Portrait</string> + <key>UILaunchImageSize</key> + <string>{375, 667}</string> + </dict> + <dict> + <key>UILaunchImageMinimumOSVersion</key> + <string>8.0</string> + <key>UILaunchImageName</key> + <string>Default-736h</string> + <key>UILaunchImageOrientation</key> + <string>Portrait</string> + <key>UILaunchImageSize</key> + <string>{414, 736}</string> + </dict> + <dict> + <key>UILaunchImageMinimumOSVersion</key> + <string>8.0</string> + <key>UILaunchImageName</key> + <string>Default-Landscape-736h</string> + <key>UILaunchImageOrientation</key> + <string>Landscape</string> + <key>UILaunchImageSize</key> + <string>{414, 736}</string> + </dict> + <dict> + <key>UILaunchImageMinimumOSVersion</key> + <string>8.0</string> + <key>UILaunchImageName</key> + <string>Default-568h</string> + <key>UILaunchImageOrientation</key> + <string>Portrait</string> + <key>UILaunchImageSize</key> + <string>{320, 568}</string> + </dict> + </array> </dict> </plist> diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp index b02535af5c..4941ae644a 100644 --- a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp +++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp @@ -101,6 +101,8 @@ bool CPeripheralBusCEC::PerformDeviceScan(PeripheralScanResults &results) break; case ADAPTERTYPE_RPI: result.m_mappedBusType = PERIPHERAL_BUS_RPI; + /** the Pi's adapter cannot be removed, no need to rescan */ + m_bNeedsPolling = false; break; default: break; diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 9907ba264b..b4b5d2f044 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1185,7 +1185,7 @@ int CPeripheralCecAdapter::CecLogMessage(void *cbParam, const cec_log_message me break; } - if (iLevel >= CEC_LOG_NOTICE || (iLevel >= 0 && g_advancedSettings.CanLogComponent(LOGCEC))) + if (iLevel >= CEC_LOG_NOTICE || (iLevel >= 0 && CLog::IsLogLevelLogged(LOGDEBUG) && g_advancedSettings.CanLogComponent(LOGCEC))) CLog::Log(iLevel, "%s - %s", __FUNCTION__, message.message); return 1; @@ -1268,8 +1268,8 @@ void CPeripheralCecAdapter::SetConfigurationFromLibCEC(const CEC::libcec_configu void CPeripheralCecAdapter::SetConfigurationFromSettings(void) { - // use the same client version as libCEC version - m_configuration.clientVersion = CEC_CLIENT_VERSION_CURRENT; + // client version matches the version of libCEC that we originally used the API from + m_configuration.clientVersion = CEC_CLIENT_VERSION_2_2_0; // device name 'XBMC' snprintf(m_configuration.strDeviceName, 13, "%s", GetSettingString("device_name").c_str()); @@ -1347,8 +1347,13 @@ void CPeripheralCecAdapter::SetConfigurationFromSettings(void) m_configuration.bPowerOffOnStandby = iStandbyAction == 13011 ? 1 : 0; m_configuration.bShutdownOnStandby = iStandbyAction == 13005 ? 1 : 0; - // double tap prevention timeout in ms +#if defined(CEC_DOUBLE_TAP_TIMEOUT_MS_OLD) + // double tap prevention timeout in ms. libCEC uses 50ms units for this in 2.2.0, so divide by 50 + m_configuration.iDoubleTapTimeout50Ms = GetSettingInt("double_tap_timeout_ms") / 50; +#else + // backwards compatibility. will be removed once the next major release of libCEC is out m_configuration.iDoubleTapTimeoutMs = GetSettingInt("double_tap_timeout_ms"); +#endif } void CPeripheralCecAdapter::ReadLogicalAddresses(const CStdString &strString, cec_logical_addresses &addresses) diff --git a/xbmc/pictures/Picture.cpp b/xbmc/pictures/Picture.cpp index 11dd8aee76..34ae62db7d 100644 --- a/xbmc/pictures/Picture.cpp +++ b/xbmc/pictures/Picture.cpp @@ -65,17 +65,11 @@ bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width } XFILE::CFile file; - if (file.OpenForWrite(thumbFile, true)) - { - file.Write(thumb, thumbsize); - file.Close(); - pImage->ReleaseThumbnailBuffer(); - delete pImage; - return true; - } + const bool ret = file.OpenForWrite(thumbFile, true) && file.Write(thumb, thumbsize) == thumbsize; pImage->ReleaseThumbnailBuffer(); delete pImage; - return false; + + return ret; } CThumbnailWriter::CThumbnailWriter(unsigned char* buffer, int width, int height, int stride, const CStdString& thumbFile) diff --git a/xbmc/playlists/PlayListM3U.cpp b/xbmc/playlists/PlayListM3U.cpp index a3c365a5f7..a086055dcd 100644 --- a/xbmc/playlists/PlayListM3U.cpp +++ b/xbmc/playlists/PlayListM3U.cpp @@ -200,14 +200,17 @@ void CPlayListM3U::Save(const std::string& strFileName) const return; } std::string strLine = StringUtils::Format("%s\n",M3U_START_MARKER); - file.Write(strLine.c_str(),strLine.size()); + if (file.Write(strLine.c_str(), strLine.size()) != strLine.size()) + return; // error + for (int i = 0; i < (int)m_vecItems.size(); ++i) { CFileItemPtr item = m_vecItems[i]; std::string strDescription=item->GetLabel(); g_charsetConverter.utf8ToStringCharset(strDescription); strLine = StringUtils::Format( "%s:%i,%s\n", M3U_INFO_MARKER, item->GetMusicInfoTag()->GetDuration() / 1000, strDescription.c_str() ); - file.Write(strLine.c_str(),strLine.size()); + if (file.Write(strLine.c_str(), strLine.size()) != strLine.size()) + return; // error if (item->m_lStartOffset != 0 || item->m_lEndOffset != 0) { strLine = StringUtils::Format("%s:%i,%i\n", M3U_OFFSET_MARKER, item->m_lStartOffset, item->m_lEndOffset); @@ -216,7 +219,8 @@ void CPlayListM3U::Save(const std::string& strFileName) const std::string strFileName = ResolveURL(item); g_charsetConverter.utf8ToStringCharset(strFileName); strLine = StringUtils::Format("%s\n",strFileName.c_str()); - file.Write(strLine.c_str(),strLine.size()); + if (file.Write(strLine.c_str(), strLine.size()) != strLine.size()) + return; // error } file.Close(); } diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index c60bb27c87..2b6018ba7a 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -129,9 +129,9 @@ void CPVRManager::OnSettingChanged(const CSetting *setting) if (settingId == "pvrmanager.enabled") { if (((CSettingBool*)setting)->GetValue()) - CApplicationMessenger::Get().ExecBuiltIn("XBMC.StartPVRManager", false); + CApplicationMessenger::Get().ExecBuiltIn("StartPVRManager", false); else - CApplicationMessenger::Get().ExecBuiltIn("XBMC.StopPVRManager", false); + CApplicationMessenger::Get().ExecBuiltIn("StopPVRManager", false); } else if (settingId == "pvrparental.enabled") { @@ -709,11 +709,13 @@ bool CPVRManager::ContinueLastChannel(void) if (channel && channel->HasPVRChannelInfoTag()) { CLog::Log(LOGNOTICE, "PVRManager - %s - continue playback on channel '%s'", __FUNCTION__, channel->GetPVRChannelInfoTag()->ChannelName().c_str()); - SetPlayingGroup(m_channelGroups->GetLastPlayedGroup()); + SetPlayingGroup(m_channelGroups->GetLastPlayedGroup(channel->GetPVRChannelInfoTag()->ChannelID())); StartPlayback(channel->GetPVRChannelInfoTag(), (CSettings::Get().GetInt("pvrplayback.startlast") == CONTINUE_LAST_CHANNEL_IN_BACKGROUND)); return true; } + CLog::Log(LOGDEBUG, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__); + return false; } @@ -1577,8 +1579,10 @@ void CPVRManager::UpdateLastWatched(CPVRChannel &channel) CDateTime::GetCurrentDateTime().GetAsTime(tNow); // update last watched timestamp for channel - channel.SetLastWatched(tNow); - channel.Persist(); + // NOTE: method could be called with a fileitem copy as argument so we need to obtain the right channel instance + CPVRChannelPtr channelPtr = m_channelGroups->GetChannelById(channel.ChannelID()); + channelPtr->SetLastWatched(tNow); + channelPtr->Persist(); // update last watched timestamp for group CPVRChannelGroupPtr group = GetPlayingGroup(channel.IsRadio()); diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp index 26b85d242a..43ec0611d5 100644 --- a/xbmc/pvr/channels/PVRChannel.cpp +++ b/xbmc/pvr/channels/PVRChannel.cpp @@ -163,7 +163,10 @@ void CPVRChannel::Serialize(CVariant& value) const CEpgInfoTag epg; if (GetEPGNow(epg)) - epg.Serialize(value); + epg.Serialize(value["broadcastnow"]); + + if (GetEPGNext(epg)) + epg.Serialize(value["broadcastnext"]); } /********** XBMC related channel methods **********/ diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index a10e2ece59..c021ef43e7 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -428,34 +428,20 @@ CPVRChannelPtr CPVRChannelGroup::GetByUniqueID(int iUniqueID) const return empty; } -CFileItemPtr CPVRChannelGroup::GetLastPlayedChannel(unsigned int iCurrentChannel /* = -1 */) const +CFileItemPtr CPVRChannelGroup::GetLastPlayedChannel(int iCurrentChannel /* = -1 */) const { CSingleLock lock(m_critSection); - time_t tCurrentLastWatched(0), tMaxLastWatched(0); - if (iCurrentChannel > 0) - { - CPVRChannelPtr channel = GetByChannelID(iCurrentChannel); - if (channel.get()) - { - CDateTime::GetCurrentDateTime().GetAsTime(tMaxLastWatched); - channel->SetLastWatched(tMaxLastWatched); - channel->Persist(); - } - } - CPVRChannelPtr returnChannel; - for (unsigned int iChannelPtr = 0; iChannelPtr < m_members.size(); iChannelPtr++) + for (std::vector<PVRChannelGroupMember>::const_iterator it = m_members.begin(); it != m_members.end(); ++it) { - PVRChannelGroupMember groupMember = m_members.at(iChannelPtr); - - if (g_PVRClients->IsConnectedClient(groupMember.channel->ClientID()) && - groupMember.channel->LastWatched() > 0 && - (tMaxLastWatched == 0 || groupMember.channel->LastWatched() < tMaxLastWatched) && - (tCurrentLastWatched == 0 || groupMember.channel->LastWatched() > tCurrentLastWatched)) + CPVRChannelPtr channel = (*it).channel; + if (channel->ChannelID() != iCurrentChannel && + g_PVRClients->IsConnectedClient(channel->ClientID()) && + channel->LastWatched() > 0 && + (!returnChannel || channel->LastWatched() > returnChannel->LastWatched())) { - returnChannel = groupMember.channel; - tCurrentLastWatched = returnChannel->LastWatched(); + returnChannel = channel; } } diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h index da88c0579c..80b6d55ddc 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.h +++ b/xbmc/pvr/channels/PVRChannelGroup.h @@ -267,7 +267,7 @@ namespace PVR * @param iCurrentChannel The channelid of the current channel that is playing, or -1 if none * @return The requested channel. */ - CFileItemPtr GetLastPlayedChannel(unsigned int iCurrentChannel = -1) const; + CFileItemPtr GetLastPlayedChannel(int iCurrentChannel = -1) const; /*! * @brief Get a channel given it's channel number. diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp index 7f7398bbca..3c4c247e00 100644 --- a/xbmc/pvr/channels/PVRChannelGroups.cpp +++ b/xbmc/pvr/channels/PVRChannelGroups.cpp @@ -337,14 +337,15 @@ CPVRChannelGroupPtr CPVRChannelGroups::GetLastGroup(void) const return empty; } -CPVRChannelGroupPtr CPVRChannelGroups::GetLastPlayedGroup() const +CPVRChannelGroupPtr CPVRChannelGroups::GetLastPlayedGroup(int iChannelID /* = -1 */) const { CSingleLock lock(m_critSection); CPVRChannelGroupPtr group; for (std::vector<CPVRChannelGroupPtr>::const_iterator it = m_groups.begin(); it != m_groups.end(); it++) { - if ((*it)->LastWatched() > 0 && (!group || (*it)->LastWatched() > group->LastWatched())) + if ((*it)->LastWatched() > 0 && (!group || (*it)->LastWatched() > group->LastWatched()) && + (iChannelID == -1 || (iChannelID >= 0 && (*it)->IsGroupMember(iChannelID)))) group = (*it); } diff --git a/xbmc/pvr/channels/PVRChannelGroups.h b/xbmc/pvr/channels/PVRChannelGroups.h index d235661f18..b564c7b79a 100644 --- a/xbmc/pvr/channels/PVRChannelGroups.h +++ b/xbmc/pvr/channels/PVRChannelGroups.h @@ -109,10 +109,11 @@ namespace PVR CPVRChannelGroupPtr GetLastGroup(void) const; /*! - * @brief The group that was played last. + * @brief The group that was played last and optionally contains the given channel. + * @param iChannelID The channel ID * @return The last watched group. */ - CPVRChannelGroupPtr GetLastPlayedGroup() const; + CPVRChannelGroupPtr GetLastPlayedGroup(int iChannelID = -1) const; /*! * @brief Get the list of groups. diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp index cc95f21718..def42c4033 100644 --- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp @@ -265,17 +265,22 @@ void CPVRChannelGroupsContainer::SearchMissingChannelIcons(void) CFileItemPtr CPVRChannelGroupsContainer::GetLastPlayedChannel(void) const { - CPVRChannelGroupPtr group = GetLastPlayedGroup(); - if (group) - return group->GetLastPlayedChannel(); + CFileItemPtr channelTV = m_groupsTV->GetGroupAll()->GetLastPlayedChannel(); + CFileItemPtr channelRadio = m_groupsRadio->GetGroupAll()->GetLastPlayedChannel(); - return CFileItemPtr(new CFileItem); + if (!channelTV || + !channelTV->HasPVRChannelInfoTag() || + (channelRadio && channelRadio->HasPVRChannelInfoTag() && + channelRadio->GetPVRChannelInfoTag()->LastWatched() > channelTV->GetPVRChannelInfoTag()->LastWatched())) + return channelRadio; + + return channelTV; } -CPVRChannelGroupPtr CPVRChannelGroupsContainer::GetLastPlayedGroup() const +CPVRChannelGroupPtr CPVRChannelGroupsContainer::GetLastPlayedGroup(int iChannelID /* = -1 */) const { - CPVRChannelGroupPtr groupTV = m_groupsTV->GetLastPlayedGroup(); - CPVRChannelGroupPtr groupRadio = m_groupsRadio->GetLastPlayedGroup(); + CPVRChannelGroupPtr groupTV = m_groupsTV->GetLastPlayedGroup(iChannelID); + CPVRChannelGroupPtr groupRadio = m_groupsRadio->GetLastPlayedGroup(iChannelID); if (!groupTV || (groupRadio && groupTV->LastWatched() < groupRadio->LastWatched())) return groupRadio; diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.h b/xbmc/pvr/channels/PVRChannelGroupsContainer.h index 491c202c79..30f063f974 100644 --- a/xbmc/pvr/channels/PVRChannelGroupsContainer.h +++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.h @@ -181,10 +181,11 @@ namespace PVR CFileItemPtr GetLastPlayedChannel(void) const; /*! - * @brief The group that was played last. + * @brief The group that was played last and optionally contains the given channel. + * @param iChannelID The channel ID * @return The last watched group. */ - CPVRChannelGroupPtr GetLastPlayedGroup() const; + CPVRChannelGroupPtr GetLastPlayedGroup(int iChannelID = -1) const; bool CreateChannel(const CPVRChannel &channel); diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp index e2fe612bcb..235857de61 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp @@ -112,17 +112,17 @@ void CGUIDialogPVRChannelsOSD::OnDeinitWindow(int nextWindowID) { if (m_group) { - g_PVRManager.SetPlayingGroup(m_group); - m_group.reset(); - } + if (m_group != GetPlayingGroup()) + { + CGUIWindowPVRBase::SetSelectedItemPath(g_PVRManager.IsPlayingRadio(), GetLastSelectedItemPath(m_group->GroupID())); + g_PVRManager.SetPlayingGroup(m_group); + } + else + { + CGUIWindowPVRBase::SetSelectedItemPath(g_PVRManager.IsPlayingRadio(), m_viewControl.GetSelectedItemPath()); + } - // set selected item path - int selectedItem = m_viewControl.GetSelectedItem(); - if (selectedItem > -1) - { - CFileItemPtr fileItem = m_vecItems->Get(selectedItem); - if (fileItem) - CGUIWindowPVRBase::SetSelectedItemPath(g_PVRManager.IsPlayingRadio(), fileItem->GetPath()); + m_group.reset(); } CGUIDialog::OnDeinitWindow(nextWindowID); @@ -190,7 +190,7 @@ void CGUIDialogPVRChannelsOSD::Update() { m_group = group; m_viewControl.SetSelectedItem(CGUIWindowPVRBase::GetSelectedItemPath(channel->IsRadio())); - SaveSelectedItem(group->GroupID()); + SaveSelectedItemPath(group->GroupID()); } } } @@ -204,7 +204,7 @@ void CGUIDialogPVRChannelsOSD::SaveControlStates() CPVRChannelGroupPtr group = GetPlayingGroup(); if (group) - SaveSelectedItem(group->GroupID()); + SaveSelectedItemPath(group->GroupID()); } void CGUIDialogPVRChannelsOSD::RestoreControlStates() @@ -214,7 +214,7 @@ void CGUIDialogPVRChannelsOSD::RestoreControlStates() CPVRChannelGroupPtr group = GetPlayingGroup(); if (group) { - m_viewControl.SetSelectedItem(GetLastSelectedItem(group->GroupID())); + m_viewControl.SetSelectedItem(GetLastSelectedItemPath(group->GroupID())); } } @@ -333,15 +333,15 @@ void CGUIDialogPVRChannelsOSD::Notify(const Observable &obs, const ObservableMes } } -void CGUIDialogPVRChannelsOSD::SaveSelectedItem(int iGroupID) +void CGUIDialogPVRChannelsOSD::SaveSelectedItemPath(int iGroupID) { - m_groupSelectedItems[iGroupID] = m_viewControl.GetSelectedItem(); + m_groupSelectedItemPaths[iGroupID] = m_viewControl.GetSelectedItemPath(); } -int CGUIDialogPVRChannelsOSD::GetLastSelectedItem(int iGroupID) const +std::string CGUIDialogPVRChannelsOSD::GetLastSelectedItemPath(int iGroupID) const { - std::map<int,int>::const_iterator it = m_groupSelectedItems.find(iGroupID); - if (it != m_groupSelectedItems.end()) + std::map<int, std::string>::const_iterator it = m_groupSelectedItemPaths.find(iGroupID); + if (it != m_groupSelectedItemPaths.end()) return it->second; - return 0; + return ""; } diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.h b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.h index 413a22590a..f19c1341f8 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.h +++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.h @@ -59,9 +59,9 @@ namespace PVR private: CPVRChannelGroupPtr m_group; - std::map<int,int> m_groupSelectedItems; - void SaveSelectedItem(int iGroupID); - int GetLastSelectedItem(int iGroupID) const; + std::map<int, std::string> m_groupSelectedItemPaths; + void SaveSelectedItemPath(int iGroupID); + std::string GetLastSelectedItemPath(int iGroupID) const; }; } diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp index 80b6776b00..d27e805e3a 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp @@ -715,11 +715,5 @@ void CGUIWindowPVRBase::UpdateButtons(void) void CGUIWindowPVRBase::UpdateSelectedItemPath() { - int selectedItem = m_viewControl.GetSelectedItem(); - if (selectedItem > -1) - { - CFileItemPtr fileItem = m_vecItems->Get(selectedItem); - if (fileItem) - m_selectedItemPaths.at(m_bRadio) = fileItem->GetPath(); - } + m_selectedItemPaths.at(m_bRadio) = m_viewControl.GetSelectedItemPath(); } diff --git a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp index d86ef90bb9..131cd6e8ac 100644 --- a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp @@ -105,6 +105,8 @@ void CGUIWindowPVRChannels::GetContextButtons(int itemNumber, CContextButtons &b buttons.Add(CONTEXT_BUTTON_FILTER, 19249); /* filter channels */ buttons.Add(CONTEXT_BUTTON_UPDATE_EPG, 19251); /* update EPG information */ } + + CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); } std::string CGUIWindowPVRChannels::GetDirectoryPath(void) diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp index a7cce2b99d..0d89d220c1 100644 --- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp @@ -100,6 +100,8 @@ void CGUIWindowPVRGuide::GetContextButtons(int itemNumber, CContextButtons &butt if (pItem->GetEPGInfoTag()->HasPVRChannel() && g_PVRClients->HasMenuHooks(pItem->GetEPGInfoTag()->ChannelTag()->ClientID(), PVR_MENUHOOK_EPG)) buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */ + + CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); } void CGUIWindowPVRGuide::UpdateSelectedItemPath() diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp index c603aab721..d52f943f2b 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp @@ -141,6 +141,8 @@ void CGUIWindowPVRRecordings::GetContextButtons(int itemNumber, CContextButtons if (pItem->HasPVRRecordingInfoTag() && g_PVRClients->HasMenuHooks(pItem->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_RECORDING)) buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */ + + CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); } bool CGUIWindowPVRRecordings::OnAction(const CAction &action) diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp index 1054f9c3a0..3a5b82e7f8 100644 --- a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp @@ -74,6 +74,8 @@ void CGUIWindowPVRSearch::GetContextButtons(int itemNumber, CContextButtons &but } buttons.Add(CONTEXT_BUTTON_CLEAR, 19232); /* Clear search results */ + + CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); } void CGUIWindowPVRSearch::OnWindowLoaded() diff --git a/xbmc/pvr/windows/GUIWindowPVRTimers.cpp b/xbmc/pvr/windows/GUIWindowPVRTimers.cpp index 8c6481dbe9..1351bbaaaa 100644 --- a/xbmc/pvr/windows/GUIWindowPVRTimers.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRTimers.cpp @@ -81,6 +81,8 @@ void CGUIWindowPVRTimers::GetContextButtons(int itemNumber, CContextButtons &but if (g_PVRClients->HasMenuHooks(pItem->GetPVRTimerInfoTag()->m_iClientId, PVR_MENUHOOK_TIMER)) buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */ } + + CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); } bool CGUIWindowPVRTimers::OnContextButton(int itemNumber, CONTEXT_BUTTON button) diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index 6109cecd49..7d048723ca 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -40,6 +40,7 @@ #include "addons/IAddon.h" #include "addons/AddonManager.h" #include "addons/GUIDialogAddonSettings.h" +#include "CompileInfo.h" #if defined(TARGET_DARWIN_IOS) #include "osx/DarwinUtils.h" #endif @@ -362,8 +363,6 @@ void CAdvancedSettings::Initialize() m_bPVRAutoScanIconsUserSet = false; m_iPVRNumericChannelSwitchTimeout = 1000; - m_measureRefreshrate = false; - m_cacheMemBufferSize = 1024 * 1024 * 20; m_networkBufferMode = 0; // Default (buffer all internet streams/filesystems) // the following setting determines the readRate of a player data @@ -1092,8 +1091,6 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) XMLUtils::GetInt(pPVR, "numericchannelswitchtimeout", m_iPVRNumericChannelSwitchTimeout, 50, 60000); } - XMLUtils::GetBoolean(pRootElement, "measurerefreshrate", m_measureRefreshrate); - TiXmlElement* pDatabase = pRootElement->FirstChildElement("videodatabase"); if (pDatabase) { diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h index 1d9021e28a..7df586e444 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -365,9 +365,6 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler bool m_bPVRAutoScanIconsUserSet; /*!< @brief mark channel icons populated by auto scan as "user set" */ int m_iPVRNumericChannelSwitchTimeout; /*!< @brief time in ms before the numeric dialog auto closes when confirmchannelswitch is disabled */ - bool m_measureRefreshrate; //when true the videoreferenceclock will measure the refreshrate when direct3d is used - //otherwise it will use the windows refreshrate - DatabaseSettings m_databaseMusic; // advanced music database setup DatabaseSettings m_databaseVideo; // advanced video database setup DatabaseSettings m_databaseTV; // advanced tv database setup diff --git a/xbmc/storage/MediaManager.cpp b/xbmc/storage/MediaManager.cpp index 139a398b32..d1eabd9735 100644 --- a/xbmc/storage/MediaManager.cpp +++ b/xbmc/storage/MediaManager.cpp @@ -222,7 +222,7 @@ void CMediaManager::GetNetworkLocations(VECSOURCES &locations, bool autolocation #ifdef HAS_ZEROCONF share.strPath = "zeroconf://"; - share.strName = "Zeroconf Browser"; + share.strName = g_localizeStrings.Get(20262); locations.push_back(share); #endif } diff --git a/xbmc/storage/linux/UDisksProvider.cpp b/xbmc/storage/linux/UDisksProvider.cpp index 02ff5fc17b..57e8b7b896 100644 --- a/xbmc/storage/linux/UDisksProvider.cpp +++ b/xbmc/storage/linux/UDisksProvider.cpp @@ -304,7 +304,8 @@ bool CUDisksProvider::HasUDisks() void CUDisksProvider::DeviceAdded(const char *object, IStorageEventsCallback *callback) { - CLog::Log(LOGDEBUG|LOGDBUS, "UDisks: DeviceAdded (%s)", object); + if (g_advancedSettings.CanLogComponent(LOGDBUS)) + CLog::Log(LOGDEBUG, "UDisks: DeviceAdded (%s)", object); if (m_AvailableDevices[object]) { @@ -319,7 +320,8 @@ void CUDisksProvider::DeviceAdded(const char *object, IStorageEventsCallback *ca if (g_advancedSettings.m_handleMounting) device->Mount(); - CLog::Log(LOGDEBUG|LOGDBUS, "UDisks: DeviceAdded - %s", device->toString().c_str()); + if (g_advancedSettings.CanLogComponent(LOGDBUS)) + CLog::Log(LOGDEBUG, "UDisks: DeviceAdded - %s", device->toString().c_str()); if (device->m_isMounted && device->IsApproved()) { @@ -331,7 +333,8 @@ void CUDisksProvider::DeviceAdded(const char *object, IStorageEventsCallback *ca void CUDisksProvider::DeviceRemoved(const char *object, IStorageEventsCallback *callback) { - CLog::Log(LOGDEBUG|LOGDBUS, "UDisks: DeviceRemoved (%s)", object); + if (g_advancedSettings.CanLogComponent(LOGDBUS)) + CLog::Log(LOGDEBUG, "UDisks: DeviceRemoved (%s)", object); CUDiskDevice *device = m_AvailableDevices[object]; if (device) @@ -346,7 +349,8 @@ void CUDisksProvider::DeviceRemoved(const char *object, IStorageEventsCallback * void CUDisksProvider::DeviceChanged(const char *object, IStorageEventsCallback *callback) { - CLog::Log(LOGDEBUG|LOGDBUS, "UDisks: DeviceChanged (%s)", object); + if (g_advancedSettings.CanLogComponent(LOGDBUS)) + CLog::Log(LOGDEBUG, "UDisks: DeviceChanged (%s)", object); CUDiskDevice *device = m_AvailableDevices[object]; if (device == NULL) @@ -368,7 +372,8 @@ void CUDisksProvider::DeviceChanged(const char *object, IStorageEventsCallback * else if (mounted && !device->m_isMounted && callback) callback->OnStorageSafelyRemoved(device->m_Label); - CLog::Log(LOGDEBUG|LOGDBUS, "UDisks: DeviceChanged - %s", device->toString().c_str()); + if (g_advancedSettings.CanLogComponent(LOGDBUS)) + CLog::Log(LOGDEBUG, "UDisks: DeviceChanged - %s", device->toString().c_str()); } } diff --git a/xbmc/test/TestUtils.cpp b/xbmc/test/TestUtils.cpp index 6dab2797ce..fac3d84336 100644 --- a/xbmc/test/TestUtils.cpp +++ b/xbmc/test/TestUtils.cpp @@ -23,6 +23,7 @@ #include "filesystem/File.h" #include "filesystem/SpecialProtocol.h" #include "utils/StringUtils.h" +#include "utils/URIUtils.h" #ifdef TARGET_WINDOWS #include <windows.h> @@ -43,7 +44,6 @@ public: bool Create(const std::string &suffix) { char tmp[MAX_PATH]; - int fd; m_ptempFileDirectory = CSpecialProtocol::TranslatePath("special://temp/"); m_ptempFilePath = m_ptempFileDirectory + "xbmctempfileXXXXXX"; @@ -64,6 +64,7 @@ public: } m_ptempFilePath = tmp; #else + int fd; if ((fd = mkstemps(tmp, suffix.length())) < 0) { m_ptempFilePath = ""; @@ -107,7 +108,7 @@ CXBMCTestUtils &CXBMCTestUtils::Instance() std::string CXBMCTestUtils::ReferenceFilePath(const std::string& path) { - return CSpecialProtocol::TranslatePath("special://xbmc") + path; + return CSpecialProtocol::TranslatePath(URIUtils::AddFileToFolder("special://xbmc", path)); } bool CXBMCTestUtils::SetReferenceFileBasePath() diff --git a/xbmc/utils/Archive.cpp b/xbmc/utils/Archive.cpp index 921b440f8e..14cd61c404 100644 --- a/xbmc/utils/Archive.cpp +++ b/xbmc/utils/Archive.cpp @@ -377,9 +377,13 @@ void CArchive::FlushBuffer() { if (m_iMode == store && m_BufferPos != m_pBuffer) { - m_pFile->Write(m_pBuffer, m_BufferPos - m_pBuffer); - m_BufferPos = m_pBuffer; - m_BufferRemain = CARCHIVE_BUFFER_MAX; + if (m_pFile->Write(m_pBuffer, m_BufferPos - m_pBuffer) != m_BufferPos - m_pBuffer) + CLog::Log(LOGERROR, "%s: Error flushing buffer", __FUNCTION__); + else + { + m_BufferPos = m_pBuffer; + m_BufferRemain = CARCHIVE_BUFFER_MAX; + } } } @@ -402,8 +406,12 @@ void CArchive::FillBuffer() { if (m_iMode == load && m_BufferRemain == 0) { - m_BufferRemain = m_pFile->Read(m_pBuffer, CARCHIVE_BUFFER_MAX); - m_BufferPos = m_pBuffer; + ssize_t read = m_pFile->Read(m_pBuffer, CARCHIVE_BUFFER_MAX); + if (read > 0) + { + m_BufferRemain = read; + m_BufferPos = m_pBuffer; + } } } diff --git a/xbmc/utils/LangCodeExpander.cpp b/xbmc/utils/LangCodeExpander.cpp index 67dc2d4c04..599609c429 100644 --- a/xbmc/utils/LangCodeExpander.cpp +++ b/xbmc/utils/LangCodeExpander.cpp @@ -1421,10 +1421,10 @@ const CharCodeConvertionWithHack CharCode2To3[189] = { "za", "zha", NULL }, { "zh", "chi", "zho" }, { "zu", "zul", NULL }, - { "zv", "und", NULL }, // XBMC intern mapping for missing "Undetermined" iso639-1 code - { "zx", "zxx", NULL }, // XBMC intern mapping for missing "No linguistic content" iso639-1 code - { "zy", "mis", NULL }, // XBMC intern mapping for missing "Miscellaneous languages" iso639-1 code - { "zz", "mul", NULL } // XBMC intern mapping for missing "Multiple languages" iso639-1 code + { "zv", "und", NULL }, // Kodi intern mapping for missing "Undetermined" iso639-1 code + { "zx", "zxx", NULL }, // Kodi intern mapping for missing "No linguistic content" iso639-1 code + { "zy", "mis", NULL }, // Kodi intern mapping for missing "Miscellaneous languages" iso639-1 code + { "zz", "mul", NULL } // Kodi intern mapping for missing "Multiple languages" iso639-1 code }; // Based on ISO 3166 diff --git a/xbmc/utils/MarkWatchedJob.cpp b/xbmc/utils/MarkWatchedJob.cpp index 632e1dcf1a..054da5c124 100644 --- a/xbmc/utils/MarkWatchedJob.cpp +++ b/xbmc/utils/MarkWatchedJob.cpp @@ -94,8 +94,16 @@ bool CMarkWatchedJob::DoWork() { CFileItemPtr pItem = *iter; if (m_bMark) - database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME); - database.SetPlayCount(*pItem, m_bMark ? 1 : 0); + { + std::string path(pItem->GetPath()); + if (pItem->HasVideoInfoTag()) + path = pItem->GetVideoInfoTag()->GetPath(); + + database.ClearBookMarksOfFile(path, CBookmark::RESUME); + database.IncrementPlayCount(*pItem); + } + else + database.SetPlayCount(*pItem, 0); } database.CommitTransaction(); diff --git a/xbmc/utils/ScraperUrl.cpp b/xbmc/utils/ScraperUrl.cpp index 841adee998..a9eafddc9c 100644 --- a/xbmc/utils/ScraperUrl.cpp +++ b/xbmc/utils/ScraperUrl.cpp @@ -307,9 +307,8 @@ bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCur std::string strCachePath = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, "scrapers/" + cacheContext + "/" + scrURL.m_cache); XFILE::CFile file; - if (file.OpenForWrite(strCachePath,true)) - file.Write(strHTML.data(),strHTML.size()); - file.Close(); + if (!file.OpenForWrite(strCachePath, true) || file.Write(strHTML.data(), strHTML.size()) != strHTML.size()) + return false; } return true; } diff --git a/xbmc/utils/TimeUtils.cpp b/xbmc/utils/TimeUtils.cpp index 3a0b7e2544..9f2e1350a8 100644 --- a/xbmc/utils/TimeUtils.cpp +++ b/xbmc/utils/TimeUtils.cpp @@ -69,23 +69,15 @@ int64_t CurrentHostFrequency(void) #endif } -CTimeSmoother *CTimeUtils::frameTimer = NULL; +CTimeSmoother CTimeUtils::frameTimer; unsigned int CTimeUtils::frameTime = 0; -void CTimeUtils::Close() -{ - delete frameTimer; - frameTimer = NULL; -}; - void CTimeUtils::UpdateFrameTime(bool flip) { - if (!frameTimer) - frameTimer = new CTimeSmoother(); unsigned int currentTime = XbmcThreads::SystemClockMillis(); if (flip) - frameTimer->AddTimeStamp(currentTime); - frameTime = frameTimer->GetNextFrameTime(currentTime); + frameTimer.AddTimeStamp(currentTime); + frameTime = frameTimer.GetNextFrameTime(currentTime); } unsigned int CTimeUtils::GetFrameTime() diff --git a/xbmc/utils/TimeUtils.h b/xbmc/utils/TimeUtils.h index c535b7bcd7..f8796d5c76 100644 --- a/xbmc/utils/TimeUtils.h +++ b/xbmc/utils/TimeUtils.h @@ -35,10 +35,9 @@ public: static void UpdateFrameTime(bool flip); ///< update the frame time. Not threadsafe static unsigned int GetFrameTime(); ///< returns the frame time in MS. Not threadsafe static CDateTime GetLocalTime(time_t time); - static void Close(); private: static unsigned int frameTime; - static CTimeSmoother *frameTimer; + static CTimeSmoother frameTimer; }; diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 4ec3cf58ff..6ab3dbb9b2 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -42,7 +42,8 @@ bool URIUtils::IsInPath(const CStdString &uri, const CStdString &baseURI) { CStdString uriPath = CSpecialProtocol::TranslatePath(uri); CStdString basePath = CSpecialProtocol::TranslatePath(baseURI); - return StringUtils::StartsWith(uriPath, basePath); + + return !basePath.empty() && StringUtils::StartsWith(uriPath, basePath); } /* returns filename extension including period of filename */ diff --git a/xbmc/utils/Weather.cpp b/xbmc/utils/Weather.cpp index 91689e67ba..a85cb15538 100644 --- a/xbmc/utils/Weather.cpp +++ b/xbmc/utils/Weather.cpp @@ -51,7 +51,7 @@ using namespace XFILE; #define LOCALIZED_TOKEN_FIRSTID 370 #define LOCALIZED_TOKEN_LASTID 395 -#define LOCALIZED_TOKEN_FIRSTID2 1396 +#define LOCALIZED_TOKEN_FIRSTID2 1350 #define LOCALIZED_TOKEN_LASTID2 1449 #define LOCALIZED_TOKEN_FIRSTID3 11 #define LOCALIZED_TOKEN_LASTID3 17 diff --git a/xbmc/utils/XBMCTinyXML.cpp b/xbmc/utils/XBMCTinyXML.cpp index ee9f8e0097..e7db9f132d 100644 --- a/xbmc/utils/XBMCTinyXML.cpp +++ b/xbmc/utils/XBMCTinyXML.cpp @@ -122,8 +122,7 @@ bool CXBMCTinyXML::SaveFile(const std::string& filename) const { TiXmlPrinter printer; Accept(&printer); - file.Write(printer.CStr(), printer.Size()); - return true; + return file.Write(printer.CStr(), printer.Size()) == printer.Size(); } return false; } diff --git a/xbmc/utils/log.cpp b/xbmc/utils/log.cpp index 4e511664e4..3443f1293d 100644 --- a/xbmc/utils/log.cpp +++ b/xbmc/utils/log.cpp @@ -23,6 +23,7 @@ #include "threads/SingleLock.h" #include "threads/Thread.h" #include "utils/StringUtils.h" +#include "CompileInfo.h" static const char* const levelNames[] = {"DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "SEVERE", "FATAL", "NONE"}; @@ -109,7 +110,9 @@ bool CLog::Init(const std::string& path) // the log folder location is initialized in the CAdvancedSettings // constructor and changed in CApplication::Create() - return s_globals.m_platform.OpenLogFile(path + "xbmc.log", path + "xbmc.old.log"); + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + return s_globals.m_platform.OpenLogFile(path + appName + ".log", path + appName + ".old.log"); } void CLog::MemDump(char *pData, int length) diff --git a/xbmc/utils/test/TestRegExp.cpp b/xbmc/utils/test/TestRegExp.cpp index 89bb34c370..e4231afa29 100644 --- a/xbmc/utils/test/TestRegExp.cpp +++ b/xbmc/utils/test/TestRegExp.cpp @@ -28,6 +28,8 @@ #include "utils/StdString.h" #include "filesystem/File.h" #include "filesystem/SpecialProtocol.h" +#include "utils/StringUtils.h" +#include "CompileInfo.h" TEST(TestRegExp, RegFind) { @@ -151,7 +153,9 @@ TEST_F(TestRegExpLog, DumpOvector) unsigned int bytesread; XFILE::CFile file; - logfile = CSpecialProtocol::TranslatePath("special://temp/") + "xbmc.log"; + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + logfile = CSpecialProtocol::TranslatePath("special://temp/") + appName + ".log"; EXPECT_TRUE(CLog::Init(CSpecialProtocol::TranslatePath("special://temp/").c_str())); EXPECT_TRUE(XFILE::CFile::Exists(logfile)); diff --git a/xbmc/utils/test/TestSystemInfo.cpp b/xbmc/utils/test/TestSystemInfo.cpp index 015bfb78f1..f19d4d0c7d 100644 --- a/xbmc/utils/test/TestSystemInfo.cpp +++ b/xbmc/utils/test/TestSystemInfo.cpp @@ -151,9 +151,6 @@ TEST_F(TestSystemInfo, GetOsPrettyNameWithVersion) TEST_F(TestSystemInfo, GetManufacturerName) { EXPECT_STRCASENE("unknown", g_sysinfo.GetManufacturerName().c_str()) << "'GetManufacturerName()' must return empty string instead of 'Unknown'"; -#ifdef TARGET_DARWIN - EXPECT_STREQ("Apple", g_sysinfo.GetManufacturerName().c_str()) << "'GetManufacturerName()' must return 'Apple'"; -#endif // TARGET_DARWIN } TEST_F(TestSystemInfo, GetModelName) diff --git a/xbmc/utils/test/Testlog.cpp b/xbmc/utils/test/Testlog.cpp index ebcbd91c0b..656201f959 100644 --- a/xbmc/utils/test/Testlog.cpp +++ b/xbmc/utils/test/Testlog.cpp @@ -23,6 +23,8 @@ #include "filesystem/File.h" #include "filesystem/SpecialProtocol.h" #include "utils/StdString.h" +#include "utils/StringUtils.h" +#include "CompileInfo.h" #include "test/TestUtils.h" @@ -46,7 +48,9 @@ TEST_F(Testlog, Log) XFILE::CFile file; CRegExp regex; - logfile = CSpecialProtocol::TranslatePath("special://temp/") + "xbmc.log"; + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + logfile = CSpecialProtocol::TranslatePath("special://temp/") + appName + ".log"; EXPECT_TRUE(CLog::Init(CSpecialProtocol::TranslatePath("special://temp/").c_str())); EXPECT_TRUE(XFILE::CFile::Exists(logfile)); @@ -100,7 +104,9 @@ TEST_F(Testlog, MemDump) CRegExp regex; char refdata[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - logfile = CSpecialProtocol::TranslatePath("special://temp/") + "xbmc.log"; + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + logfile = CSpecialProtocol::TranslatePath("special://temp/") + appName + ".log"; EXPECT_TRUE(CLog::Init(CSpecialProtocol::TranslatePath("special://temp/").c_str())); EXPECT_TRUE(XFILE::CFile::Exists(logfile)); @@ -132,7 +138,9 @@ TEST_F(Testlog, SetLogLevel) { CStdString logfile; - logfile = CSpecialProtocol::TranslatePath("special://temp/") + "xbmc.log"; + std::string appName = CCompileInfo::GetAppName(); + StringUtils::ToLower(appName); + logfile = CSpecialProtocol::TranslatePath("special://temp/") + appName + ".log"; EXPECT_TRUE(CLog::Init(CSpecialProtocol::TranslatePath("special://temp/").c_str())); EXPECT_TRUE(XFILE::CFile::Exists(logfile)); diff --git a/xbmc/video/Teletext.cpp b/xbmc/video/Teletext.cpp index fc33299020..2f2e1e9409 100644 --- a/xbmc/video/Teletext.cpp +++ b/xbmc/video/Teletext.cpp @@ -34,8 +34,10 @@ #include "guilib/GraphicContext.h" #include "cores/IPlayer.h" -#ifdef HAS_SDL +#if SDL_VERSION == 1 #include <SDL/SDL_stdinc.h> +#elif SDL_VERSION == 2 +#include <SDL2/SDL_stdinc.h> #else #define SDL_memset4(dst, val, len) \ do { \ diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index 056e9eb7c7..c18c3b523a 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -3193,14 +3193,13 @@ void CVideoDatabase::DeleteMovie(int idMovie, bool bKeepId /* = false */) // the ancilliary tables are still purged if (!bKeepId) { - strSQL=PrepareSQL("delete from movie where idMovie=%i", idMovie); - m_pDS->exec(strSQL.c_str()); - - // TODO: Why are we invalidating paths here? int idFile = GetDbId(PrepareSQL("SELECT idFile FROM movie WHERE idMovie=%i", idMovie)); std::string path = GetSingleValue(PrepareSQL("SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i", idFile)); if (!path.empty()) InvalidatePathHash(path); + + strSQL=PrepareSQL("delete from movie where idMovie=%i", idMovie); + m_pDS->exec(strSQL.c_str()); } //TODO: move this below CommitTransaction() once UPnP doesn't rely on this anymore @@ -3403,14 +3402,13 @@ void CVideoDatabase::DeleteMusicVideo(int idMVideo, bool bKeepId /* = false */) // the ancilliary tables are still purged if (!bKeepId) { - strSQL=PrepareSQL("delete from musicvideo where idMVideo=%i", idMVideo); - m_pDS->exec(strSQL.c_str()); - - // TODO: Why are we invalidating paths here? int idFile = GetDbId(PrepareSQL("SELECT idFile FROM musicvideo WHERE idMVideo=%i", idMVideo)); std::string path = GetSingleValue(PrepareSQL("SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i", idFile)); if (!path.empty()) InvalidatePathHash(path); + + strSQL=PrepareSQL("delete from musicvideo where idMVideo=%i", idMVideo); + m_pDS->exec(strSQL.c_str()); } //TODO: move this below CommitTransaction() once UPnP doesn't rely on this anymore @@ -7977,6 +7975,10 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const se if (URIUtils::IsStack(fullPath)) fullPath = CStackDirectory::GetFirstStackedFile(fullPath); + // get the actual archive path + if (URIUtils::IsInArchive(fullPath)) + fullPath = CURL(fullPath).GetHostName(); + // remove optical, non-existing files if (URIUtils::IsOnDVD(fullPath) || !CFile::Exists(fullPath, false)) filesToTestForDelete += m_pDS->fv("files.idFile").get_asString() + ","; @@ -8090,7 +8092,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const se } CLog::Log(LOGDEBUG, "%s: Cleaning paths that don't exist and have content set...", __FUNCTION__); - sql = "SELECT path.idPath, path.strPath FROM path " + sql = "SELECT path.idPath, path.strPath, path.idParentPath FROM path " "WHERE NOT ((strContent IS NULL OR strContent = '') " "AND (strSettings IS NULL OR strSettings = '') " "AND (strHash IS NULL OR strHash = '') " @@ -8100,8 +8102,12 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const se while (!m_pDS->eof()) { std::map<int, bool>::const_iterator pathsDeleteDecision = pathsDeleteDecisions.find(m_pDS->fv(0).get_asInt()); - if ((pathsDeleteDecision != pathsDeleteDecisions.end() && pathsDeleteDecision->second) || - (pathsDeleteDecision == pathsDeleteDecisions.end() && !CDirectory::Exists(m_pDS->fv(1).get_asString(), false))) + // Check if we have a decision for the parent path + std::map<int, bool>::const_iterator pathsDeleteDecisionByParent = pathsDeleteDecisions.find(m_pDS->fv(2).get_asInt()); + if (((pathsDeleteDecision != pathsDeleteDecisions.end() && pathsDeleteDecision->second) || + (pathsDeleteDecision == pathsDeleteDecisions.end() && !CDirectory::Exists(m_pDS->fv(1).get_asString(), false))) && + ((pathsDeleteDecisionByParent != pathsDeleteDecisions.end() && pathsDeleteDecisionByParent->second) || + (pathsDeleteDecisionByParent == pathsDeleteDecisions.end()))) strIds += m_pDS->fv(0).get_asString() + ","; m_pDS->next(); diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp index 9bf4349a6b..b4a2672a79 100644 --- a/xbmc/video/VideoInfoScanner.cpp +++ b/xbmc/video/VideoInfoScanner.cpp @@ -123,7 +123,7 @@ namespace VIDEO * doesn't exist rather than a NAS being switched off. A manual clean from settings * will still pick up and remove it though. */ - CLog::Log(LOGWARNING, "%s directory '%s' does not exist - skipping scan%s.", __FUNCTION__, directory.c_str(), m_bClean ? " and clean" : ""); + CLog::Log(LOGWARNING, "%s directory '%s' does not exist - skipping scan%s.", __FUNCTION__, CURL::GetRedacted(directory).c_str(), m_bClean ? " and clean" : ""); m_pathsToScan.erase(m_pathsToScan.begin()); } else if (!DoScan(directory)) @@ -172,17 +172,20 @@ namespace VIDEO m_pathsToScan.clear(); m_pathsToClean.clear(); + m_database.Open(); if (strDirectory.empty()) { // scan all paths in the database. We do this by scanning all paths in the db, and crossing them off the list as // we go. - m_database.Open(); m_database.GetPaths(m_pathsToScan); - m_database.Close(); } else - { - m_pathsToScan.insert(strDirectory); + { // scan all the paths of this subtree that is in the database + vector< pair<int, string> > subpaths; + m_database.GetSubPaths(m_strStartDir, subpaths); + for (vector< pair<int, string> >::iterator it = subpaths.begin(); it < subpaths.end(); ++it) + m_pathsToScan.insert(it->second); } + m_database.Close(); m_bClean = g_advancedSettings.m_bVideoLibraryCleanOnUpdate; StopThread(); @@ -259,7 +262,7 @@ namespace VIDEO if (IsExcluded(strDirectory)) { - CLog::Log(LOGWARNING, "Skipping item '%s' with '.nomedia' file in parent directory, it won't be added to the library.", strDirectory.c_str()); + CLog::Log(LOGWARNING, "Skipping item '%s' with '.nomedia' file in parent directory, it won't be added to the library.", CURL::GetRedacted(strDirectory).c_str()); return true; } @@ -838,7 +841,7 @@ namespace VIDEO episode.isFolder = false; episodeList.push_back(episode); CLog::Log(LOGDEBUG, "%s - found match for: %s. Season %d, Episode %d", __FUNCTION__, - episode.strPath.c_str(), episode.iSeason, episode.iEpisode); + CURL::GetRedacted(episode.strPath).c_str(), episode.iSeason, episode.iEpisode); return true; } @@ -863,7 +866,7 @@ namespace VIDEO episode.cDate = item->GetVideoInfoTag()->m_firstAired; episodeList.push_back(episode); CLog::Log(LOGDEBUG, "%s - found match for: '%s', firstAired: '%s' = '%s', title: '%s'", - __FUNCTION__, episode.strPath.c_str(), tag->m_firstAired.GetAsDBDateTime().c_str(), + __FUNCTION__, CURL::GetRedacted(episode.strPath).c_str(), tag->m_firstAired.GetAsDBDateTime().c_str(), episode.cDate.GetAsLocalizedDate().c_str(), episode.strTitle.c_str()); return true; } @@ -885,7 +888,7 @@ namespace VIDEO episode.iEpisode = -1; episodeList.push_back(episode); CLog::Log(LOGDEBUG,"%s - found match for: '%s', title: '%s'", __FUNCTION__, - episode.strPath.c_str(), episode.strTitle.c_str()); + CURL::GetRedacted(episode.strPath).c_str(), episode.strTitle.c_str()); return true; } @@ -897,7 +900,7 @@ namespace VIDEO if (tag->m_iSeason == 0 && tag->m_iEpisode == 0) { CLog::Log(LOGDEBUG,"%s - found exclusion match for: %s. Both Season and Episode are 0. Item will be ignored for scanning.", - __FUNCTION__, item->GetPath().c_str()); + __FUNCTION__, CURL::GetRedacted(item->GetPath()).c_str()); return true; } @@ -938,7 +941,7 @@ namespace VIDEO if (!GetAirDateFromRegExp(reg, episode)) continue; - CLog::Log(LOGDEBUG, "VideoInfoScanner: Found date based match %s (%s) [%s]", strLabel.c_str(), + CLog::Log(LOGDEBUG, "VideoInfoScanner: Found date based match %s (%s) [%s]", CURL::GetRedacted(strLabel).c_str(), episode.cDate.GetAsLocalizedDate().c_str(), expression[i].regexp.c_str()); } else @@ -946,7 +949,7 @@ namespace VIDEO if (!GetEpisodeAndSeasonFromRegExp(reg, episode, defaultSeason)) continue; - CLog::Log(LOGDEBUG, "VideoInfoScanner: Found episode match %s (s%ie%i) [%s]", strLabel.c_str(), + CLog::Log(LOGDEBUG, "VideoInfoScanner: Found episode match %s (s%ie%i) [%s]", CURL::GetRedacted(strLabel).c_str(), episode.iSeason, episode.iEpisode, expression[i].regexp.c_str()); } @@ -1449,7 +1452,7 @@ namespace VIDEO { CLog::Log(LOGERROR, "VideoInfoScanner: Asked to lookup episode %s" " online, but we have no episode guide. Check your tvshow.nfo and make" - " sure the <episodeguide> tag is in place.", file->strPath.c_str()); + " sure the <episodeguide> tag is in place.", CURL::GetRedacted(file->strPath).c_str()); continue; } diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp index 6d84b60613..03f8bf3aa4 100644 --- a/xbmc/video/VideoReferenceClock.cpp +++ b/xbmc/video/VideoReferenceClock.cpp @@ -26,127 +26,66 @@ #include "utils/TimeUtils.h" #include "utils/StringUtils.h" #include "threads/SingleLock.h" +#include "guilib/GraphicContext.h" +#include "video/videosync/VideoSync.h" +#include "windowing/WindowingFactory.h" -#if defined(HAS_GLX) && defined(HAS_XRANDR) - #include <sstream> - #include <X11/extensions/Xrandr.h> - #include "windowing/WindowingFactory.h" - #include "guilib/GraphicContext.h" -#elif defined(TARGET_DARWIN_OSX) - #include <QuartzCore/CVDisplayLink.h> - #include "osx/CocoaInterface.h" -#elif defined(TARGET_DARWIN_IOS) - #include "windowing/WindowingFactory.h" -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - #pragma comment (lib,"d3d9.lib") - #if (D3DX_SDK_VERSION >= 42) //aug 2009 sdk and up there is no dxerr9 anymore - #include <Dxerr.h> - #pragma comment (lib,"DxErr.lib") - #else - #include <dxerr9.h> - #define DXGetErrorString(hr) DXGetErrorString9(hr) - #define DXGetErrorDescription(hr) DXGetErrorDescription9(hr) - #pragma comment (lib,"Dxerr9.lib") - #endif - #include "windowing/WindowingFactory.h" - #include "settings/AdvancedSettings.h" +#if defined(HAS_GLX) +#include "video/videosync/VideoSyncGLX.h" +#endif +#if defined(HAVE_X11) +#include "video/videosync/VideoSyncDRM.h" +#elif defined(TARGET_RASPBERRY_PI) +#include "video/videosync/VideoSyncPi.h" +#endif +#if defined(TARGET_WINDOWS) +#include "video/videosync/VideoSyncD3D.h" +#endif +#if defined(TARGET_DARWIN) +#include "video/videosync/VideoSyncCocoa.h" #endif using namespace std; -#if defined(TARGET_WINDOWS) && defined(HAS_DX) - - void CD3DCallback::Reset() - { - m_devicevalid = true; - m_deviceused = false; - } - - void CD3DCallback::OnDestroyDevice() - { - CSingleLock lock(m_critsection); - m_devicevalid = false; - while (m_deviceused) - { - lock.Leave(); - m_releaseevent.Wait(); - lock.Enter(); - } - } - - void CD3DCallback::OnCreateDevice() - { - CSingleLock lock(m_critsection); - m_devicevalid = true; - m_createevent.Set(); - } - - void CD3DCallback::Aquire() - { - CSingleLock lock(m_critsection); - while(!m_devicevalid) - { - lock.Leave(); - m_createevent.Wait(); - lock.Enter(); - } - m_deviceused = true; - } - - void CD3DCallback::Release() - { - CSingleLock lock(m_critsection); - m_deviceused = false; - m_releaseevent.Set(); - } - - bool CD3DCallback::IsValid() - { - return m_devicevalid; - } - -#endif - -CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock") +CVideoReferenceClock::CVideoReferenceClock() : CThread("RefClock") { m_SystemFrequency = CurrentHostFrequency(); m_ClockSpeed = 1.0; m_ClockOffset = 0; m_TotalMissedVblanks = 0; m_UseVblank = false; - m_Started.Reset(); m_CurrTime = 0; m_LastIntTime = 0; m_CurrTimeFract = 0.0; - m_LastRefreshTime = 0; m_fineadjust = 0.0; m_RefreshRate = 0.0; - m_PrevRefreshRate = 0; m_MissedVblanks = 0; m_RefreshChanged = 0; m_VblankTime = 0; -#if defined(HAS_GLX) && defined(HAS_XRANDR) - m_glXWaitVideoSyncSGI = NULL; - m_glXGetVideoSyncSGI = NULL; - m_Dpy = NULL; - m_vInfo = NULL; - m_Window = 0; - m_Context = NULL; -#endif + m_pVideoSync = NULL; } CVideoReferenceClock::~CVideoReferenceClock() { -#if defined(HAS_GLX) - // some ATI voodoo, if we don't close the display, we crash on exit - if (m_Dpy) +} + +void CVideoReferenceClock::Stop() +{ + CSingleExit lock(g_graphicsContext); + StopThread(); +} + +void CVideoReferenceClock::CBUpdateClock(int NrVBlanks, uint64_t time) +{ { - XCloseDisplay(m_Dpy); - m_Dpy = NULL; + CSingleLock lock(g_VideoReferenceClock.m_CritSection); + g_VideoReferenceClock.m_VblankTime = time; + g_VideoReferenceClock.UpdateClock(NrVBlanks, true); } -#endif + + g_VideoReferenceClock.SendVblankSignal(); } void CVideoReferenceClock::Process() @@ -154,33 +93,32 @@ void CVideoReferenceClock::Process() bool SetupSuccess = false; int64_t Now; -#if defined(TARGET_WINDOWS) && defined(HAS_DX) - //register callback - m_D3dCallback.Reset(); - g_Windowing.Register(&m_D3dCallback); -#endif -#if defined(HAS_GLX) && defined(HAS_XRANDR) - g_Windowing.Register(this); - m_xrrEvent = false; -#endif - while(!m_bStop) { //set up the vblank clock -#if defined(HAS_GLX) && defined(HAS_XRANDR) - SetupSuccess = SetupGLX(); -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - SetupSuccess = SetupD3D(); -#elif defined(TARGET_DARWIN) - SetupSuccess = SetupCocoa(); -#elif defined(HAS_GLX) - CLog::Log(LOGDEBUG, "CVideoReferenceClock: compiled without RandR support"); +#if defined(HAVE_X11) + std::string gpuvendor = g_Windowing.GetRenderVendor(); + std::transform(gpuvendor.begin(), gpuvendor.end(), gpuvendor.begin(), ::tolower); + if (gpuvendor.compare(0, 5, "intel") == 0) + m_pVideoSync = new CVideoSyncDRM(); +#if defined(HAS_GLX) + else + m_pVideoSync = new CVideoSyncGLX(); +#endif #elif defined(TARGET_WINDOWS) - CLog::Log(LOGDEBUG, "CVideoReferenceClock: only available on directx build"); -#else - CLog::Log(LOGDEBUG, "CVideoReferenceClock: no implementation available"); + m_pVideoSync = new CVideoSyncD3D(); +#elif defined(TARGET_DARWIN) + m_pVideoSync = new CVideoSyncCocoa(); +#elif defined(TARGET_RASPBERRY_PI) + m_pVideoSync = new CVideoSyncPi(); #endif + if (m_pVideoSync) + { + SetupSuccess = m_pVideoSync->Setup(CBUpdateClock); + UpdateRefreshrate(); + } + CSingleLock SingleLock(m_CritSection); Now = CurrentHostCounter(); m_CurrTime = Now + m_ClockOffset; //add the clock offset from the previous time we stopped @@ -190,7 +128,7 @@ void CVideoReferenceClock::Process() m_TotalMissedVblanks = 0; m_fineadjust = 1.0; m_RefreshChanged = 0; - m_Started.Set(); + m_MissedVblanks = 0; if (SetupSuccess) { @@ -199,14 +137,7 @@ void CVideoReferenceClock::Process() SingleLock.Leave(); //run the clock -#if defined(HAS_GLX) && defined(HAS_XRANDR) - RunGLX(); -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - RunD3D(); -#elif defined(TARGET_DARWIN) - RunCocoa(); -#endif - + m_pVideoSync->Run(m_bStop); } else { @@ -221,650 +152,14 @@ void CVideoReferenceClock::Process() SingleLock.Leave(); //clean up the vblank clock -#if defined(HAS_GLX) && defined(HAS_XRANDR) - CleanupGLX(); - if (m_xrrEvent) - { - m_releaseEvent.Set(); - while (!m_bStop) - { - if (m_resetEvent.WaitMSec(100)) - break; - } - m_xrrEvent = false; - } -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - CleanupD3D(); -#elif defined(TARGET_DARWIN) - CleanupCocoa(); -#endif - if (!SetupSuccess) break; - } - -#if defined(TARGET_WINDOWS) && defined(HAS_DX) - g_Windowing.Unregister(&m_D3dCallback); -#endif -#if defined(HAS_GLX) - g_Windowing.Unregister(this); -#endif -} - -bool CVideoReferenceClock::WaitStarted(int MSecs) -{ - //not waiting here can cause issues with alsa - return m_Started.WaitMSec(MSecs); -} - -#if defined(HAS_GLX) && defined(HAS_XRANDR) - -void CVideoReferenceClock::OnLostDevice() -{ - if (!m_xrrEvent) - { - m_releaseEvent.Reset(); - m_resetEvent.Reset(); - m_xrrEvent = true; - m_releaseEvent.Wait(); - } -} - -void CVideoReferenceClock::OnResetDevice() -{ - m_xrrEvent = false; - m_resetEvent.Set(); -} - -bool CVideoReferenceClock::SetupGLX() -{ - int singleBufferAttributes[] = { - GLX_RGBA, - GLX_RED_SIZE, 0, - GLX_GREEN_SIZE, 0, - GLX_BLUE_SIZE, 0, - None - }; - - int ReturnV, SwaMask; - unsigned int GlxTest; - XSetWindowAttributes Swa; - - m_vInfo = NULL; - m_Context = NULL; - m_Window = 0; - - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Setting up GLX"); - - if (!m_Dpy) - { - m_Dpy = XOpenDisplay(NULL); - if (!m_Dpy) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Unable to open display"); - return false; - } - } - - if (!glXQueryExtension(m_Dpy, NULL, NULL)) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX"); - return false; - } - - bool ExtensionFound = false; - istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); - string ExtensionStr; - - while (!ExtensionFound) - { - Extensions >> ExtensionStr; - if (Extensions.fail()) + m_pVideoSync->Cleanup(); + delete m_pVideoSync; + m_pVideoSync = NULL; + if (!SetupSuccess) break; - - if (ExtensionStr == "GLX_SGI_video_sync") - ExtensionFound = true; - } - - if (!ExtensionFound) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX_SGI_video_sync"); - return false; - } - - m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); - if (!m_vInfo) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); - return false; - } - - Swa.border_pixel = 0; - Swa.event_mask = StructureNotifyMask; - Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); - SwaMask = CWBorderPixel | CWColormap | CWEventMask; - - m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, - m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); - - m_Context = glXCreateContext(m_Dpy, m_vInfo, NULL, True); - if (!m_Context) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXCreateContext returned NULL"); - return false; - } - - ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); - if (ReturnV != True) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); - return false; - } - - m_glXWaitVideoSyncSGI = (int (*)(int, int, unsigned int*))glXGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI"); - if (!m_glXWaitVideoSyncSGI) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI not found"); - return false; - } - - ReturnV = m_glXWaitVideoSyncSGI(2, 0, &GlxTest); - if (ReturnV) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); - return false; - } - - m_glXGetVideoSyncSGI = (int (*)(unsigned int*))glXGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI"); - if (!m_glXGetVideoSyncSGI) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI not found"); - return false; - } - - ReturnV = m_glXGetVideoSyncSGI(&GlxTest); - if (ReturnV) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI returned %i", ReturnV); - return false; - } - - XRRSizes(m_Dpy, m_vInfo->screen, &ReturnV); - if (ReturnV == 0) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: RandR not supported"); - return false; - } - - UpdateRefreshrate(true); //forced refreshrate update - m_MissedVblanks = 0; - - return true; -} - -void CVideoReferenceClock::CleanupGLX() -{ - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cleaning up GLX"); - - if (m_vInfo) - { - XFree(m_vInfo); - m_vInfo = NULL; - } - if (m_Context) - { - glXMakeCurrent(m_Dpy, None, NULL); - glXDestroyContext(m_Dpy, m_Context); - m_Context = NULL; - } - if (m_Window) - { - XDestroyWindow(m_Dpy, m_Window); - m_Window = 0; - } - - //ati saves the Display* in their libGL, if we close it here, we crash - if (m_Dpy) - { - XCloseDisplay(m_Dpy); - m_Dpy = NULL; - } -} - -void CVideoReferenceClock::RunGLX() -{ - unsigned int PrevVblankCount; - unsigned int VblankCount; - int ReturnV; - bool IsReset = false; - int64_t Now; - - CSingleLock SingleLock(m_CritSection); - SingleLock.Leave(); - - //get the current vblank counter - m_glXGetVideoSyncSGI(&VblankCount); - PrevVblankCount = VblankCount; - - while(!m_bStop) - { - if (m_xrrEvent) - return; - - //wait for the next vblank - ReturnV = m_glXWaitVideoSyncSGI(2, (VblankCount + 1) % 2, &VblankCount); - m_glXGetVideoSyncSGI(&VblankCount); //the vblank count returned by glXWaitVideoSyncSGI is not always correct - Now = CurrentHostCounter(); //get the timestamp of this vblank - - if(ReturnV) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); - return; - } - - if (VblankCount > PrevVblankCount) - { - //update the vblank timestamp, update the clock and send a signal that we got a vblank - SingleLock.Enter(); - m_VblankTime = Now; - UpdateClock((int)(VblankCount - PrevVblankCount), true); - SingleLock.Leave(); - SendVblankSignal(); - IsReset = false; - } - else - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Vblank counter has reset"); - - //only try reattaching once - if (IsReset) - return; - - //because of a bug in the nvidia driver, glXWaitVideoSyncSGI breaks when the vblank counter resets - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detaching glX context"); - ReturnV = glXMakeCurrent(m_Dpy, None, NULL); - if (ReturnV != True) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); - return; - } - - //sleep here so we don't busy spin when this constantly happens, for example when the display went to sleep - Sleep(1000); - - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Attaching glX context"); - ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); - if (ReturnV != True) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); - return; - } - - m_glXGetVideoSyncSGI(&VblankCount); - - IsReset = true; - } - PrevVblankCount = VblankCount; - } -} - -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - -void CVideoReferenceClock::RunD3D() -{ - D3DRASTER_STATUS RasterStatus; - int64_t Now; - int64_t LastVBlankTime; - unsigned int LastLine; - int NrVBlanks; - double VBlankTime; - int ReturnV; - - CSingleLock SingleLock(m_CritSection); - SingleLock.Leave(); - - //get the scanline we're currently at - m_D3dDev->GetRasterStatus(0, &RasterStatus); - if (RasterStatus.InVBlank) LastLine = 0; - else LastLine = RasterStatus.ScanLine; - - //init the vblanktime - Now = CurrentHostCounter(); - LastVBlankTime = Now; - - while(!m_bStop && m_D3dCallback.IsValid()) - { - //get the scanline we're currently at - ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); - if (ReturnV != D3D_OK) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetRasterStatus returned returned %s: %s", - DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); - return; - } - - //if InVBlank is set, or the current scanline is lower than the previous scanline, a vblank happened - if ((RasterStatus.InVBlank && LastLine > 0) || (RasterStatus.ScanLine < LastLine)) - { - //calculate how many vblanks happened - Now = CurrentHostCounter() - m_SystemFrequency * RasterStatus.ScanLine / (m_Height * MathUtils::round_int(m_RefreshRate)); - VBlankTime = (double)(Now - LastVBlankTime) / (double)m_SystemFrequency; - NrVBlanks = MathUtils::round_int(VBlankTime * m_RefreshRate); - - //update the vblank timestamp, update the clock and send a signal that we got a vblank - SingleLock.Enter(); - m_VblankTime = Now; - UpdateClock(NrVBlanks, true); - SingleLock.Leave(); - SendVblankSignal(); - - if (UpdateRefreshrate()) - { - //we have to measure the refreshrate again - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Displaymode changed"); - return; - } - - //save the timestamp of this vblank so we can calculate how many vblanks happened next time - LastVBlankTime = Now; - - //because we had a vblank, sleep until half the refreshrate period - Now = CurrentHostCounter(); - int SleepTime = (int)((LastVBlankTime + (m_SystemFrequency / MathUtils::round_int(m_RefreshRate) / 2) - Now) * 1000 / m_SystemFrequency); - if (SleepTime > 100) SleepTime = 100; //failsafe - if (SleepTime > 0) ::Sleep(SleepTime); - } - else - { - ::Sleep(1); - } - - if (RasterStatus.InVBlank) LastLine = 0; - else LastLine = RasterStatus.ScanLine; - } -} - -//how many times we measure the refreshrate -#define NRMEASURES 6 -//how long to measure in milliseconds -#define MEASURETIME 250 - -bool CVideoReferenceClock::SetupD3D() -{ - int ReturnV; - - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Setting up Direct3d"); - - m_D3dCallback.Aquire(); - - //get d3d device - m_D3dDev = g_Windowing.Get3DDevice(); - - //we need a high priority thread to get accurate timing - if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) - CLog::Log(LOGDEBUG, "CVideoReferenceClock: SetThreadPriority failed"); - - D3DCAPS9 DevCaps; - ReturnV = m_D3dDev->GetDeviceCaps(&DevCaps); - if (ReturnV != D3D_OK) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetDeviceCaps returned %s: %s", - DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); - return false; - } - - if ((DevCaps.Caps & D3DCAPS_READ_SCANLINE) != D3DCAPS_READ_SCANLINE) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Hardware does not support GetRasterStatus"); - return false; - } - - D3DRASTER_STATUS RasterStatus; - ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); - if (ReturnV != D3D_OK) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetRasterStatus returned returned %s: %s", - DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); - return false; - } - - D3DDISPLAYMODE DisplayMode; - ReturnV = m_D3dDev->GetDisplayMode(0, &DisplayMode); - if (ReturnV != D3D_OK) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetDisplayMode returned returned %s: %s", - DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); - return false; - } - - //forced update of windows refreshrate - UpdateRefreshrate(true); - - if (g_advancedSettings.m_measureRefreshrate) - { - //measure the refreshrate a couple times - list<double> Measures; - for (int i = 0; i < NRMEASURES; i++) - Measures.push_back(MeasureRefreshrate(MEASURETIME)); - - //build up a string of measured rates - CStdString StrRates; - for (list<double>::iterator it = Measures.begin(); it != Measures.end(); it++) - StrRates += StringUtils::Format("%.2f ", *it); - - //get the top half of the measured rates - Measures.sort(); - double RefreshRate = 0.0; - int NrMeasurements = 0; - while (NrMeasurements < NRMEASURES / 2 && !Measures.empty()) - { - if (Measures.back() > 0.0) - { - RefreshRate += Measures.back(); - NrMeasurements++; - } - Measures.pop_back(); - } - - if (NrMeasurements < NRMEASURES / 2) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: refreshrate measurements: %s, unable to get a good measurement", - StrRates.c_str(), m_RefreshRate); - return false; - } - - RefreshRate /= NrMeasurements; - m_RefreshRate = RefreshRate; - - CLog::Log(LOGDEBUG, "CVideoReferenceClock: refreshrate measurements: %s, assuming %i hertz", StrRates.c_str(), m_RefreshRate); - } - else - { - m_RefreshRate = m_PrevRefreshRate; - if (MathUtils::round_int(m_RefreshRate) == 23 || - MathUtils::round_int(m_RefreshRate) == 29 || - MathUtils::round_int(m_RefreshRate) == 59) - m_RefreshRate++; - - if (m_Interlaced) - { - m_RefreshRate *= 2; - CLog::Log(LOGDEBUG, "CVideoReferenceClock: display is interlaced"); - } - - CLog::Log(LOGDEBUG, "CVideoReferenceClock: detected refreshrate: %i hertz, assuming %i hertz", m_PrevRefreshRate, MathUtils::round_int(m_RefreshRate)); - } - - m_MissedVblanks = 0; - - return true; -} - -double CVideoReferenceClock::MeasureRefreshrate(int MSecs) -{ - D3DRASTER_STATUS RasterStatus; - int64_t Now; - int64_t Target; - int64_t Prev; - int64_t AvgInterval; - int64_t MeasureCount; - unsigned int LastLine; - int ReturnV; - - Now = CurrentHostCounter(); - Target = Now + (m_SystemFrequency * MSecs / 1000); - Prev = -1; - AvgInterval = 0; - MeasureCount = 0; - - //start measuring vblanks - LastLine = 0; - while(Now <= Target) - { - ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); - Now = CurrentHostCounter(); - if (ReturnV != D3D_OK) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetRasterStatus returned returned %s: %s", - DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); - return -1.0; - } - - if ((RasterStatus.InVBlank && LastLine != 0) || (!RasterStatus.InVBlank && RasterStatus.ScanLine < LastLine)) - { //we got a vblank - if (Prev != -1) //need two for a measurement - { - AvgInterval += Now - Prev; //save how long this vblank lasted - MeasureCount++; - } - Prev = Now; //save this time for the next measurement - } - - //save the current scanline - if (RasterStatus.InVBlank) - LastLine = 0; - else - LastLine = RasterStatus.ScanLine; - - ::Sleep(1); - } - - if (MeasureCount < 1) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Didn't measure any vblanks"); - return -1.0; - } - - double fRefreshRate = 1.0 / ((double)AvgInterval / (double)MeasureCount / (double)m_SystemFrequency); - - return fRefreshRate; -} - -void CVideoReferenceClock::CleanupD3D() -{ - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cleaning up Direct3d"); - m_D3dCallback.Release(); -} - -#elif defined(TARGET_DARWIN) -#if defined(TARGET_DARWIN_OSX) -// Called by the Core Video Display Link whenever it's appropriate to render a frame. -static CVReturn DisplayLinkCallBack(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) -{ - double fps = 60.0; - - if (inNow->videoRefreshPeriod > 0) - fps = (double)inOutputTime->videoTimeScale / (double)inOutputTime->videoRefreshPeriod; - - // Create an autorelease pool (necessary to call into non-Obj-C code from Obj-C code) - void* pool = Cocoa_Create_AutoReleasePool(); - - CVideoReferenceClock *VideoReferenceClock = reinterpret_cast<CVideoReferenceClock*>(displayLinkContext); - VideoReferenceClock->VblankHandler(inOutputTime->hostTime, fps); - - // Destroy the autorelease pool - Cocoa_Destroy_AutoReleasePool(pool); - - return kCVReturnSuccess; -} -#endif -bool CVideoReferenceClock::SetupCocoa() -{ - CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up Cocoa"); - - //init the vblank timestamp - m_LastVBlankTime = CurrentHostCounter(); - m_MissedVblanks = 0; - m_RefreshRate = 60; //init the refreshrate so we don't get any division by 0 errors - - #if defined(TARGET_DARWIN_IOS) - { - g_Windowing.InitDisplayLink(); - } - #else - if (!Cocoa_CVDisplayLinkCreate((void*)DisplayLinkCallBack, reinterpret_cast<void*>(this))) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cocoa_CVDisplayLinkCreate failed"); - return false; - } - else - #endif - { - UpdateRefreshrate(true); - return true; } } -void CVideoReferenceClock::RunCocoa() -{ - //because cocoa has a vblank callback, we just keep sleeping until we're asked to stop the thread - while(!m_bStop) - { - Sleep(1000); - } -} - -void CVideoReferenceClock::CleanupCocoa() -{ - CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up Cocoa"); - #if defined(TARGET_DARWIN_IOS) - g_Windowing.DeinitDisplayLink(); - #else - Cocoa_CVDisplayLinkRelease(); - #endif -} - -void CVideoReferenceClock::VblankHandler(int64_t nowtime, double fps) -{ - int NrVBlanks; - double VBlankTime; - int RefreshRate = MathUtils::round_int(fps); - - CSingleLock SingleLock(m_CritSection); - - if (RefreshRate != MathUtils::round_int(m_RefreshRate)) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %f hertz, rounding to %i hertz", fps, RefreshRate); - m_RefreshRate = RefreshRate; - } - m_LastRefreshTime = m_CurrTime; - - //calculate how many vblanks happened - VBlankTime = (double)(nowtime - m_LastVBlankTime) / (double)m_SystemFrequency; - NrVBlanks = MathUtils::round_int(VBlankTime * m_RefreshRate); - - //save the timestamp of this vblank so we can calculate how many happened next time - m_LastVBlankTime = nowtime; - - //update the vblank timestamp, update the clock and send a signal that we got a vblank - m_VblankTime = nowtime; - UpdateClock(NrVBlanks, true); - - SingleLock.Leave(); - - SendVblankSignal(); - UpdateRefreshrate(); -} -#endif - //this is called from the vblank run function and from CVideoReferenceClock::Wait in case of a late update void CVideoReferenceClock::UpdateClock(int NrVBlanks, bool CheckMissed) { @@ -979,79 +274,12 @@ double CVideoReferenceClock::GetSpeed() return 1.0; } -bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) +void CVideoReferenceClock::UpdateRefreshrate() { - //if the graphicscontext signaled that the refreshrate changed, we check it about one second later - if (m_RefreshChanged == 1 && !Forced) - { - m_LastRefreshTime = m_CurrTime; - m_RefreshChanged = 2; - return false; - } - - //update the refreshrate about once a second, or update immediately if a forced update is required - if (m_CurrTime - m_LastRefreshTime < m_SystemFrequency && !Forced) - return false; - - if (Forced) - m_LastRefreshTime = 0; - else - m_LastRefreshTime = m_CurrTime; - -#if defined(HAS_GLX) && defined(HAS_XRANDR) - - if (!Forced) - m_RefreshChanged = 0; - - if (!Forced) //refreshrate did not change - return false; - CSingleLock SingleLock(m_CritSection); - m_RefreshRate = g_graphicsContext.GetFPS(); + m_RefreshRate = m_pVideoSync->GetFps(); CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %.3f hertz", m_RefreshRate); - - return true; - -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - - D3DDISPLAYMODE DisplayMode; - m_D3dDev->GetDisplayMode(0, &DisplayMode); - - //0 indicates adapter default - if (DisplayMode.RefreshRate == 0) - DisplayMode.RefreshRate = 60; - - if (m_PrevRefreshRate != DisplayMode.RefreshRate || m_Width != DisplayMode.Width || m_Height != DisplayMode.Height || - m_Interlaced != g_Windowing.Interlaced() || Forced ) - { - m_PrevRefreshRate = DisplayMode.RefreshRate; - m_Width = DisplayMode.Width; - m_Height = DisplayMode.Height; - m_Interlaced = g_Windowing.Interlaced(); - return true; - } - - return false; - -#elif defined(TARGET_DARWIN) - #if defined(TARGET_DARWIN_IOS) - int RefreshRate = round(g_Windowing.GetDisplayLinkFPS() + 0.5); - #else - int RefreshRate = MathUtils::round_int(Cocoa_GetCVDisplayLinkRefreshPeriod()); - #endif - - if (RefreshRate != MathUtils::round_int(m_RefreshRate) || Forced) - { - CSingleLock SingleLock(m_CritSection); - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %i hertz", RefreshRate); - m_RefreshRate = RefreshRate; - return true; - } - return false; -#endif - - return false; } //dvdplayer needs to know the refreshrate for matching the fps of the video playing to it diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h index 6027031449..33a0adf568 100644 --- a/xbmc/video/VideoReferenceClock.h +++ b/xbmc/video/VideoReferenceClock.h @@ -19,47 +19,12 @@ * */ -#include "system.h" // for HAS_XRANDR, and Win32 types #include "threads/Thread.h" #include "threads/CriticalSection.h" -//TODO: get rid of #ifdef hell, abstract implementations in separate classes - -#if defined(HAS_GLX) && defined(HAS_XRANDR) - #include "system_gl.h" - #include <X11/X.h> - #include <X11/Xlib.h> - #include <GL/glx.h> - #include "guilib/DispResource.h" -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - #include <d3d9.h> - #include "guilib/D3DResource.h" - -class CD3DCallback : public ID3DResource -{ - public: - void Reset(); - void OnDestroyDevice(); - void OnCreateDevice(); - void Aquire(); - void Release(); - bool IsValid(); - - private: - bool m_devicevalid; - bool m_deviceused; - - CCriticalSection m_critsection; - CEvent m_createevent; - CEvent m_releaseevent; -}; - -#endif +class CVideoSync; class CVideoReferenceClock : public CThread -#if defined(HAS_GLX) && defined(HAS_XRANDR) - ,public IDispResource -#endif { public: CVideoReferenceClock(); @@ -71,86 +36,40 @@ class CVideoReferenceClock : public CThread double GetSpeed(); double GetRefreshRate(double* interval = NULL); int64_t Wait(int64_t Target); - bool WaitStarted(int MSecs); bool GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate); void SetFineAdjust(double fineadjust); void RefreshChanged() { m_RefreshChanged = 1; } - -#if defined(TARGET_DARWIN) - void VblankHandler(int64_t nowtime, double fps); -#endif - -#if defined(HAS_GLX) && defined(HAS_XRANDR) - virtual void OnLostDevice(); - virtual void OnResetDevice(); -#endif + void Stop(); private: void Process(); - bool UpdateRefreshrate(bool Forced = false); + void UpdateRefreshrate(); void SendVblankSignal(); void UpdateClock(int NrVBlanks, bool CheckMissed); double UpdateInterval(); int64_t TimeOfNextVblank(); + static void CBUpdateClock(int NrVBlanks, uint64_t time); int64_t m_CurrTime; //the current time of the clock when using vblank as clock source int64_t m_LastIntTime; //last interpolated clock value, to make sure the clock doesn't go backwards double m_CurrTimeFract; //fractional part that is lost due to rounding when updating the clock double m_ClockSpeed; //the frequency of the clock set by dvdplayer int64_t m_ClockOffset; //the difference between the vblank clock and systemclock, set when vblank clock is stopped - int64_t m_LastRefreshTime; //last time we updated the refreshrate int64_t m_SystemFrequency; //frequency of the systemclock double m_fineadjust; bool m_UseVblank; //set to true when vblank is used as clock source double m_RefreshRate; //current refreshrate - int m_PrevRefreshRate; //previous refreshrate, used for log printing and getting refreshrate from nvidia-settings int m_MissedVblanks; //number of clock updates missed by the vblank clock int m_RefreshChanged; //1 = we changed the refreshrate, 2 = we should check the refreshrate forced int m_TotalMissedVblanks;//total number of clock updates missed, used by codec information screen int64_t m_VblankTime; //last time the clock was updated when using vblank as clock - CEvent m_Started; //set when the vblank clock is started CEvent m_VblankEvent; //set when a vblank happens CCriticalSection m_CritSection; -#if defined(HAS_GLX) && defined(HAS_XRANDR) - bool SetupGLX(); - void RunGLX(); - void CleanupGLX(); - - int (*m_glXWaitVideoSyncSGI) (int, int, unsigned int*); - int (*m_glXGetVideoSyncSGI) (unsigned int*); - - Display* m_Dpy; - XVisualInfo *m_vInfo; - Window m_Window; - GLXContext m_Context; - bool m_xrrEvent; - CEvent m_releaseEvent, m_resetEvent; - -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - bool SetupD3D(); - double MeasureRefreshrate(int MSecs); - void RunD3D(); - void CleanupD3D(); - - LPDIRECT3DDEVICE9 m_D3dDev; - CD3DCallback m_D3dCallback; - - unsigned int m_Width; - unsigned int m_Height; - bool m_Interlaced; - -#elif defined(TARGET_DARWIN) - bool SetupCocoa(); - void RunCocoa(); - void CleanupCocoa(); - - int64_t m_LastVBlankTime; //timestamp of the last vblank, used for calculating how many vblanks happened - //not the same as m_VblankTime -#endif + CVideoSync *m_pVideoSync; }; extern CVideoReferenceClock g_VideoReferenceClock; diff --git a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp index 442b6f2830..32a9ba4158 100644 --- a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp +++ b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp @@ -316,7 +316,7 @@ void CGUIDialogAudioSubtitleSettings::InitializeSettings() // audio delay setting if (SupportsAudioFeature(IPC_AUD_OFFSET)) { - CSettingNumber *settingAudioDelay = AddSlider(groupAudio, SETTING_AUDIO_DELAY, 297, 0, videoSettings.m_AudioDelay, 0, -g_advancedSettings.m_videoAudioDelayRange, 0.025f, g_advancedSettings.m_videoAudioDelayRange, -1, usePopup); + CSettingNumber *settingAudioDelay = AddSlider(groupAudio, SETTING_AUDIO_DELAY, 297, 0, videoSettings.m_AudioDelay, 0, -g_advancedSettings.m_videoAudioDelayRange, 0.025f, g_advancedSettings.m_videoAudioDelayRange, 297, usePopup); static_cast<CSettingControlSlider*>(settingAudioDelay->GetControl())->SetFormatter(SettingFormatterDelay); } @@ -344,7 +344,7 @@ void CGUIDialogAudioSubtitleSettings::InitializeSettings() // subtitle delay setting if (SupportsSubtitleFeature(IPC_SUBS_OFFSET)) { - CSettingNumber *settingSubtitleDelay = AddSlider(groupSubtitles, SETTING_SUBTITLE_DELAY, 22006, 0, videoSettings.m_SubtitleDelay, 0, -g_advancedSettings.m_videoSubsDelayRange, 0.1f, g_advancedSettings.m_videoSubsDelayRange, -1, usePopup); + CSettingNumber *settingSubtitleDelay = AddSlider(groupSubtitles, SETTING_SUBTITLE_DELAY, 22006, 0, videoSettings.m_SubtitleDelay, 0, -g_advancedSettings.m_videoSubsDelayRange, 0.1f, g_advancedSettings.m_videoSubsDelayRange, 22006, usePopup); static_cast<CSettingControlSlider*>(settingSubtitleDelay->GetControl())->SetFormatter(SettingFormatterDelay); } diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp index 401b261ea3..cffd5a4491 100644 --- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp @@ -325,11 +325,11 @@ void CGUIDialogVideoSettings::InitializeSettings() AddSpinner(groupVideo, SETTING_VIDEO_VIEW_MODE, 629, 0, videoSettings.m_ViewMode, entries); } if (g_renderManager.Supports(RENDERFEATURE_ZOOM)) - AddSlider(groupVideo, SETTING_VIDEO_ZOOM, 216, 0, videoSettings.m_CustomZoomAmount, "%2.2f", 0.5f, 0.01f, 2.0f, -1, usePopup); + AddSlider(groupVideo, SETTING_VIDEO_ZOOM, 216, 0, videoSettings.m_CustomZoomAmount, "%2.2f", 0.5f, 0.01f, 2.0f, 216, usePopup); if (g_renderManager.Supports(RENDERFEATURE_VERTICAL_SHIFT)) - AddSlider(groupVideo, SETTING_VIDEO_VERTICAL_SHIFT, 225, 0, videoSettings.m_CustomVerticalShift, "%2.2f", -2.0f, 0.01f, 2.0f, -1, usePopup); + AddSlider(groupVideo, SETTING_VIDEO_VERTICAL_SHIFT, 225, 0, videoSettings.m_CustomVerticalShift, "%2.2f", -2.0f, 0.01f, 2.0f, 225, usePopup); if (g_renderManager.Supports(RENDERFEATURE_PIXEL_RATIO)) - AddSlider(groupVideo, SETTING_VIDEO_PIXEL_RATIO, 217, 0, videoSettings.m_CustomPixelRatio, "%2.2f", 0.5f, 0.01f, 2.0f, -1, usePopup); + AddSlider(groupVideo, SETTING_VIDEO_PIXEL_RATIO, 217, 0, videoSettings.m_CustomPixelRatio, "%2.2f", 0.5f, 0.01f, 2.0f, 217, usePopup); if (g_renderManager.Supports(RENDERFEATURE_POSTPROCESS)) AddToggle(groupVideo, SETTING_VIDEO_POSTPROCESS, 16400, 0, videoSettings.m_PostProcess); if (g_renderManager.Supports(RENDERFEATURE_BRIGHTNESS)) @@ -339,9 +339,9 @@ void CGUIDialogVideoSettings::InitializeSettings() if (g_renderManager.Supports(RENDERFEATURE_GAMMA)) AddPercentageSlider(groupVideoPlayback, SETTING_VIDEO_GAMMA, 466, 0, static_cast<int>(videoSettings.m_Gamma), 14047, 1, 466, usePopup); if (g_renderManager.Supports(RENDERFEATURE_NOISE)) - AddSlider(groupVideoPlayback, SETTING_VIDEO_VDPAU_NOISE, 16312, 0, videoSettings.m_NoiseReduction, "%2.2f", 0.0f, 0.01f, 1.0f, -1, usePopup); + AddSlider(groupVideoPlayback, SETTING_VIDEO_VDPAU_NOISE, 16312, 0, videoSettings.m_NoiseReduction, "%2.2f", 0.0f, 0.01f, 1.0f, 16312, usePopup); if (g_renderManager.Supports(RENDERFEATURE_SHARPNESS)) - AddSlider(groupVideoPlayback, SETTING_VIDEO_VDPAU_SHARPNESS, 16313, 0, videoSettings.m_Sharpness, "%2.2f", -1.0f, 0.02f, 1.0f, -1, usePopup); + AddSlider(groupVideoPlayback, SETTING_VIDEO_VDPAU_SHARPNESS, 16313, 0, videoSettings.m_Sharpness, "%2.2f", -1.0f, 0.02f, 1.0f, 16313, usePopup); if (g_renderManager.Supports(RENDERFEATURE_NONLINSTRETCH)) AddToggle(groupVideoPlayback, SETTING_VIDEO_NONLIN_STRETCH, 659, 0, videoSettings.m_CustomNonLinStretch); #endif diff --git a/xbmc/video/videosync/Makefile b/xbmc/video/videosync/Makefile new file mode 100644 index 0000000000..cd8f397a05 --- /dev/null +++ b/xbmc/video/videosync/Makefile @@ -0,0 +1,9 @@ +SRCS=VideoSyncGLX.cpp \ + VideoSyncCocoa.cpp \ + VideoSyncDRM.cpp \ + VideoSyncPi.cpp \ + +LIB=videosync.a + +include ../../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
\ No newline at end of file diff --git a/xbmc/video/videosync/VideoSync.h b/xbmc/video/videosync/VideoSync.h new file mode 100644 index 0000000000..0b03f7dcbc --- /dev/null +++ b/xbmc/video/videosync/VideoSync.h @@ -0,0 +1,35 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +typedef void (*PUPDATECLOCK)(int NrVBlanks, uint64_t time); + +class CVideoSync +{ +public: + virtual ~CVideoSync() {}; + virtual bool Setup(PUPDATECLOCK func) = 0; + virtual void Run(volatile bool& stop) = 0; + virtual void Cleanup() = 0; + virtual float GetFps() = 0; +protected: + PUPDATECLOCK UpdateClock; + float m_fps; +}; diff --git a/xbmc/video/videosync/VideoSyncCocoa.cpp b/xbmc/video/videosync/VideoSyncCocoa.cpp new file mode 100644 index 0000000000..1e28183c5a --- /dev/null +++ b/xbmc/video/videosync/VideoSyncCocoa.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" + +#if defined(TARGET_DARWIN) +#include "utils/log.h" +#include "VideoSyncCocoa.h" +#include "utils/MathUtils.h" +#include "video/VideoReferenceClock.h" +#include "utils/TimeUtils.h" + +//ios specifics +#if defined(TARGET_DARWIN_IOS) +#include "windowing/WindowingFactory.h" +#endif + +//osx specifics +#if defined(TARGET_DARWIN_OSX) +#include <QuartzCore/CVDisplayLink.h> +#include "osx/CocoaInterface.h" +// Called by the Core Video Display Link whenever it's appropriate to render a frame. +static CVReturn DisplayLinkCallBack(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) +{ + double fps = 60.0; + + if (inNow->videoRefreshPeriod > 0) + fps = (double)inOutputTime->videoTimeScale / (double)inOutputTime->videoRefreshPeriod; + + // Create an autorelease pool (necessary to call into non-Obj-C code from Obj-C code) + void* pool = Cocoa_Create_AutoReleasePool(); + + CVideoSyncCocoa *VideoSyncCocoa = reinterpret_cast<CVideoSyncCocoa*>(displayLinkContext); + VideoSyncCocoa->VblankHandler(inOutputTime->hostTime, fps); + + // Destroy the autorelease pool + Cocoa_Destroy_AutoReleasePool(pool); + + return kCVReturnSuccess; +} +#endif + +void CVideoSyncCocoa::VblankHandler(int64_t nowtime, double fps) +{ + int NrVBlanks; + double VBlankTime; + int RefreshRate = MathUtils::round_int(fps); + + if (RefreshRate != MathUtils::round_int(m_fps)) + { + CLog::Log(LOGDEBUG, "CVideoSyncCocoa: Detected refreshrate: %f hertz, rounding to %i hertz", fps, RefreshRate); + UpdateFPS(fps); + } + + //calculate how many vblanks happened + VBlankTime = (double)(nowtime - m_LastVBlankTime) / (double)g_VideoReferenceClock.GetFrequency(); + NrVBlanks = MathUtils::round_int(VBlankTime * m_fps); + + //save the timestamp of this vblank so we can calculate how many happened next time + m_LastVBlankTime = nowtime; + + //update the vblank timestamp, update the clock and send a signal that we got a vblank + UpdateClock(NrVBlanks, nowtime); +} + +bool CVideoSyncCocoa::Setup(PUPDATECLOCK func) +{ + CLog::Log(LOGDEBUG, "CVideoSyncCocoa: setting up Cocoa"); + + //init the vblank timestamp + m_LastVBlankTime = CurrentHostCounter(); + UpdateClock = func; + +#if defined(TARGET_DARWIN_IOS) + { + g_Windowing.InitDisplayLink(this); + } +#else + if (!Cocoa_CVDisplayLinkCreate((void*)DisplayLinkCallBack, reinterpret_cast<void*>(this))) + { + CLog::Log(LOGDEBUG, "CVideoSyncCocoa: Cocoa_CVDisplayLinkCreate failed"); + return false; + } + else +#endif + { + GetFps();//UpdateRefreshrate(true); - FIXME?NEEDED? + return true; + } +} + +void CVideoSyncCocoa::Run(volatile bool& stop) +{ + //because cocoa has a vblank callback, we just keep sleeping until we're asked to stop the thread + while(!stop) + { + Sleep(1000); + } +} + +void CVideoSyncCocoa::Cleanup() +{ + CLog::Log(LOGDEBUG, "CVideoSyncCocoa: cleaning up Cocoa"); +#if defined(TARGET_DARWIN_IOS) + g_Windowing.DeinitDisplayLink(); +#else + Cocoa_CVDisplayLinkRelease(); +#endif +} + +void CVideoSyncCocoa::UpdateFPS(double fps) +{ + int fpsInt = MathUtils::round_int(fps); + + if (fpsInt != MathUtils::round_int(m_fps)) + { + CLog::Log(LOGDEBUG, "CVideoSyncCocoa: Detected refreshrate: %i hertz", fpsInt); + m_fps = fpsInt; + } +} + +float CVideoSyncCocoa::GetFps() +{ +#if defined(TARGET_DARWIN_IOS) + UpdateFPS(g_Windowing.GetDisplayLinkFPS() + 0.5); +#else + UpdateFPS(Cocoa_GetCVDisplayLinkRefreshPeriod()); +#endif + + return m_fps; +} + +#endif//TARGET_DARWIN diff --git a/xbmc/video/videosync/VideoSyncCocoa.h b/xbmc/video/videosync/VideoSyncCocoa.h new file mode 100644 index 0000000000..a7ddc73e56 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncCocoa.h @@ -0,0 +1,37 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#if defined(TARGET_DARWIN) +#include "VideoSync.h" +class CVideoSyncCocoa : public CVideoSync +{ +public: + virtual bool Setup(PUPDATECLOCK func); + virtual void Run(volatile bool& stop); + virtual void Cleanup(); + virtual float GetFps(); + void VblankHandler(int64_t nowtime, double fps); +private: + void UpdateFPS(double fps); + int64_t m_LastVBlankTime; //timestamp of the last vblank, used for calculating how many vblanks happened +}; + +#endif diff --git a/xbmc/video/videosync/VideoSyncD3D.cpp b/xbmc/video/videosync/VideoSyncD3D.cpp new file mode 100644 index 0000000000..166635f724 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncD3D.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" + +#if defined(TARGET_WINDOWS) + +#pragma comment (lib,"d3d9.lib") +#pragma comment (lib,"DxErr.lib") +#include <Dxerr.h> +#include "utils/log.h" +#include "Utils/TimeUtils.h" +#include "Utils/MathUtils.h" +#include "windowing\WindowingFactory.h" +#include "video/videosync/VideoSyncD3D.h" +#include "guilib/GraphicContext.h" + +void CVideoSyncD3D::OnDestroyDevice() +{ + if (!m_displayLost) + { + m_displayLost = true; + m_lostEvent.Wait(); + } +} + +void CVideoSyncD3D::OnResetDevice() +{ + m_displayReset = true; +} + +bool CVideoSyncD3D::Setup(PUPDATECLOCK func) +{ + int ReturnV; + CLog::Log(LOGDEBUG, "CVideoSyncD3D: Setting up Direct3d"); + CSingleLock lock(g_graphicsContext); + g_Windowing.Register(this); + m_displayLost = false; + m_displayReset = false; + m_lostEvent.Reset(); + UpdateClock = func; + + //get d3d device + m_D3dDev = g_Windowing.Get3DDevice(); + //we need a high priority thread to get accurate timing + if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) + CLog::Log(LOGDEBUG, "CVideoSyncD3D: SetThreadPriority failed"); + + D3DCAPS9 DevCaps; + ReturnV = m_D3dDev->GetDeviceCaps(&DevCaps); + + if (ReturnV != D3D_OK) + { + CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetDeviceCaps returned %s: %s", + DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); + return false; + } + + if ((DevCaps.Caps & D3DCAPS_READ_SCANLINE) != D3DCAPS_READ_SCANLINE) + { + CLog::Log(LOGDEBUG, "CVideoSyncD3D: Hardware does not support GetRasterStatus"); + return false; + } + + D3DRASTER_STATUS RasterStatus; + ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); + if (ReturnV != D3D_OK) + { + CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetRasterStatus returned returned %s: %s", + DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); + return false; + } + + D3DDISPLAYMODE DisplayMode; + ReturnV = m_D3dDev->GetDisplayMode(0, &DisplayMode); + if (ReturnV != D3D_OK) + { + CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetDisplayMode returned returned %s: %s", + DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); + return false; + } + m_height = DisplayMode.Height; + + return true; +} + +void CVideoSyncD3D::Run(volatile bool& stop) +{ + D3DRASTER_STATUS RasterStatus; + int64_t Now; + int64_t LastVBlankTime; + unsigned int LastLine; + int NrVBlanks; + double VBlankTime; + int ReturnV; + int64_t systemFrequency = CurrentHostFrequency(); + + //get the scanline we're currently at + m_D3dDev->GetRasterStatus(0, &RasterStatus); + if (RasterStatus.InVBlank) + LastLine = 0; + else + LastLine = RasterStatus.ScanLine; + + //init the vblanktime + Now = CurrentHostCounter(); + LastVBlankTime = Now; + m_lastUpdateTime = Now - systemFrequency; + while (!stop && !m_displayLost && !m_displayReset) + { + //get the scanline we're currently at + ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); + if (ReturnV != D3D_OK) + { + CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetRasterStatus returned returned %s: %s", + DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); + return; + } + + //if InVBlank is set, or the current scanline is lower than the previous scanline, a vblank happened + if ((RasterStatus.InVBlank && LastLine > 0) || (RasterStatus.ScanLine < LastLine)) + { + //calculate how many vblanks happened + Now = CurrentHostCounter() - systemFrequency * RasterStatus.ScanLine / (m_height * MathUtils::round_int(m_fps)); + VBlankTime = (double)(Now - LastVBlankTime) / (double)systemFrequency; + NrVBlanks = MathUtils::round_int(VBlankTime * m_fps); + //update the vblank timestamp, update the clock and send a signal that we got a vblank + UpdateClock(NrVBlanks, Now); + + //save the timestamp of this vblank so we can calculate how many vblanks happened next time + LastVBlankTime = Now; + //because we had a vblank, sleep until half the refreshrate period + Now = CurrentHostCounter(); + + if ((Now - m_lastUpdateTime) >= systemFrequency) + { + if (m_fps != GetFps()) + break; + } + + int SleepTime = (int)((LastVBlankTime + (systemFrequency / MathUtils::round_int(m_fps) / 2) - Now) * 1000 / systemFrequency); + if (SleepTime > 100) + SleepTime = 100; //failsafe + if (SleepTime > 0) + ::Sleep(SleepTime); + } + else + { + ::Sleep(1); + } + + if (RasterStatus.InVBlank) + LastLine = 0; + else + LastLine = RasterStatus.ScanLine; + } + + m_lostEvent.Set(); + while (!stop && m_displayLost && !m_displayReset) + { + Sleep(10); + } +} + +void CVideoSyncD3D::Cleanup() +{ + CLog::Log(LOGDEBUG, "CVideoSyncD3D: Cleaning up Direct3d"); + CSingleLock lock(g_graphicsContext); + + m_lostEvent.Set(); + g_Windowing.Unregister(this); +} + +float CVideoSyncD3D::GetFps() +{ + D3DDISPLAYMODE DisplayMode; + m_D3dDev->GetDisplayMode(0, &DisplayMode); + m_fps = DisplayMode.RefreshRate; + if (m_fps == 0) + m_fps = 60; + + if (m_fps == 23 || m_fps == 29 || m_fps == 59) + m_fps++; + + if (g_Windowing.Interlaced()) + { + m_fps *= 2; + } + return m_fps; +} +#endif diff --git a/xbmc/video/videosync/VideoSyncD3D.h b/xbmc/video/videosync/VideoSyncD3D.h new file mode 100644 index 0000000000..5ccbdd24f9 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncD3D.h @@ -0,0 +1,50 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#if defined(TARGET_WINDOWS) + +#include "video/videosync/VideoSync.h" +#include <d3d9.h> +#include "guilib/D3DResource.h" +#include "threads/CriticalSection.h" +#include "threads/Event.h" + +class CVideoSyncD3D : public CVideoSync, ID3DResource +{ +public: + virtual bool Setup(PUPDATECLOCK func); + virtual void Run(volatile bool& stop); + virtual void Cleanup(); + virtual float GetFps(); + + virtual void OnCreateDevice() {} + virtual void OnDestroyDevice(); + virtual void OnResetDevice(); +private: + LPDIRECT3DDEVICE9 m_D3dDev; + int m_height; + volatile bool m_displayLost; + volatile bool m_displayReset; + CEvent m_lostEvent; + int64_t m_lastUpdateTime; +}; + +#endif diff --git a/xbmc/video/videosync/VideoSyncDRM.cpp b/xbmc/video/videosync/VideoSyncDRM.cpp new file mode 100644 index 0000000000..1929a3a185 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncDRM.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" + +#if defined(HAVE_X11) + +#include "video/videosync/VideoSyncDRM.h" +#include "xf86drm.h" +#include <sys/poll.h> +#include <sys/time.h> +#include "utils/TimeUtils.h" +#include "utils/MathUtils.h" +#include "windowing/WindowingFactory.h" +#include "guilib/GraphicContext.h" +#include "utils/log.h" + +bool CVideoSyncDRM::Setup(PUPDATECLOCK func) +{ + CLog::Log(LOGDEBUG, "CVideoSyncDRM::%s - setting up DRM", __FUNCTION__); + + UpdateClock = func; + + m_fd = open("/dev/dri/card0", O_RDWR, 0); + if (m_fd < 0) + { + CLog::Log(LOGERROR, "CVideoSyncDRM::%s - can't open /dev/dri/card0", __FUNCTION__); + return false; + } + + drmVBlank vbl; + int ret; + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 0; + ret = drmWaitVBlank(m_fd, &vbl); + if (ret != 0) + { + CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmWaitVBlank returned error", __FUNCTION__); + return false; + } + + m_abort = false; + g_Windowing.Register(this); + + return true; +} + +void CVideoSyncDRM::Run(volatile bool& stop) +{ + drmVBlank vbl; + VblInfo info; + int ret; + int crtc = g_Windowing.GetCrtc(); + + vbl.request.type = DRM_VBLANK_RELATIVE; + if (crtc == 1) + { + vbl.request.type = (drmVBlankSeqType)(vbl.request.type | DRM_VBLANK_SECONDARY); + } + else if (crtc > 1) + { + vbl.request.type = (drmVBlankSeqType)(vbl.request.type | + (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK); + } + vbl.request.sequence = 0; + ret = drmWaitVBlank(m_fd, &vbl); + if (ret != 0) + { + CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmWaitVBlank returned error", __FUNCTION__); + return; + } + + info.start = CurrentHostCounter(); + info.videoSync = this; + + vbl.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); + if (crtc == 1) + { + vbl.request.type = (drmVBlankSeqType)(vbl.request.type | DRM_VBLANK_SECONDARY); + } + else if (crtc > 1) + { + vbl.request.type = (drmVBlankSeqType)(vbl.request.type | + (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK); + } + vbl.request.sequence = 1; + vbl.request.signal = (unsigned long)&info; + ret = drmWaitVBlank(m_fd, &vbl); + if (ret != 0) + { + CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmWaitVBlank returned error", __FUNCTION__); + return; + } + + drmEventContext evctx; + memset(&evctx, 0, sizeof evctx); + evctx.version = DRM_EVENT_CONTEXT_VERSION; + evctx.vblank_handler = EventHandler; + evctx.page_flip_handler = NULL; + + timeval timeout; + fd_set fds; + FD_ZERO(&fds); + FD_SET(m_fd, &fds); + + while (!stop && !m_abort) + { + timeout.tv_sec = 1; + timeout.tv_usec = 0; + ret = select(m_fd + 1, &fds, NULL, NULL, &timeout); + + if (ret <= 0) + { + continue; + } + + ret = drmHandleEvent(m_fd, &evctx); + if (ret != 0) + { + CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmHandleEvent returned error", __FUNCTION__); + break; + } + } +} + +void CVideoSyncDRM::Cleanup() +{ + close(m_fd); + g_Windowing.Unregister(this); +} + +void CVideoSyncDRM::EventHandler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *data) +{ + drmVBlank vbl; + struct timeval end; + VblInfo *info = (VblInfo*)data; + int crtc = g_Windowing.GetCrtc(); + + vbl.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); + if (crtc == 1) + { + vbl.request.type = (drmVBlankSeqType)(vbl.request.type | DRM_VBLANK_SECONDARY); + } + else if (crtc > 1) + { + vbl.request.type = (drmVBlankSeqType)(vbl.request.type | + (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK); + } + vbl.request.sequence = 1; + vbl.request.signal = (unsigned long)data; + + drmWaitVBlank(info->videoSync->m_fd, &vbl); + + uint64_t now = CurrentHostCounter(); + float diff = (float)(now - info->start)/CurrentHostFrequency(); + int vblanks = MathUtils::round_int(diff * info->videoSync->m_fps); + info->start = now; + + info->videoSync->UpdateClock(vblanks, now); +} + +void CVideoSyncDRM::OnResetDevice() +{ + m_abort = true; +} + +float CVideoSyncDRM::GetFps() +{ + m_fps = g_graphicsContext.GetFPS(); + return m_fps; +} + +#endif diff --git a/xbmc/video/videosync/VideoSyncDRM.h b/xbmc/video/videosync/VideoSyncDRM.h new file mode 100644 index 0000000000..35f3e2110e --- /dev/null +++ b/xbmc/video/videosync/VideoSyncDRM.h @@ -0,0 +1,46 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#if defined(HAVE_X11) + +#include "video/videosync/VideoSync.h" +#include "guilib/DispResource.h" + +class CVideoSyncDRM : public CVideoSync, IDispResource +{ +public: + virtual bool Setup(PUPDATECLOCK func); + virtual void Run(volatile bool& stop); + virtual void Cleanup(); + virtual float GetFps(); + virtual void OnResetDevice(); +private: + static void EventHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data); + int m_fd; + volatile bool m_abort; + struct VblInfo + { + uint64_t start; + CVideoSyncDRM *videoSync; + }; +}; + +#endif diff --git a/xbmc/video/videosync/VideoSyncGLX.cpp b/xbmc/video/videosync/VideoSyncGLX.cpp new file mode 100644 index 0000000000..fe839045d3 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncGLX.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" + +#if defined(HAS_GLX) + +#include "video/videosync/VideoSyncGLX.h" +#include <sstream> +#include <X11/extensions/Xrandr.h> +#include "windowing/WindowingFactory.h" +#include "guilib/GraphicContext.h" +#include "threads/SingleLock.h" +#include "utils/log.h" +#include "utils/TimeUtils.h" +#include <string> + +using namespace std; + +Display* CVideoSyncGLX::m_Dpy = NULL; + +void CVideoSyncGLX::OnLostDevice() +{ + if (!m_displayLost) + { + m_displayLost = true; + m_lostEvent.Wait(); + } +} + +void CVideoSyncGLX::OnResetDevice() +{ + m_displayReset = true; +} + +bool CVideoSyncGLX::Setup(PUPDATECLOCK func) +{ + CSingleLock lock(g_graphicsContext); + + m_glXWaitVideoSyncSGI = NULL; + m_glXGetVideoSyncSGI = NULL; + m_vInfo = NULL; + m_Window = 0; + m_Context = NULL; + UpdateClock = func; + + int singleBufferAttributes[] = { + GLX_RGBA, + GLX_RED_SIZE, 0, + GLX_GREEN_SIZE, 0, + GLX_BLUE_SIZE, 0, + None + }; + + int ReturnV, SwaMask; + unsigned int GlxTest; + XSetWindowAttributes Swa; + + m_vInfo = NULL; + m_Context = NULL; + m_Window = 0; + + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Setting up GLX"); + + g_Windowing.Register(this); + + m_displayLost = false; + m_displayReset = false; + m_lostEvent.Reset(); + + if (!m_Dpy) + { + m_Dpy = XOpenDisplay(NULL); + if (!m_Dpy) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Unable to open display"); + return false; + } + } + + if (!glXQueryExtension(m_Dpy, NULL, NULL)) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX"); + return false; + } + + bool ExtensionFound = false; + istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); + string ExtensionStr; + + while (!ExtensionFound) + { + Extensions >> ExtensionStr; + if (Extensions.fail()) + break; + + if (ExtensionStr == "GLX_SGI_video_sync") + ExtensionFound = true; + } + + if (!ExtensionFound) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX_SGI_video_sync"); + return false; + } + + m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); + if (!m_vInfo) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); + return false; + } + + Swa.border_pixel = 0; + Swa.event_mask = StructureNotifyMask; + Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); + SwaMask = CWBorderPixel | CWColormap | CWEventMask; + + m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, + m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); + + m_Context = glXCreateContext(m_Dpy, m_vInfo, NULL, True); + if (!m_Context) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXCreateContext returned NULL"); + return false; + } + + ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); + if (ReturnV != True) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); + return false; + } + + m_glXWaitVideoSyncSGI = (int (*)(int, int, unsigned int*))glXGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI"); + if (!m_glXWaitVideoSyncSGI) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI not found"); + return false; + } + + ReturnV = m_glXWaitVideoSyncSGI(2, 0, &GlxTest); + if (ReturnV) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); + return false; + } + + m_glXGetVideoSyncSGI = (int (*)(unsigned int*))glXGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI"); + if (!m_glXGetVideoSyncSGI) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI not found"); + return false; + } + + ReturnV = m_glXGetVideoSyncSGI(&GlxTest); + if (ReturnV) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI returned %i", ReturnV); + return false; + } + + return true; +} + +void CVideoSyncGLX::Run(volatile bool& stop) +{ + unsigned int PrevVblankCount; + unsigned int VblankCount; + int ReturnV; + bool IsReset = false; + int64_t Now; + + //get the current vblank counter + m_glXGetVideoSyncSGI(&VblankCount); + PrevVblankCount = VblankCount; + + while(!stop && !m_displayLost && !m_displayReset) + { + //wait for the next vblank + ReturnV = m_glXWaitVideoSyncSGI(2, (VblankCount + 1) % 2, &VblankCount); + m_glXGetVideoSyncSGI(&VblankCount); //the vblank count returned by glXWaitVideoSyncSGI is not always correct + Now = CurrentHostCounter(); //get the timestamp of this vblank + + if(ReturnV) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); + return; + } + + if (VblankCount > PrevVblankCount) + { + UpdateClock((int)(VblankCount - PrevVblankCount), Now); + IsReset = false; + } + else + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Vblank counter has reset"); + + //only try reattaching once + if (IsReset) + return; + + //because of a bug in the nvidia driver, glXWaitVideoSyncSGI breaks when the vblank counter resets + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detaching glX context"); + ReturnV = glXMakeCurrent(m_Dpy, None, NULL); + if (ReturnV != True) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); + return; + } + + //sleep here so we don't busy spin when this constantly happens, for example when the display went to sleep + Sleep(1000); + + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Attaching glX context"); + ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); + if (ReturnV != True) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); + return; + } + + m_glXGetVideoSyncSGI(&VblankCount); + + IsReset = true; + } + PrevVblankCount = VblankCount; + } + m_lostEvent.Set(); + while(!stop && m_displayLost && !m_displayReset) + { + Sleep(10); + } +} + +void CVideoSyncGLX::Cleanup() +{ + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cleaning up GLX"); + CSingleLock lock(g_graphicsContext); + + if (m_vInfo) + { + XFree(m_vInfo); + m_vInfo = NULL; + } + if (m_Context) + { + glXMakeCurrent(m_Dpy, None, NULL); + glXDestroyContext(m_Dpy, m_Context); + m_Context = NULL; + } + if (m_Window) + { + XDestroyWindow(m_Dpy, m_Window); + m_Window = 0; + } + + m_lostEvent.Set(); + g_Windowing.Unregister(this); +} + +float CVideoSyncGLX::GetFps() +{ + m_fps = g_graphicsContext.GetFPS(); + return m_fps; +} + +#endif diff --git a/xbmc/video/videosync/VideoSyncGLX.h b/xbmc/video/videosync/VideoSyncGLX.h new file mode 100644 index 0000000000..38d719defc --- /dev/null +++ b/xbmc/video/videosync/VideoSyncGLX.h @@ -0,0 +1,55 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#if defined(HAS_GLX) + +#include "video/videosync/VideoSync.h" +#include "system_gl.h" +#include <X11/X.h> +#include <X11/Xlib.h> +#include <GL/glx.h> +#include "guilib/DispResource.h" +#include "threads/Event.h" + +class CVideoSyncGLX : public CVideoSync, IDispResource +{ +public: + virtual bool Setup(PUPDATECLOCK func); + virtual void Run(volatile bool& stop); + virtual void Cleanup(); + virtual float GetFps(); + virtual void OnLostDevice(); + virtual void OnResetDevice(); + +private: + int (*m_glXWaitVideoSyncSGI) (int, int, unsigned int*); + int (*m_glXGetVideoSyncSGI) (unsigned int*); + + static Display* m_Dpy; + XVisualInfo *m_vInfo; + Window m_Window; + GLXContext m_Context; + volatile bool m_displayLost; + volatile bool m_displayReset; + CEvent m_lostEvent; +}; + +#endif diff --git a/xbmc/video/videosync/VideoSyncPi.cpp b/xbmc/video/videosync/VideoSyncPi.cpp new file mode 100644 index 0000000000..debe85b0bc --- /dev/null +++ b/xbmc/video/videosync/VideoSyncPi.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" + +#if defined(TARGET_RASPBERRY_PI) + +#include "video/videosync/VideoSyncPi.h" +#include "guilib/GraphicContext.h" +#include "windowing/WindowingFactory.h" +#include "utils/TimeUtils.h" +#include "utils/log.h" +#include "linux/RBP.h" +#include "threads/Thread.h" + +bool CVideoSyncPi::Setup(PUPDATECLOCK func) +{ + UpdateClock = func; + m_abort = false; + g_Windowing.Register(this); + CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up RPi"); + return true; +} + +void CVideoSyncPi::Run(volatile bool& stop) +{ + /* This shouldn't be very busy and timing is important so increase priority */ + CThread::GetCurrentThread()->SetPriority(CThread::GetCurrentThread()->GetPriority()+1); + + while (!stop && !m_abort) + { + g_RBP.WaitVsync(); + uint64_t now = CurrentHostCounter(); + UpdateClock(1, now); + } +} + +void CVideoSyncPi::Cleanup() +{ + CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up RPi"); + g_Windowing.Unregister(this); +} + +float CVideoSyncPi::GetFps() +{ + m_fps = g_graphicsContext.GetFPS(); + CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.2f", m_fps); + return m_fps; +} + +void CVideoSyncPi::OnResetDevice() +{ + m_abort = true; +} + +#endif diff --git a/xbmc/video/videosync/VideoSyncPi.h b/xbmc/video/videosync/VideoSyncPi.h new file mode 100644 index 0000000000..783cd19a5b --- /dev/null +++ b/xbmc/video/videosync/VideoSyncPi.h @@ -0,0 +1,39 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#if defined(TARGET_RASPBERRY_PI) + +#include "video/videosync/VideoSync.h" +#include "guilib/DispResource.h" + +class CVideoSyncPi : public CVideoSync, IDispResource +{ +public: + virtual bool Setup(PUPDATECLOCK func); + virtual void Run(volatile bool& stop); + virtual void Cleanup(); + virtual float GetFps(); + virtual void OnResetDevice(); +private: + volatile bool m_abort; +}; + +#endif diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp index 707cf4f1b3..ca9d83930a 100644 --- a/xbmc/video/windows/GUIWindowVideoBase.cpp +++ b/xbmc/video/windows/GUIWindowVideoBase.cpp @@ -1453,7 +1453,6 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) if (item->m_bIsFolder) { - m_database.SetPathHash(strPath,""); // to force scan OnScan(strPath, true); } else diff --git a/xbmc/view/GUIViewControl.cpp b/xbmc/view/GUIViewControl.cpp index cafd582f32..3205fdc657 100644 --- a/xbmc/view/GUIViewControl.cpp +++ b/xbmc/view/GUIViewControl.cpp @@ -175,6 +175,22 @@ int CGUIViewControl::GetSelectedItem() const return GetSelectedItem(m_visibleViews[m_currentView]); } +std::string CGUIViewControl::GetSelectedItemPath() const +{ + if (m_currentView < 0 || (size_t)m_currentView >= m_visibleViews.size()) + return ""; + + int selectedItem = GetSelectedItem(m_visibleViews[m_currentView]); + if (selectedItem > -1) + { + CFileItemPtr fileItem = m_fileItems->Get(selectedItem); + if (fileItem) + return fileItem->GetPath(); + } + + return ""; +} + void CGUIViewControl::SetSelectedItem(int item) { if (!m_fileItems || item < 0 || item >= m_fileItems->Size()) diff --git a/xbmc/view/GUIViewControl.h b/xbmc/view/GUIViewControl.h index ba9f6ec52e..4da81a48bd 100644 --- a/xbmc/view/GUIViewControl.h +++ b/xbmc/view/GUIViewControl.h @@ -46,6 +46,7 @@ public: void SetSelectedItem(const std::string &itemPath); int GetSelectedItem() const; + std::string GetSelectedItemPath() const; void SetFocused(); bool HasControl(int controlID) const; diff --git a/xbmc/windowing/WinEventsSDL.cpp b/xbmc/windowing/WinEventsSDL.cpp index bbc8d60a43..02d6d22935 100644 --- a/xbmc/windowing/WinEventsSDL.cpp +++ b/xbmc/windowing/WinEventsSDL.cpp @@ -233,6 +233,8 @@ bool CWinEventsSDL::MessagePump() case SDL_JOYAXISMOTION: case SDL_JOYBALLMOTION: case SDL_JOYHATMOTION: + case SDL_JOYDEVICEADDED: + case SDL_JOYDEVICEREMOVED: g_Joystick.Update(event); ret = true; break; diff --git a/xbmc/windowing/WinEventsSDL.h b/xbmc/windowing/WinEventsSDL.h index 930db45326..42fd1467a3 100644 --- a/xbmc/windowing/WinEventsSDL.h +++ b/xbmc/windowing/WinEventsSDL.h @@ -25,7 +25,11 @@ #include "system.h" #ifdef HAS_SDL +#if SDL_VERSION == 1 #include <SDL/SDL_events.h> +#elif SDL_VERSION == 2 +#include <SDL/SDL_events.h> +#endif #include "WinEvents.h" diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp index d3eb136071..869fb1d582 100644 --- a/xbmc/windowing/WinEventsX11.cpp +++ b/xbmc/windowing/WinEventsX11.cpp @@ -613,6 +613,8 @@ bool CWinEventsX11Imp::MessagePump() case SDL_JOYAXISMOTION: case SDL_JOYBALLMOTION: case SDL_JOYHATMOTION: + case SDL_JOYDEVICEADDED: + case SDL_JOYDEVICEREMOVED: g_Joystick.Update(event); ret = true; break; diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp index 62887135d6..83ad7df098 100644 --- a/xbmc/windowing/X11/WinSystemX11.cpp +++ b/xbmc/windowing/X11/WinSystemX11.cpp @@ -38,6 +38,7 @@ #include "utils/StringUtils.h" #include "settings/Settings.h" #include "windowing/WindowingFactory.h" +#include "CompileInfo.h" #include <X11/Xatom.h> #if defined(HAS_XRANDR) @@ -216,10 +217,13 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n } } - if(m_nWidth == newWidth - && m_nHeight == newHeight - && m_userOutput.compare(m_currentOutput) == 0) + if(m_nWidth == newWidth && + m_nHeight == newHeight && + m_userOutput.compare(m_currentOutput) == 0) + { + UpdateCrtc(); return true; + } if (!SetWindow(newWidth, newHeight, false, m_userOutput)) { @@ -1174,8 +1178,9 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: XWMHints *wm_hints; XClassHint *class_hints; XTextProperty windowName, iconName; - std::string titleString = "XBMC Media Center"; - std::string classString = "xbmc.bin"; + + std::string titleString = CCompileInfo::GetAppName(); + std::string classString = titleString; char *title = (char*)titleString.c_str(); XStringListToTextProperty(&title, 1, &windowName); @@ -1230,6 +1235,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: #endif } + UpdateCrtc(); + return true; } @@ -1421,4 +1428,16 @@ bool CWinSystemX11::HasWindowManager() return true; } +void CWinSystemX11::UpdateCrtc() +{ + XWindowAttributes winattr; + int posx, posy; + Window child; + XGetWindowAttributes(m_dpy, m_mainWindow, &winattr); + XTranslateCoordinates(m_dpy, m_mainWindow, RootWindow(m_dpy, m_nScreen), winattr.x, winattr.y, + &posx, &posy, &child); + + m_crtc = g_xrandr.GetCrtc(posx+winattr.width/2, posy+winattr.height/2); +} + #endif diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h index 35ae99fbef..d15655482d 100644 --- a/xbmc/windowing/X11/WinSystemX11.h +++ b/xbmc/windowing/X11/WinSystemX11.h @@ -87,6 +87,7 @@ public: void GetConnectedOutputs(std::vector<CStdString> *outputs); bool IsCurrentOutput(CStdString output); void RecreateWindow(); + int GetCrtc() { return m_crtc; } protected: bool RefreshGlxContext(bool force); @@ -118,12 +119,14 @@ protected: bool m_bIsInternalXrr; bool m_newGlContext; int m_MouseX, m_MouseY; + int m_crtc; private: bool IsSuitableVisual(XVisualInfo *vInfo); static int XErrorHandler(Display* dpy, XErrorEvent* error); bool CreateIconPixmap(); bool HasWindowManager(); + void UpdateCrtc(); CStopWatch m_screensaverReset; }; diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp index c94f2e3801..d9d7a8fb1c 100644 --- a/xbmc/windowing/X11/XRandR.cpp +++ b/xbmc/windowing/X11/XRandR.cpp @@ -30,6 +30,7 @@ #include "utils/StringUtils.h" #include "../xbmc/utils/log.h" #include "threads/SystemClock.h" +#include "CompileInfo.h" #if defined(TARGET_FREEBSD) #include <sys/types.h> @@ -54,7 +55,7 @@ bool CXRandR::Query(bool force, bool ignoreoff) m_bInit = true; - if (getenv("XBMC_BIN_HOME") == NULL) + if (getenv("APP_BIN_HOME") == NULL) return false; m_outputs.clear(); @@ -71,10 +72,15 @@ bool CXRandR::Query(bool force, bool ignoreoff) bool CXRandR::Query(bool force, int screennum, bool ignoreoff) { - CStdString cmd; - cmd = getenv("XBMC_BIN_HOME"); - cmd += "/xbmc-xrandr"; - cmd = StringUtils::Format("%s -q --screen %d", cmd.c_str(), screennum); + std::string cmd; + std::string appname = CCompileInfo::GetAppName(); + StringUtils::ToLower(appname); + if (getenv("APP_BIN_HOME")) + { + cmd = getenv("APP_BIN_HOME"); + cmd += "/" + appname + "-xrandr"; + cmd = StringUtils::Format("%s -q --screen %d", cmd.c_str(), screennum); + } FILE* file = popen(cmd.c_str(),"r"); if (!file) @@ -111,6 +117,7 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff) xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0); xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0); xoutput.y = (output->Attribute("y") != NULL ? atoi(output->Attribute("y")) : 0); + xoutput.crtc = (output->Attribute("crtc") != NULL ? atoi(output->Attribute("crtc")) : 0); xoutput.wmm = (output->Attribute("wmm") != NULL ? atoi(output->Attribute("wmm")) : 0); xoutput.hmm = (output->Attribute("hmm") != NULL ? atoi(output->Attribute("hmm")) : 0); if (output->Attribute("rotation") != NULL @@ -153,10 +160,16 @@ bool CXRandR::TurnOffOutput(CStdString name) if (!output) return false; - CStdString cmd; - cmd = getenv("XBMC_BIN_HOME"); - cmd += "/xbmc-xrandr"; - cmd = StringUtils::Format("%s --screen %d --output %s --off", cmd.c_str(), output->screen, name.c_str()); + std::string cmd; + std::string appname = CCompileInfo::GetAppName(); + StringUtils::ToLower(appname); + + if (getenv("APP_BIN_HOME")) + { + cmd = getenv("APP_BIN_HOME"); + cmd += "/" + appname + "-xrandr"; + cmd = StringUtils::Format("%s --screen %d --output %s --off", cmd.c_str(), output->screen, name.c_str()); + } int status = system(cmd.c_str()); if (status == -1) @@ -312,9 +325,12 @@ bool CXRandR::SetMode(XOutput output, XMode mode) m_currentOutput = outputFound.name; m_currentMode = modeFound.id; + std::string appname = CCompileInfo::GetAppName(); + StringUtils::ToLower(appname); char cmd[255]; - if (getenv("XBMC_BIN_HOME")) - snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --screen %d --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str()); + + if (getenv("APP_BIN_HOME")) + snprintf(cmd, sizeof(cmd), "%s/%s-xrandr --screen %d --output %s --mode %s", getenv("APP_BIN_HOME"),appname.c_str(), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str()); else return false; CLog::Log(LOGINFO, "XRANDR: %s", cmd); @@ -401,20 +417,23 @@ void CXRandR::LoadCustomModeLinesToAllOutputs(void) StringUtils::Trim(name); strModeLine = modeline->FirstChild()->Value(); StringUtils::Trim(strModeLine); - if (getenv("XBMC_BIN_HOME")) + std::string appname = CCompileInfo::GetAppName(); + StringUtils::ToLower(appname); + + if (getenv("APP_BIN_HOME")) { - snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --newmode \"%s\" %s > /dev/null 2>&1", getenv("XBMC_BIN_HOME"), - name.c_str(), strModeLine.c_str()); + snprintf(cmd, sizeof(cmd), "%s/%s-xrandr --newmode \"%s\" %s > /dev/null 2>&1", getenv("APP_BIN_HOME"), + appname.c_str(), name.c_str(), strModeLine.c_str()); if (system(cmd) != 0) CLog::Log(LOGERROR, "Unable to create modeline \"%s\"", name.c_str()); } for (unsigned int i = 0; i < m_outputs.size(); i++) { - if (getenv("XBMC_BIN_HOME")) + if (getenv("APP_BIN_HOME")) { - snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --addmode %s \"%s\" > /dev/null 2>&1", getenv("XBMC_BIN_HOME"), - m_outputs[i].name.c_str(), name.c_str()); + snprintf(cmd, sizeof(cmd), "%s/%s-xrandr --addmode %s \"%s\" > /dev/null 2>&1", getenv("APP_BIN_HOME"), + appname.c_str(), m_outputs[i].name.c_str(), name.c_str()); if (system(cmd) != 0) CLog::Log(LOGERROR, "Unable to add modeline \"%s\"", name.c_str()); } @@ -459,6 +478,24 @@ XOutput* CXRandR::GetOutput(CStdString outputName) return result; } +int CXRandR::GetCrtc(int x, int y) +{ + int crtc = 0; + for (unsigned int i = 0; i < m_outputs.size(); ++i) + { + if (!m_outputs[i].isConnected) + continue; + + if ((m_outputs[i].x <= x && (m_outputs[i].x+m_outputs[i].w) > x) && + (m_outputs[i].y <= y && (m_outputs[i].y+m_outputs[i].h) > y)) + { + crtc = m_outputs[i].crtc; + break; + } + } + return crtc; +} + CXRandR g_xrandr; #endif // HAS_XRANDR diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h index ab7cc63ea6..4538bad7a9 100644 --- a/xbmc/windowing/X11/XRandR.h +++ b/xbmc/windowing/X11/XRandR.h @@ -84,6 +84,7 @@ public: int h; int x; int y; + int crtc; int wmm; int hmm; std::vector<XMode> modes; @@ -107,6 +108,7 @@ public: bool IsOutputConnected(CStdString name); bool TurnOffOutput(CStdString name); bool TurnOnOutput(CStdString name); + int GetCrtc(int x, int y); //bool Has1080i(); //bool Has1080p(); //bool Has720p(); diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index 6de3532619..d2a94c92f4 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -29,6 +29,8 @@ #include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "settings/DisplaySettings.h" +#include "guilib/DispResource.h" +#include "threads/SingleLock.h" #include "utils/log.h" #include "EGLWrapper.h" #include "EGLQuirks.h" @@ -282,6 +284,11 @@ bool CWinSystemEGL::CreateNewWindow(const CStdString& name, bool fullScreen, RES } Show(); + CSingleLock lock(m_resourceSection); + // tell any shared resources + for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++) + (*i)->OnResetDevice(); + return true; } @@ -472,6 +479,20 @@ bool CWinSystemEGL::Show(bool raise) return m_egl->ShowWindow(true); } +void CWinSystemEGL::Register(IDispResource *resource) +{ + CSingleLock lock(m_resourceSection); + m_resources.push_back(resource); +} + +void CWinSystemEGL::Unregister(IDispResource* resource) +{ + CSingleLock lock(m_resourceSection); + std::vector<IDispResource*>::iterator i = find(m_resources.begin(), m_resources.end(), resource); + if (i != m_resources.end()) + m_resources.erase(i); +} + EGLDisplay CWinSystemEGL::GetEGLDisplay() { return m_display; diff --git a/xbmc/windowing/egl/WinSystemEGL.h b/xbmc/windowing/egl/WinSystemEGL.h index 6c15471592..654889540c 100644 --- a/xbmc/windowing/egl/WinSystemEGL.h +++ b/xbmc/windowing/egl/WinSystemEGL.h @@ -29,6 +29,7 @@ #include "windowing/WinSystem.h" class CEGLWrapper; +class IDispResource; class CWinSystemEGL : public CWinSystemBase, public CRenderSystemGLES { @@ -55,6 +56,8 @@ public: virtual bool Restore() ; virtual bool Hide(); virtual bool Show(bool raise = true); + virtual void Register(IDispResource *resource); + virtual void Unregister(IDispResource *resource); virtual bool Support3D(int width, int height, uint32_t mode) const; virtual bool ClampToGUIDisplayLimits(int &width, int &height); @@ -79,6 +82,8 @@ protected: CEGLWrapper *m_egl; std::string m_extensions; + CCriticalSection m_resourceSection; + std::vector<IDispResource*> m_resources; }; XBMC_GLOBAL_REF(CWinSystemEGL,g_Windowing); diff --git a/xbmc/windowing/osx/WinSystemIOS.h b/xbmc/windowing/osx/WinSystemIOS.h index 049e0c8291..c34110a6e6 100644 --- a/xbmc/windowing/osx/WinSystemIOS.h +++ b/xbmc/windowing/osx/WinSystemIOS.h @@ -30,6 +30,7 @@ #include "threads/CriticalSection.h" class IDispResource; +class CVideoSyncCocoa; class CWinSystemIOS : public CWinSystemBase, public CRenderSystemGLES { @@ -67,7 +68,8 @@ public: virtual int GetNumScreens(); virtual int GetCurrentScreen(); - void InitDisplayLink(void); + void InitDisplayLink(CVideoSyncCocoa *syncImpl); + void VblankHandler(int64_t nowtime, double fps); void DeinitDisplayLink(void); double GetDisplayLinkFPS(void); void OnAppFocusChange(bool focus); @@ -85,6 +87,7 @@ protected: CCriticalSection m_resourceSection; std::vector<IDispResource*> m_resources; bool m_bIsBackgrounded; + CVideoSyncCocoa *m_VideoSync; private: bool GetScreenResolution(int* w, int* h, double* fps, int screenIdx); diff --git a/xbmc/windowing/osx/WinSystemIOS.mm b/xbmc/windowing/osx/WinSystemIOS.mm index 11abe30f84..5639a9604d 100644 --- a/xbmc/windowing/osx/WinSystemIOS.mm +++ b/xbmc/windowing/osx/WinSystemIOS.mm @@ -36,6 +36,7 @@ #include "utils/StringUtils.h" #include "guilib/DispResource.h" #include "threads/SingleLock.h" +#include "video/videosync/VideoSyncCocoa.h" #include <vector> #undef BOOL @@ -43,7 +44,7 @@ #import <OpenGLES/ES2/gl.h> #import <OpenGLES/ES2/glext.h> #if defined(TARGET_DARWIN_IOS_ATV2) -#import "atv2/XBMCController.h" +#import "atv2/KodiController.h" #else #import "ios/XBMCController.h" #endif @@ -57,6 +58,7 @@ CWinSystemIOS::CWinSystemIOS() : CWinSystemBase() m_iVSyncErrors = 0; m_bIsBackgrounded = false; + m_VideoSync = NULL; } CWinSystemIOS::~CWinSystemIOS() @@ -344,8 +346,15 @@ void CWinSystemIOS::OnAppFocusChange(bool focus) (*i)->OnAppFocusChange(focus); } -void CWinSystemIOS::InitDisplayLink(void) +void CWinSystemIOS::VblankHandler(int64_t nowtime, double fps) { + if (m_VideoSync) + m_VideoSync->VblankHandler(nowtime, fps); +} + +void CWinSystemIOS::InitDisplayLink(CVideoSyncCocoa *syncImpl) +{ + m_VideoSync = syncImpl; } void CWinSystemIOS::DeinitDisplayLink(void) { diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm index 7689546820..59ca25aa1a 100644 --- a/xbmc/windowing/osx/WinSystemOSX.mm +++ b/xbmc/windowing/osx/WinSystemOSX.mm @@ -26,6 +26,7 @@ #include "WinSystemOSX.h" #include "WinEventsOSX.h" #include "Application.h" +#include "CompileInfo.h" #include "guilib/DispResource.h" #include "guilib/GUIWindowManager.h" #include "settings/DisplaySettings.h" @@ -729,10 +730,10 @@ bool CWinSystemOSX::CreateNewWindow(const CStdString& name, bool fullScreen, RES [new_context makeCurrentContext]; // set the window title - NSString *string; - string = [ [ NSString alloc ] initWithUTF8String:"XBMC Media Center" ]; + NSMutableString *string; + string = [NSMutableString stringWithUTF8String:CCompileInfo::GetAppName()]; + [string appendString:@" Entertainment Center" ]; [ [ [new_context view] window] setTitle:string ]; - [ string release ]; m_glContext = new_context; m_lastOwnedContext = new_context; diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp index 1a873078b8..e190de3c3f 100644 --- a/xbmc/windows/GUIMediaWindow.cpp +++ b/xbmc/windows/GUIMediaWindow.cpp @@ -364,7 +364,7 @@ bool CGUIMediaWindow::OnMessage(CGUIMessage& message) m_vecItems->IsSourcesPath()) && IsActive()) { int iItem = m_viewControl.GetSelectedItem(); - Refresh(); + Refresh(true); m_viewControl.SetSelectedItem(iItem); } return true; @@ -1928,6 +1928,12 @@ bool CGUIMediaWindow::IsFiltered() (m_canFilterAdvanced && !m_filter.IsEmpty()); } +bool CGUIMediaWindow::IsSameStartFolder(const std::string &dir) +{ + const std::string startFolder = GetStartFolder(dir); + return StringUtils::StartsWith(m_vecItems->GetPath(), startFolder); +} + bool CGUIMediaWindow::Filter(bool advanced /* = true */) { // basic filtering diff --git a/xbmc/windows/GUIMediaWindow.h b/xbmc/windows/GUIMediaWindow.h index 0be9c3090b..40b65b2a5f 100644 --- a/xbmc/windows/GUIMediaWindow.h +++ b/xbmc/windows/GUIMediaWindow.h @@ -51,6 +51,7 @@ public: virtual bool CanFilterAdvanced() { return m_canFilterAdvanced; } virtual bool IsFiltered(); + virtual bool IsSameStartFolder(const std::string &dir); protected: virtual void LoadAdditionalTags(TiXmlElement *root); diff --git a/xbmc/windows/GUIWindowDebugInfo.cpp b/xbmc/windows/GUIWindowDebugInfo.cpp index 5de435e278..47638e071a 100644 --- a/xbmc/windows/GUIWindowDebugInfo.cpp +++ b/xbmc/windows/GUIWindowDebugInfo.cpp @@ -24,6 +24,7 @@ #include "addons/Skin.h" #include "utils/CPUInfo.h" #include "utils/log.h" +#include "CompileInfo.h" #include "input/ButtonTranslator.h" #include "guilib/GUIControlFactory.h" #include "guilib/GUIFontManager.h" @@ -103,12 +104,14 @@ void CGUIWindowDebugInfo::Process(unsigned int currentTime, CDirtyRegionList &di GlobalMemoryStatusEx(&stat); CStdString profiling = CGUIControlProfiler::IsRunning() ? " (profiling)" : ""; CStdString strCores = g_cpuInfo.GetCoresUsageString(); + std::string lcAppName = CCompileInfo::GetAppName(); + StringUtils::ToLower(lcAppName); #if !defined(TARGET_POSIX) - info = StringUtils::Format("LOG: %sxbmc.log\nMEM: %" PRIu64"/%" PRIu64" KB - FPS: %2.1f fps\nCPU: %s%s", g_advancedSettings.m_logFolder.c_str(), + info = StringUtils::Format("LOG: %s%s.log\nMEM: %" PRIu64"/%" PRIu64" KB - FPS: %2.1f fps\nCPU: %s%s", g_advancedSettings.m_logFolder.c_str(), lcAppName.c_str(), stat.ullAvailPhys/1024, stat.ullTotalPhys/1024, g_infoManager.GetFPS(), strCores.c_str(), profiling.c_str()); #else double dCPU = m_resourceCounter.GetCPUUsage(); - info = StringUtils::Format("LOG: %sxbmc.log\nMEM: %" PRIu64"/%" PRIu64" KB - FPS: %2.1f fps\nCPU: %s (CPU-XBMC %4.2f%%%s)", g_advancedSettings.m_logFolder.c_str(), + info = StringUtils::Format("LOG: %s%s.log\nMEM: %" PRIu64"/%" PRIu64" KB - FPS: %2.1f fps\nCPU: %s (CPU-XBMC %4.2f%%%s)", g_advancedSettings.m_logFolder.c_str(), lcAppName.c_str(), stat.ullAvailPhys/1024, stat.ullTotalPhys/1024, g_infoManager.GetFPS(), strCores.c_str(), dCPU, profiling.c_str()); #endif } |