From 9d11b08ad61b1f0d6d7023ce403285d8662efaed Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 4 Mar 2015 00:23:39 +0100 Subject: sync with upstream --- xbmc/addons/Addon.cpp | 653 ------ xbmc/addons/Addon.h | 278 --- xbmc/addons/AddonCallbacks.cpp | 173 -- xbmc/addons/AddonCallbacks.h | 466 ---- xbmc/addons/AddonCallbacksAddon.cpp | 532 ----- xbmc/addons/AddonCallbacksAddon.h | 73 - xbmc/addons/AddonCallbacksCodec.cpp | 116 - xbmc/addons/AddonCallbacksCodec.h | 46 - xbmc/addons/AddonCallbacksGUI.cpp | 2281 -------------------- xbmc/addons/AddonCallbacksGUI.h | 272 --- xbmc/addons/AddonCallbacksPVR.cpp | 324 --- xbmc/addons/AddonCallbacksPVR.h | 166 -- xbmc/addons/AddonDatabase.cpp | 797 ------- xbmc/addons/AddonDatabase.h | 175 -- xbmc/addons/AddonDll.h | 572 ----- xbmc/addons/AddonInstaller.cpp | 974 --------- xbmc/addons/AddonInstaller.h | 229 -- xbmc/addons/AddonManager.cpp | 1030 --------- xbmc/addons/AddonManager.h | 253 --- xbmc/addons/AddonStatusHandler.cpp | 175 -- xbmc/addons/AddonStatusHandler.h | 56 - xbmc/addons/AddonVersion.cpp | 138 -- xbmc/addons/AddonVersion.h | 72 - xbmc/addons/AudioEncoder.cpp | 90 - xbmc/addons/AudioEncoder.h | 51 - xbmc/addons/ContextItemAddon.cpp | 108 - xbmc/addons/ContextItemAddon.h | 72 - xbmc/addons/DllAddon.h | 70 - xbmc/addons/DllLibCPluff.h | 116 - xbmc/addons/DllPVRClient.h | 29 - xbmc/addons/GUIDialogAddonInfo.cpp | 458 ---- xbmc/addons/GUIDialogAddonInfo.h | 80 - xbmc/addons/GUIDialogAddonSettings.cpp | 1200 ---------- xbmc/addons/GUIDialogAddonSettings.h | 91 - xbmc/addons/GUIViewStateAddonBrowser.cpp | 132 -- xbmc/addons/GUIViewStateAddonBrowser.h | 35 - xbmc/addons/GUIWindowAddonBrowser.cpp | 677 ------ xbmc/addons/GUIWindowAddonBrowser.h | 79 - xbmc/addons/IAddon.h | 138 -- xbmc/addons/Makefile | 31 - xbmc/addons/PluginSource.cpp | 96 - xbmc/addons/PluginSource.h | 58 - xbmc/addons/Repository.cpp | 395 ---- xbmc/addons/Repository.h | 82 - xbmc/addons/Scraper.cpp | 1033 --------- xbmc/addons/Scraper.h | 178 -- xbmc/addons/ScreenSaver.cpp | 125 -- xbmc/addons/ScreenSaver.h | 47 - xbmc/addons/Service.cpp | 158 -- xbmc/addons/Service.h | 63 - xbmc/addons/Skin.cpp | 491 ----- xbmc/addons/Skin.h | 155 -- xbmc/addons/Visualisation.cpp | 486 ----- xbmc/addons/Visualisation.h | 111 - xbmc/addons/Webinterface.cpp | 75 - xbmc/addons/Webinterface.h | 54 - xbmc/addons/addon-bindings.mk | 4 +- xbmc/addons/include/NOTE | 12 - xbmc/addons/include/kodi_audiodec_dll.h | 60 + xbmc/addons/include/kodi_audiodec_types.h | 101 + xbmc/addons/test/Makefile | 9 - xbmc/addons/test/TestAddonVersion.cpp | 254 --- xbmc/cores/AudioEngine/Utils/AEChannelData.h | 128 ++ xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp | 184 -- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 359 --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp | 193 -- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h | 85 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp | 404 ---- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h | 68 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp | 197 -- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h | 60 - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 1767 --------------- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 172 -- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp | 391 ---- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h | 68 - .../dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp | 493 ----- .../dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h | 118 - .../dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp | 199 -- .../dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h | 60 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp | 89 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h | 31 - .../cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp | 247 --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h | 99 - .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 153 -- .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h | 30 - xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in | 19 - 86 files changed, 292 insertions(+), 22677 deletions(-) delete mode 100644 xbmc/addons/Addon.cpp delete mode 100644 xbmc/addons/Addon.h delete mode 100644 xbmc/addons/AddonCallbacks.cpp delete mode 100644 xbmc/addons/AddonCallbacks.h delete mode 100644 xbmc/addons/AddonCallbacksAddon.cpp delete mode 100644 xbmc/addons/AddonCallbacksAddon.h delete mode 100644 xbmc/addons/AddonCallbacksCodec.cpp delete mode 100644 xbmc/addons/AddonCallbacksCodec.h delete mode 100644 xbmc/addons/AddonCallbacksGUI.cpp delete mode 100644 xbmc/addons/AddonCallbacksGUI.h delete mode 100644 xbmc/addons/AddonCallbacksPVR.cpp delete mode 100644 xbmc/addons/AddonCallbacksPVR.h delete mode 100644 xbmc/addons/AddonDatabase.cpp delete mode 100644 xbmc/addons/AddonDatabase.h delete mode 100644 xbmc/addons/AddonDll.h delete mode 100644 xbmc/addons/AddonInstaller.cpp delete mode 100644 xbmc/addons/AddonInstaller.h delete mode 100644 xbmc/addons/AddonManager.cpp delete mode 100644 xbmc/addons/AddonManager.h delete mode 100644 xbmc/addons/AddonStatusHandler.cpp delete mode 100644 xbmc/addons/AddonStatusHandler.h delete mode 100644 xbmc/addons/AddonVersion.cpp delete mode 100644 xbmc/addons/AddonVersion.h delete mode 100644 xbmc/addons/AudioEncoder.cpp delete mode 100644 xbmc/addons/AudioEncoder.h delete mode 100644 xbmc/addons/ContextItemAddon.cpp delete mode 100644 xbmc/addons/ContextItemAddon.h delete mode 100644 xbmc/addons/DllAddon.h delete mode 100644 xbmc/addons/DllLibCPluff.h delete mode 100644 xbmc/addons/DllPVRClient.h delete mode 100644 xbmc/addons/GUIDialogAddonInfo.cpp delete mode 100644 xbmc/addons/GUIDialogAddonInfo.h delete mode 100644 xbmc/addons/GUIDialogAddonSettings.cpp delete mode 100644 xbmc/addons/GUIDialogAddonSettings.h delete mode 100644 xbmc/addons/GUIViewStateAddonBrowser.cpp delete mode 100644 xbmc/addons/GUIViewStateAddonBrowser.h delete mode 100644 xbmc/addons/GUIWindowAddonBrowser.cpp delete mode 100644 xbmc/addons/GUIWindowAddonBrowser.h delete mode 100644 xbmc/addons/IAddon.h delete mode 100644 xbmc/addons/Makefile delete mode 100644 xbmc/addons/PluginSource.cpp delete mode 100644 xbmc/addons/PluginSource.h delete mode 100644 xbmc/addons/Repository.cpp delete mode 100644 xbmc/addons/Repository.h delete mode 100644 xbmc/addons/Scraper.cpp delete mode 100644 xbmc/addons/Scraper.h delete mode 100644 xbmc/addons/ScreenSaver.cpp delete mode 100644 xbmc/addons/ScreenSaver.h delete mode 100644 xbmc/addons/Service.cpp delete mode 100644 xbmc/addons/Service.h delete mode 100644 xbmc/addons/Skin.cpp delete mode 100644 xbmc/addons/Skin.h delete mode 100644 xbmc/addons/Visualisation.cpp delete mode 100644 xbmc/addons/Visualisation.h delete mode 100644 xbmc/addons/Webinterface.cpp delete mode 100644 xbmc/addons/Webinterface.h delete mode 100644 xbmc/addons/include/NOTE create mode 100644 xbmc/addons/include/kodi_audiodec_dll.h create mode 100644 xbmc/addons/include/kodi_audiodec_types.h delete mode 100644 xbmc/addons/test/Makefile delete mode 100644 xbmc/addons/test/TestAddonVersion.cpp create mode 100644 xbmc/cores/AudioEngine/Utils/AEChannelData.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in (limited to 'xbmc') diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp deleted file mode 100644 index 2aa849f..0000000 --- a/xbmc/addons/Addon.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "Addon.h" -#include "AddonManager.h" -#include "settings/Settings.h" -#include "filesystem/Directory.h" -#include "filesystem/File.h" -#include "system.h" -#ifdef HAS_PYTHON -#include "interfaces/python/XBPython.h" -#endif -#if defined(TARGET_DARWIN) -#include "../osx/OSXGNUReplacements.h" -#endif -#ifdef TARGET_FREEBSD -#include "freebsd/FreeBSDGNUReplacements.h" -#endif -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" -#include "URL.h" -#include "Util.h" -#include -#include -#include - -using XFILE::CDirectory; -using XFILE::CFile; -using namespace std; - -namespace ADDON -{ - -/** - * helper functions - * - */ - -typedef struct -{ - const char* name; - TYPE type; - int pretty; - const char* icon; -} TypeMapping; - -static const TypeMapping types[] = - {{"unknown", ADDON_UNKNOWN, 0, "" }, - {"xbmc.metadata.scraper.albums", ADDON_SCRAPER_ALBUMS, 24016, "DefaultAddonAlbumInfo.png" }, - {"xbmc.metadata.scraper.artists", ADDON_SCRAPER_ARTISTS, 24017, "DefaultAddonArtistInfo.png" }, - {"xbmc.metadata.scraper.movies", ADDON_SCRAPER_MOVIES, 24007, "DefaultAddonMovieInfo.png" }, - {"xbmc.metadata.scraper.musicvideos", ADDON_SCRAPER_MUSICVIDEOS, 24015, "DefaultAddonMusicVideoInfo.png" }, - {"xbmc.metadata.scraper.tvshows", ADDON_SCRAPER_TVSHOWS, 24014, "DefaultAddonTvInfo.png" }, - {"xbmc.metadata.scraper.library", ADDON_SCRAPER_LIBRARY, 24083, "DefaultAddonInfoLibrary.png" }, - {"xbmc.ui.screensaver", ADDON_SCREENSAVER, 24008, "DefaultAddonScreensaver.png" }, - {"xbmc.player.musicviz", ADDON_VIZ, 24010, "DefaultAddonVisualization.png" }, - {"visualization-library", ADDON_VIZ_LIBRARY, 24084, "" }, - {"xbmc.python.pluginsource", ADDON_PLUGIN, 24005, "" }, - {"xbmc.python.script", ADDON_SCRIPT, 24009, "" }, - {"xbmc.python.weather", ADDON_SCRIPT_WEATHER, 24027, "DefaultAddonWeather.png" }, - {"xbmc.python.lyrics", ADDON_SCRIPT_LYRICS, 24013, "DefaultAddonLyrics.png" }, - {"xbmc.python.library", ADDON_SCRIPT_LIBRARY, 24081, "DefaultAddonHelper.png" }, - {"xbmc.python.module", ADDON_SCRIPT_MODULE, 24082, "DefaultAddonLibrary.png" }, - {"xbmc.subtitle.module", ADDON_SUBTITLE_MODULE, 24012, "DefaultAddonSubtitles.png" }, - {"kodi.context.item", ADDON_CONTEXT_ITEM, 24025, "DefaultAddonContextItem.png" }, - {"xbmc.gui.skin", ADDON_SKIN, 166, "DefaultAddonSkin.png" }, - {"xbmc.webinterface", ADDON_WEB_INTERFACE, 199, "DefaultAddonWebSkin.png" }, - {"xbmc.addon.repository", ADDON_REPOSITORY, 24011, "DefaultAddonRepository.png" }, - {"xbmc.pvrclient", ADDON_PVRDLL, 24019, "DefaultAddonPVRClient.png" }, - {"xbmc.addon.video", ADDON_VIDEO, 1037, "DefaultAddonVideo.png" }, - {"xbmc.addon.audio", ADDON_AUDIO, 1038, "DefaultAddonMusic.png" }, - {"xbmc.addon.image", ADDON_IMAGE, 1039, "DefaultAddonPicture.png" }, - {"xbmc.addon.executable", ADDON_EXECUTABLE, 1043, "DefaultAddonProgram.png" }, - {"xbmc.audioencoder", ADDON_AUDIOENCODER, 200, "DefaultAddonAudioEncoder.png" }, - {"xbmc.service", ADDON_SERVICE, 24018, "DefaultAddonService.png" }}; - -const std::string TranslateType(const ADDON::TYPE &type, bool pretty/*=false*/) -{ - for (unsigned int index=0; index < ARRAY_SIZE(types); ++index) - { - const TypeMapping &map = types[index]; - if (type == map.type) - { - if (pretty && map.pretty) - return g_localizeStrings.Get(map.pretty); - else - return map.name; - } - } - return ""; -} - -TYPE TranslateType(const std::string &string) -{ - for (unsigned int index=0; index < ARRAY_SIZE(types); ++index) - { - const TypeMapping &map = types[index]; - if (string == map.name) - return map.type; - } - - return ADDON_UNKNOWN; -} - -const std::string GetIcon(const ADDON::TYPE& type) -{ - for (unsigned int index=0; index < ARRAY_SIZE(types); ++index) - { - const TypeMapping &map = types[index]; - if (type == map.type) - return map.icon; - } - return ""; -} - -#define EMPTY_IF(x,y) \ - { \ - std::string fan=CAddonMgr::Get().GetExtValue(metadata->configuration, x); \ - if (fan == "true") \ - y.clear(); \ - } - -#define SS(x) (x) ? x : "" - -AddonProps::AddonProps(const cp_extension_t *ext) - : id(SS(ext->plugin->identifier)) - , version(SS(ext->plugin->version)) - , minversion(SS(ext->plugin->abi_bw_compatibility)) - , name(SS(ext->plugin->name)) - , path(SS(ext->plugin->plugin_path)) - , author(SS(ext->plugin->provider_name)) - , stars(0) -{ - if (ext->ext_point_id) - type = TranslateType(ext->ext_point_id); - - icon = "icon.png"; - fanart = URIUtils::AddFileToFolder(path, "fanart.jpg"); - changelog = URIUtils::AddFileToFolder(path, "changelog.txt"); - // Grab more detail from the props... - const cp_extension_t *metadata = CAddonMgr::Get().GetExtension(ext->plugin, "xbmc.addon.metadata"); //plugin, "kodi.addon.metadata"); - if (metadata) - { - summary = CAddonMgr::Get().GetTranslatedString(metadata->configuration, "summary"); - description = CAddonMgr::Get().GetTranslatedString(metadata->configuration, "description"); - disclaimer = CAddonMgr::Get().GetTranslatedString(metadata->configuration, "disclaimer"); - license = CAddonMgr::Get().GetExtValue(metadata->configuration, "license"); - std::string language; - language = CAddonMgr::Get().GetExtValue(metadata->configuration, "language"); - if (!language.empty()) - extrainfo.insert(make_pair("language",language)); - broken = CAddonMgr::Get().GetExtValue(metadata->configuration, "broken"); - EMPTY_IF("nofanart",fanart) - EMPTY_IF("noicon",icon) - EMPTY_IF("nochangelog",changelog) - } - BuildDependencies(ext->plugin); -} - -AddonProps::AddonProps(const cp_plugin_info_t *plugin) - : id(SS(plugin->identifier)) - , type(ADDON_UNKNOWN) - , version(SS(plugin->version)) - , minversion(SS(plugin->abi_bw_compatibility)) - , name(SS(plugin->name)) - , path(SS(plugin->plugin_path)) - , author(SS(plugin->provider_name)) - , stars(0) -{ - BuildDependencies(plugin); -} - -void AddonProps::Serialize(CVariant &variant) const -{ - variant["addonid"] = id; - variant["type"] = TranslateType(type); - variant["version"] = version.asString(); - variant["minversion"] = minversion.asString(); - variant["name"] = name; - variant["license"] = license; - variant["summary"] = summary; - variant["description"] = description; - variant["path"] = path; - variant["libname"] = libname; - variant["author"] = author; - variant["source"] = source; - - if (CURL::IsFullPath(icon)) - variant["icon"] = icon; - else - variant["icon"] = URIUtils::AddFileToFolder(path, icon); - - variant["thumbnail"] = variant["icon"]; - variant["disclaimer"] = disclaimer; - variant["changelog"] = changelog; - - if (CURL::IsFullPath(fanart)) - variant["fanart"] = fanart; - else - variant["fanart"] = URIUtils::AddFileToFolder(path, fanart); - - variant["dependencies"] = CVariant(CVariant::VariantTypeArray); - for (ADDONDEPS::const_iterator it = dependencies.begin(); it != dependencies.end(); ++it) - { - CVariant dep(CVariant::VariantTypeObject); - dep["addonid"] = it->first; - dep["version"] = it->second.first.asString(); - dep["optional"] = it->second.second; - variant["dependencies"].push_back(dep); - } - if (broken.empty()) - variant["broken"] = false; - else - variant["broken"] = broken; - variant["extrainfo"] = CVariant(CVariant::VariantTypeArray); - for (InfoMap::const_iterator it = extrainfo.begin(); it != extrainfo.end(); ++it) - { - CVariant info(CVariant::VariantTypeObject); - info["key"] = it->first; - info["value"] = it->second; - variant["extrainfo"].push_back(info); - } - variant["rating"] = stars; -} - -void AddonProps::BuildDependencies(const cp_plugin_info_t *plugin) -{ - if (!plugin) - return; - for (unsigned int i = 0; i < plugin->num_imports; ++i) - dependencies.insert(make_pair(std::string(plugin->imports[i].plugin_id), - make_pair(AddonVersion(SS(plugin->imports[i].version)), plugin->imports[i].optional != 0))); -} - -/** - * CAddon - * - */ - -CAddon::CAddon(const cp_extension_t *ext) - : m_props(ext) -{ - BuildLibName(ext); - Props().libname = m_strLibName; - BuildProfilePath(); - m_userSettingsPath = URIUtils::AddFileToFolder(Profile(), "settings.xml"); - m_enabled = true; - m_hasSettings = true; - m_hasStrings = false; - m_checkedStrings = false; - m_settingsLoaded = false; - m_userSettingsLoaded = false; -} - -CAddon::CAddon(const cp_plugin_info_t *plugin) - : m_props(plugin) -{ - m_enabled = true; - m_hasSettings = false; - m_hasStrings = false; - m_checkedStrings = true; - m_settingsLoaded = false; - m_userSettingsLoaded = false; -} - -CAddon::CAddon(const AddonProps &props) - : m_props(props) -{ - if (props.libname.empty()) BuildLibName(); - else m_strLibName = props.libname; - BuildProfilePath(); - m_userSettingsPath = URIUtils::AddFileToFolder(Profile(), "settings.xml"); - m_enabled = true; - m_hasSettings = true; - m_hasStrings = false; - m_checkedStrings = false; - m_settingsLoaded = false; - m_userSettingsLoaded = false; -} - -CAddon::CAddon(const CAddon &rhs) - : m_props(rhs.Props()), - m_settings(rhs.m_settings) -{ - m_addonXmlDoc = rhs.m_addonXmlDoc; - m_settingsLoaded = rhs.m_settingsLoaded; - m_userSettingsLoaded = rhs.m_userSettingsLoaded; - m_hasSettings = rhs.m_hasSettings; - BuildProfilePath(); - m_userSettingsPath = URIUtils::AddFileToFolder(Profile(), "settings.xml"); - m_strLibName = rhs.m_strLibName; - m_enabled = rhs.Enabled(); - m_hasStrings = false; - m_checkedStrings = false; -} - -AddonPtr CAddon::Clone() const -{ - return AddonPtr(new CAddon(*this)); -} - -bool CAddon::MeetsVersion(const AddonVersion &version) const -{ - return m_props.minversion <= version && version <= m_props.version; -} - -//TODO platform/path crap should be negotiated between the addon and -// the handler for it's type -void CAddon::BuildLibName(const cp_extension_t *extension) -{ - if (!extension) - { - m_strLibName = "default"; - std::string ext; - switch (m_props.type) - { - case ADDON_SCRAPER_ALBUMS: - case ADDON_SCRAPER_ARTISTS: - case ADDON_SCRAPER_MOVIES: - case ADDON_SCRAPER_MUSICVIDEOS: - case ADDON_SCRAPER_TVSHOWS: - case ADDON_SCRAPER_LIBRARY: - ext = ADDON_SCRAPER_EXT; - break; - case ADDON_SCREENSAVER: - ext = ADDON_SCREENSAVER_EXT; - break; - case ADDON_SKIN: - m_strLibName = "skin.xml"; - return; - case ADDON_VIZ: - ext = ADDON_VIS_EXT; - break; - case ADDON_PVRDLL: - ext = ADDON_PVRDLL_EXT; - break; - case ADDON_SCRIPT: - case ADDON_SCRIPT_LIBRARY: - case ADDON_SCRIPT_LYRICS: - case ADDON_SCRIPT_WEATHER: - case ADDON_SUBTITLE_MODULE: - case ADDON_PLUGIN: - case ADDON_SERVICE: - case ADDON_CONTEXT_ITEM: - ext = ADDON_PYTHON_EXT; - break; - default: - m_strLibName.clear(); - return; - } - // extensions are returned as *.ext - // so remove the asterisk - ext.erase(0,1); - m_strLibName.append(ext); - } - else - { - switch (m_props.type) - { - case ADDON_SCREENSAVER: - case ADDON_SCRIPT: - case ADDON_SCRIPT_LIBRARY: - case ADDON_SCRIPT_LYRICS: - case ADDON_SCRIPT_WEATHER: - case ADDON_SCRIPT_MODULE: - case ADDON_SUBTITLE_MODULE: - case ADDON_SCRAPER_ALBUMS: - case ADDON_SCRAPER_ARTISTS: - case ADDON_SCRAPER_MOVIES: - case ADDON_SCRAPER_MUSICVIDEOS: - case ADDON_SCRAPER_TVSHOWS: - case ADDON_SCRAPER_LIBRARY: - case ADDON_PVRDLL: - case ADDON_PLUGIN: - case ADDON_WEB_INTERFACE: - case ADDON_SERVICE: - case ADDON_REPOSITORY: - case ADDON_AUDIOENCODER: - case ADDON_CONTEXT_ITEM: - { - std::string temp = CAddonMgr::Get().GetExtValue(extension->configuration, "@library"); - m_strLibName = temp; - } - break; - default: - m_strLibName.clear(); - break; - } - } -} - -/** - * Language File Handling - */ -bool CAddon::LoadStrings() -{ - // Path where the language strings reside - std::string chosenPath = URIUtils::AddFileToFolder(m_props.path, "resources/language/"); - - m_hasStrings = m_strings.Load(chosenPath, CSettings::Get().GetString("locale.language")); - return m_checkedStrings = true; -} - -void CAddon::ClearStrings() -{ - // Unload temporary language strings - m_strings.Clear(); - m_hasStrings = false; -} - -std::string CAddon::GetString(uint32_t id) -{ - if (!m_hasStrings && ! m_checkedStrings && !LoadStrings()) - return ""; - - return m_strings.Get(id); -} - -/** - * Settings Handling - */ -bool CAddon::HasSettings() -{ - return LoadSettings(); -} - -bool CAddon::LoadSettings(bool bForce /* = false*/) -{ - if (m_settingsLoaded && !bForce) - return true; - if (!m_hasSettings) - return false; - std::string addonFileName = URIUtils::AddFileToFolder(m_props.path, "resources/settings.xml"); - - if (!m_addonXmlDoc.LoadFile(addonFileName)) - { - if (CFile::Exists(addonFileName)) - CLog::Log(LOGERROR, "Unable to load: %s, Line %d\n%s", addonFileName.c_str(), m_addonXmlDoc.ErrorRow(), m_addonXmlDoc.ErrorDesc()); - m_hasSettings = false; - return false; - } - - // Make sure that the addon XML has the settings element - TiXmlElement *setting = m_addonXmlDoc.RootElement(); - if (!setting || strcmpi(setting->Value(), "settings") != 0) - { - CLog::Log(LOGERROR, "Error loading Settings %s: cannot find root element 'settings'", addonFileName.c_str()); - return false; - } - SettingsFromXML(m_addonXmlDoc, true); - LoadUserSettings(); - m_settingsLoaded = true; - return true; -} - -bool CAddon::HasUserSettings() -{ - if (!LoadSettings()) - return false; - - return m_userSettingsLoaded; -} - -bool CAddon::ReloadSettings() -{ - return LoadSettings(true); -} - -bool CAddon::LoadUserSettings() -{ - m_userSettingsLoaded = false; - CXBMCTinyXML doc; - if (doc.LoadFile(m_userSettingsPath)) - m_userSettingsLoaded = SettingsFromXML(doc); - return m_userSettingsLoaded; -} - -void CAddon::SaveSettings(void) -{ - if (m_settings.empty()) - return; // no settings to save - - // break down the path into directories - std::string strAddon = URIUtils::GetDirectory(m_userSettingsPath); - URIUtils::RemoveSlashAtEnd(strAddon); - std::string strRoot = URIUtils::GetDirectory(strAddon); - URIUtils::RemoveSlashAtEnd(strRoot); - - // create the individual folders - if (!CDirectory::Exists(strRoot)) - CDirectory::Create(strRoot); - if (!CDirectory::Exists(strAddon)) - CDirectory::Create(strAddon); - - // create the XML file - CXBMCTinyXML doc; - SettingsToXML(doc); - doc.SaveFile(m_userSettingsPath); - m_userSettingsLoaded = true; - - CAddonMgr::Get().ReloadSettings(ID());//push the settings changes to the running addon instance -#ifdef HAS_PYTHON - g_pythonParser.OnSettingsChanged(ID()); -#endif -} - -std::string CAddon::GetSetting(const std::string& key) -{ - if (!LoadSettings()) - return ""; // no settings available - - map::const_iterator i = m_settings.find(key); - if (i != m_settings.end()) - return i->second; - return ""; -} - -void CAddon::UpdateSetting(const std::string& key, const std::string& value) -{ - LoadSettings(); - if (key.empty()) return; - m_settings[key] = value; -} - -bool CAddon::SettingsFromXML(const CXBMCTinyXML &doc, bool loadDefaults /*=false */) -{ - if (!doc.RootElement()) - return false; - - if (loadDefaults) - m_settings.clear(); - - const TiXmlElement* category = doc.RootElement()->FirstChildElement("category"); - if (!category) - category = doc.RootElement(); - - bool foundSetting = false; - while (category) - { - const TiXmlElement *setting = category->FirstChildElement("setting"); - while (setting) - { - const char *id = setting->Attribute("id"); - const char *value = setting->Attribute(loadDefaults ? "default" : "value"); - if (id && value) - { - m_settings[id] = value; - foundSetting = true; - } - setting = setting->NextSiblingElement("setting"); - } - category = category->NextSiblingElement("category"); - } - return foundSetting; -} - -void CAddon::SettingsToXML(CXBMCTinyXML &doc) const -{ - TiXmlElement node("settings"); - doc.InsertEndChild(node); - for (map::const_iterator i = m_settings.begin(); i != m_settings.end(); ++i) - { - TiXmlElement nodeSetting("setting"); - nodeSetting.SetAttribute("id", i->first.c_str()); - nodeSetting.SetAttribute("value", i->second.c_str()); - doc.RootElement()->InsertEndChild(nodeSetting); - } - doc.SaveFile(m_userSettingsPath); -} - -TiXmlElement* CAddon::GetSettingsXML() -{ - return m_addonXmlDoc.RootElement(); -} - -void CAddon::BuildProfilePath() -{ - m_profile = StringUtils::Format("special://profile/addon_data/%s/", ID().c_str()); -} - -const std::string CAddon::Icon() const -{ - if (CURL::IsFullPath(m_props.icon)) - return m_props.icon; - return URIUtils::AddFileToFolder(m_props.path, m_props.icon); -} - -const std::string CAddon::LibPath() const -{ - return URIUtils::AddFileToFolder(m_props.path, m_strLibName); -} - -AddonVersion CAddon::GetDependencyVersion(const std::string &dependencyID) const -{ - const ADDON::ADDONDEPS &deps = GetDeps(); - ADDONDEPS::const_iterator it = deps.find(dependencyID); - if (it != deps.end()) - return it->second.first; - return AddonVersion("0.0.0"); -} - -/** - * CAddonLibrary - * - */ - -CAddonLibrary::CAddonLibrary(const cp_extension_t *ext) - : CAddon(ext) - , m_addonType(SetAddonType()) -{ -} - -CAddonLibrary::CAddonLibrary(const AddonProps& props) - : CAddon(props) - , m_addonType(SetAddonType()) -{ -} - -AddonPtr CAddonLibrary::Clone() const -{ - return AddonPtr(new CAddonLibrary(*this)); -} - -TYPE CAddonLibrary::SetAddonType() -{ - if (Type() == ADDON_VIZ_LIBRARY) - return ADDON_VIZ; - else - return ADDON_UNKNOWN; -} - -} /* namespace ADDON */ - diff --git a/xbmc/addons/Addon.h b/xbmc/addons/Addon.h deleted file mode 100644 index 4fbf085..0000000 --- a/xbmc/addons/Addon.h +++ /dev/null @@ -1,278 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "IAddon.h" -#include "addons/AddonVersion.h" -#include "utils/XBMCTinyXML.h" -#include "guilib/LocalizeStrings.h" -#include "utils/ISerializable.h" -#include - -class TiXmlElement; -class CAddonCallbacksAddon; - -typedef struct cp_plugin_info_t cp_plugin_info_t; -typedef struct cp_extension_t cp_extension_t; - -namespace ADDON -{ - typedef std::vector VECADDONS; - typedef std::vector::iterator IVECADDONS; - -// utils -const std::string TranslateType(const TYPE &type, bool pretty=false); -const std::string GetIcon(const TYPE &type); - TYPE TranslateType(const std::string &string); - -class AddonProps : public ISerializable -{ -public: - AddonProps(const std::string &id, TYPE type, const std::string &versionstr, const std::string &minversionstr) - : id(id) - , type(type) - , version(versionstr) - , minversion(minversionstr) - , stars(0) - { - } - - virtual ~AddonProps() {} - - AddonProps(const cp_extension_t *ext); - AddonProps(const cp_plugin_info_t *plugin); - - bool operator==(const AddonProps &rhs) - { - return (*this).id == rhs.id - && (*this).type == rhs.type - && (*this).version == rhs.version; - } - - void Serialize(CVariant &variant) const; - - std::string id; - TYPE type; - AddonVersion version; - AddonVersion minversion; - std::string name; - std::string license; - std::string summary; - std::string description; - std::string path; - std::string libname; - std::string author; - std::string source; - std::string icon; - std::string disclaimer; - std::string changelog; - std::string fanart; - ADDONDEPS dependencies; - std::string broken; - InfoMap extrainfo; - int stars; -private: - void BuildDependencies(const cp_plugin_info_t *plugin); -}; - -typedef std::vector VECADDONPROPS; - -class CAddon : public IAddon -{ -public: - CAddon(const AddonProps &addonprops); - CAddon(const cp_extension_t *ext); - CAddon(const cp_plugin_info_t *plugin); - virtual ~CAddon() {} - virtual AddonPtr Clone() const; - - /*! \brief Check whether the this addon can be configured or not - \return true if the addon has settings, false otherwise - \sa LoadSettings, LoadUserSettings, SaveSettings, HasUserSettings, GetSetting, UpdateSetting - */ - bool HasSettings(); - - /*! \brief Check whether the user has configured this addon or not - \return true if previously saved settings are found, false otherwise - \sa LoadSettings, LoadUserSettings, SaveSettings, HasSettings, GetSetting, UpdateSetting - */ - bool HasUserSettings(); - - /*! \brief Save any user configured settings - \sa LoadSettings, LoadUserSettings, HasSettings, HasUserSettings, GetSetting, UpdateSetting - */ - virtual void SaveSettings(); - - /*! \brief Update a user-configured setting with a new value - \param key the id of the setting to update - \param value the value that the setting should take - \sa LoadSettings, LoadUserSettings, SaveSettings, HasSettings, HasUserSettings, GetSetting - */ - void UpdateSetting(const std::string& key, const std::string& value); - - /*! \brief Retrieve a particular settings value - If a previously configured user setting is available, we return it's value, else we return the default (if available) - \param key the id of the setting to retrieve - \return the current value of the setting, or the default if the setting has yet to be configured. - \sa LoadSettings, LoadUserSettings, SaveSettings, HasSettings, HasUserSettings, UpdateSetting - */ - virtual std::string GetSetting(const std::string& key); - - TiXmlElement* GetSettingsXML(); - virtual std::string GetString(uint32_t id); - - // properties - TYPE Type() const { return m_props.type; } - bool IsType(TYPE type) const { return type == m_props.type; } - AddonProps Props() const { return m_props; } - AddonProps& Props() { return m_props; } - const std::string ID() const { return m_props.id; } - const std::string Name() const { return m_props.name; } - bool Enabled() const { return m_enabled; } - virtual bool IsInUse() const { return false; }; - const AddonVersion Version() const { return m_props.version; } - const AddonVersion MinVersion() const { return m_props.minversion; } - const std::string Summary() const { return m_props.summary; } - const std::string Description() const { return m_props.description; } - const std::string Path() const { return m_props.path; } - const std::string Profile() const { return m_profile; } - const std::string LibPath() const; - const std::string Author() const { return m_props.author; } - const std::string ChangeLog() const { return m_props.changelog; } - const std::string FanArt() const { return m_props.fanart; } - const std::string Icon() const; - int Stars() const { return m_props.stars; } - const std::string Disclaimer() const { return m_props.disclaimer; } - const InfoMap &ExtraInfo() const { return m_props.extrainfo; } - const ADDONDEPS &GetDeps() const { return m_props.dependencies; } - - /*! \brief get the required version of a dependency. - \param dependencyID the addon ID of the dependency. - \return the version this addon requires. - */ - AddonVersion GetDependencyVersion(const std::string &dependencyID) const; - - /*! \brief return whether or not this addon satisfies the given version requirements - \param version the version to meet. - \return true if min_version <= version <= current_version, false otherwise. - */ - bool MeetsVersion(const AddonVersion &version) const; - virtual bool ReloadSettings(); - - void MarkAsDisabled() { m_enabled = false; } - - /*! \brief callback for when this add-on is disabled. - Use to perform any needed actions (e.g. stop a service) - */ - virtual void OnDisabled() {}; - - /*! \brief callback for when this add-on is enabled. - Use to perform any needed actions (e.g. start a service) - */ - virtual void OnEnabled() {}; - - /*! \brief retrieve the running instance of an add-on if it persists while running. - */ - virtual AddonPtr GetRunningInstance() const { return AddonPtr(); } - - /*! \brief callbacks for special install/uninstall behaviour */ - virtual bool OnPreInstall() { return false; }; - virtual void OnPostInstall(bool restart, bool update, bool modal) {}; - virtual void OnPreUnInstall() {}; - virtual void OnPostUnInstall() {}; - virtual bool CanInstall(const std::string& referer) { return true; } -protected: - friend class CAddonCallbacksAddon; - - CAddon(const CAddon &rhs); // protected as all copying is handled by Clone() - virtual void BuildLibName(const cp_extension_t *ext = NULL); - - /*! \brief Load the default settings and override these with any previously configured user settings - \param bForce force the load of settings even if they are already loaded (reload) - \return true if settings exist, false otherwise - \sa LoadUserSettings, SaveSettings, HasSettings, HasUserSettings, GetSetting, UpdateSetting - */ - virtual bool LoadSettings(bool bForce = false); - - /*! \brief Load the user settings - \return true if user settings exist, false otherwise - \sa LoadSettings, SaveSettings, HasSettings, HasUserSettings, GetSetting, UpdateSetting - */ - bool LoadUserSettings(); - - /*! \brief Parse settings from an XML document - \param doc XML document to parse for settings - \param loadDefaults if true, the default attribute is used and settings are reset prior to parsing, else the value attribute is used. - \return true if settings are loaded, false otherwise - \sa SettingsToXML - */ - bool SettingsFromXML(const CXBMCTinyXML &doc, bool loadDefaults = false); - - /*! \brief Parse settings into an XML document - \param doc XML document to receive the settings - \sa SettingsFromXML - */ - void SettingsToXML(CXBMCTinyXML &doc) const; - - CXBMCTinyXML m_addonXmlDoc; - std::string m_strLibName; - bool m_settingsLoaded; - bool m_userSettingsLoaded; - - virtual void ClearStrings(); -private: - friend class CAddonMgr; - AddonProps m_props; - std::string m_userSettingsPath; - void BuildProfilePath(); - - virtual bool IsAddonLibrary() { return false; } - - void Enable() { LoadStrings(); m_enabled = true; } - void Disable() { m_enabled = false; ClearStrings();} - - virtual bool LoadStrings(); - - bool m_hasStrings; - bool m_checkedStrings; - bool m_hasSettings; - - std::string m_profile; - bool m_enabled; - CLocalizeStrings m_strings; - std::map m_settings; -}; - -class CAddonLibrary : public CAddon -{ -public: - CAddonLibrary(const AddonProps &props); - CAddonLibrary(const cp_extension_t *ext); - - virtual AddonPtr Clone() const; - -private: - virtual bool IsAddonLibrary() { return true; } - TYPE SetAddonType(); - const TYPE m_addonType; // addon type this library enhances -}; - -}; /* namespace ADDON */ - diff --git a/xbmc/addons/AddonCallbacks.cpp b/xbmc/addons/AddonCallbacks.cpp deleted file mode 100644 index 8634373..0000000 --- a/xbmc/addons/AddonCallbacks.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "Addon.h" -#include "AddonCallbacks.h" -#include "AddonCallbacksAddon.h" -#include "AddonCallbacksCodec.h" -#include "AddonCallbacksGUI.h" -#include "AddonCallbacksPVR.h" -#include "filesystem/SpecialProtocol.h" -#include "utils/log.h" - -namespace ADDON -{ - -CAddonCallbacks::CAddonCallbacks(CAddon* addon) -{ - m_addon = addon; - m_callbacks = new AddonCB; - m_helperAddon = NULL; - m_helperGUI = NULL; - m_helperPVR = NULL; - m_helperCODEC = NULL; - - m_callbacks->libBasePath = strdup(CSpecialProtocol::TranslatePath("special://xbmcbin/addons").c_str()); - m_callbacks->addonData = this; - m_callbacks->AddOnLib_RegisterMe = CAddonCallbacks::AddOnLib_RegisterMe; - m_callbacks->AddOnLib_UnRegisterMe = CAddonCallbacks::AddOnLib_UnRegisterMe; - m_callbacks->CODECLib_RegisterMe = CAddonCallbacks::CODECLib_RegisterMe; - m_callbacks->CODECLib_UnRegisterMe = CAddonCallbacks::CODECLib_UnRegisterMe; - m_callbacks->GUILib_RegisterMe = CAddonCallbacks::GUILib_RegisterMe; - m_callbacks->GUILib_UnRegisterMe = CAddonCallbacks::GUILib_UnRegisterMe; - m_callbacks->PVRLib_RegisterMe = CAddonCallbacks::PVRLib_RegisterMe; - m_callbacks->PVRLib_UnRegisterMe = CAddonCallbacks::PVRLib_UnRegisterMe; -} - -CAddonCallbacks::~CAddonCallbacks() -{ - delete m_helperAddon; - m_helperAddon = NULL; - delete m_helperCODEC; - m_helperCODEC = NULL; - delete m_helperGUI; - m_helperGUI = NULL; - delete m_helperPVR; - m_helperPVR = NULL; - free((char*)m_callbacks->libBasePath); - delete m_callbacks; - m_callbacks = NULL; -} - -CB_AddOnLib* CAddonCallbacks::AddOnLib_RegisterMe(void *addonData) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return NULL; - } - - addon->m_helperAddon = new CAddonCallbacksAddon(addon->m_addon); - return addon->m_helperAddon->GetCallbacks(); -} - -void CAddonCallbacks::AddOnLib_UnRegisterMe(void *addonData, CB_AddOnLib *cbTable) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return; - } - - delete addon->m_helperAddon; - addon->m_helperAddon = NULL; -} - -CB_CODECLib* CAddonCallbacks::CODECLib_RegisterMe(void *addonData) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return NULL; - } - - addon->m_helperCODEC = new CAddonCallbacksCodec(addon->m_addon); - return addon->m_helperCODEC->GetCallbacks(); -} - -void CAddonCallbacks::CODECLib_UnRegisterMe(void *addonData, CB_CODECLib *cbTable) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return; - } - - delete addon->m_helperCODEC; - addon->m_helperCODEC = NULL; -} - -CB_GUILib* CAddonCallbacks::GUILib_RegisterMe(void *addonData) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return NULL; - } - - addon->m_helperGUI = new CAddonCallbacksGUI(addon->m_addon); - return addon->m_helperGUI->GetCallbacks(); -} - -void CAddonCallbacks::GUILib_UnRegisterMe(void *addonData, CB_GUILib *cbTable) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return; - } - - delete addon->m_helperGUI; - addon->m_helperGUI = NULL; -} - -CB_PVRLib* CAddonCallbacks::PVRLib_RegisterMe(void *addonData) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return NULL; - } - - addon->m_helperPVR = new CAddonCallbacksPVR(addon->m_addon); - return addon->m_helperPVR->GetCallbacks(); -} - -void CAddonCallbacks::PVRLib_UnRegisterMe(void *addonData, CB_PVRLib *cbTable) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); - return; - } - - delete addon->m_helperPVR; - addon->m_helperPVR = NULL; -} - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacks.h b/xbmc/addons/AddonCallbacks.h deleted file mode 100644 index f0902e4..0000000 --- a/xbmc/addons/AddonCallbacks.h +++ /dev/null @@ -1,466 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include -#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); -typedef bool (*AddOnGetSetting)(void *addonData, const char *settingName, void *settingValue); -typedef char* (*AddOnUnknownToUTF8)(const char *sourceDest); -typedef char* (*AddOnGetLocalizedString)(const void* addonData, long dwCode); -typedef char* (*AddOnGetDVDMenuLanguage)(const void* addonData); -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 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 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); -typedef int64_t (*AddOnGetFilePosition)(const void* addonData, void* file); -typedef int64_t (*AddOnGetFileLength)(const void* addonData, void* file); -typedef void (*AddOnCloseFile)(const void* addonData, void* file); -typedef int (*AddOnGetFileChunkSize)(const void* addonData, void* file); -typedef bool (*AddOnFileExists)(const void* addonData, const char *strFileName, bool bUseCache); -typedef int (*AddOnStatFile)(const void* addonData, const char *strFileName, struct __stat64* buffer); -typedef bool (*AddOnDeleteFile)(const void* addonData, const char *strFileName); -typedef bool (*AddOnCanOpenDirectory)(const void* addonData, const char* strURL); -typedef bool (*AddOnCreateDirectory)(const void* addonData, const char *strPath); -typedef bool (*AddOnDirectoryExists)(const void* addonData, const char *strPath); -typedef bool (*AddOnRemoveDirectory)(const void* addonData, const char *strPath); - -typedef struct CB_AddOn -{ - AddOnLogCallback Log; - AddOnQueueNotification QueueNotification; - AddOnWakeOnLan WakeOnLan; - AddOnGetSetting GetSetting; - AddOnUnknownToUTF8 UnknownToUTF8; - AddOnGetLocalizedString GetLocalizedString; - AddOnGetDVDMenuLanguage GetDVDMenuLanguage; - AddOnFreeString FreeString; - - AddOnOpenFile OpenFile; - AddOnOpenFileForWrite OpenFileForWrite; - AddOnReadFile ReadFile; - AddOnReadFileString ReadFileString; - AddOnWriteFile WriteFile; - AddOnFlushFile FlushFile; - AddOnSeekFile SeekFile; - AddOnTruncateFile TruncateFile; - AddOnGetFilePosition GetFilePosition; - AddOnGetFileLength GetFileLength; - AddOnCloseFile CloseFile; - AddOnGetFileChunkSize GetFileChunkSize; - AddOnFileExists FileExists; - AddOnStatFile StatFile; - AddOnDeleteFile DeleteFile; - AddOnCanOpenDirectory CanOpenDirectory; - AddOnCreateDirectory CreateDirectory; - AddOnDirectoryExists DirectoryExists; - AddOnRemoveDirectory RemoveDirectory; -} CB_AddOnLib; - -typedef xbmc_codec_t (*CODECGetCodecByName)(const void* addonData, const char* strCodecName); - -typedef struct CB_CODEC -{ - CODECGetCodecByName GetCodecByName; -} CB_CODECLib; - -typedef void (*GUILock)(); -typedef void (*GUIUnlock)(); -typedef int (*GUIGetScreenHeight)(); -typedef int (*GUIGetScreenWidth)(); -typedef int (*GUIGetVideoResolution)(); -typedef GUIHANDLE (*GUIWindow_New)(void *addonData, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog); -typedef void (*GUIWindow_Delete)(void *addonData, GUIHANDLE handle); -typedef void (*GUIWindow_SetCallbacks)(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*)(GUIHANDLE handle), bool (*)(GUIHANDLE handle, int), bool (*)(GUIHANDLE handle, int), bool (*)(GUIHANDLE handle, int)); -typedef bool (*GUIWindow_Show)(void *addonData, GUIHANDLE handle); -typedef bool (*GUIWindow_Close)(void *addonData, GUIHANDLE handle); -typedef bool (*GUIWindow_DoModal)(void *addonData, GUIHANDLE handle); -typedef bool (*GUIWindow_SetFocusId)(void *addonData, GUIHANDLE handle, int iControlId); -typedef int (*GUIWindow_GetFocusId)(void *addonData, GUIHANDLE handle); -typedef bool (*GUIWindow_SetCoordinateResolution)(void *addonData, GUIHANDLE handle, int res); -typedef void (*GUIWindow_SetProperty)(void *addonData, GUIHANDLE handle, const char *key, const char *value); -typedef void (*GUIWindow_SetPropertyInt)(void *addonData, GUIHANDLE handle, const char *key, int value); -typedef void (*GUIWindow_SetPropertyBool)(void *addonData, GUIHANDLE handle, const char *key, bool value); -typedef void (*GUIWindow_SetPropertyDouble)(void *addonData, GUIHANDLE handle, const char *key, double value); -typedef const char* (*GUIWindow_GetProperty)(void *addonData, GUIHANDLE handle, const char *key); -typedef int (*GUIWindow_GetPropertyInt)(void *addonData, GUIHANDLE handle, const char *key); -typedef bool (*GUIWindow_GetPropertyBool)(void *addonData, GUIHANDLE handle, const char *key); -typedef double (*GUIWindow_GetPropertyDouble)(void *addonData, GUIHANDLE handle, const char *key); -typedef void (*GUIWindow_ClearProperties)(void *addonData, GUIHANDLE handle); -typedef int (*GUIWindow_GetListSize)(void *addonData, GUIHANDLE handle); -typedef void (*GUIWindow_ClearList)(void *addonData, GUIHANDLE handle); -typedef GUIHANDLE (*GUIWindow_AddItem)(void *addonData, GUIHANDLE handle, GUIHANDLE item, int itemPosition); -typedef GUIHANDLE (*GUIWindow_AddStringItem)(void *addonData, GUIHANDLE handle, const char *itemName, int itemPosition); -typedef void (*GUIWindow_RemoveItem)(void *addonData, GUIHANDLE handle, int itemPosition); -typedef GUIHANDLE (*GUIWindow_GetListItem)(void *addonData, GUIHANDLE handle, int listPos); -typedef void (*GUIWindow_SetCurrentListPosition)(void *addonData, GUIHANDLE handle, int listPos); -typedef int (*GUIWindow_GetCurrentListPosition)(void *addonData, GUIHANDLE handle); -typedef GUIHANDLE (*GUIWindow_GetControl_Spin)(void *addonData, GUIHANDLE handle, int controlId); -typedef GUIHANDLE (*GUIWindow_GetControl_Button)(void *addonData, GUIHANDLE handle, int controlId); -typedef GUIHANDLE (*GUIWindow_GetControl_RadioButton)(void *addonData, GUIHANDLE handle, int controlId); -typedef GUIHANDLE (*GUIWindow_GetControl_Edit)(void *addonData, GUIHANDLE handle, int controlId); -typedef GUIHANDLE (*GUIWindow_GetControl_Progress)(void *addonData, GUIHANDLE handle, int controlId); -typedef GUIHANDLE (*GUIWindow_GetControl_RenderAddon)(void *addonData, GUIHANDLE handle, int controlId); -typedef void (*GUIWindow_SetControlLabel)(void *addonData, GUIHANDLE handle, int controlId, const char *label); -typedef void (*GUIWindow_MarkDirtyRegion)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_Spin_SetVisible)(void *addonData, GUIHANDLE spinhandle, bool yesNo); -typedef void (*GUIControl_Spin_SetText)(void *addonData, GUIHANDLE spinhandle, const char *label); -typedef void (*GUIControl_Spin_Clear)(void *addonData, GUIHANDLE spinhandle); -typedef void (*GUIControl_Spin_AddLabel)(void *addonData, GUIHANDLE spinhandle, const char *label, int iValue); -typedef int (*GUIControl_Spin_GetValue)(void *addonData, GUIHANDLE spinhandle); -typedef void (*GUIControl_Spin_SetValue)(void *addonData, GUIHANDLE spinhandle, int iValue); -typedef void (*GUIControl_RadioButton_SetVisible)(void *addonData, GUIHANDLE handle, bool yesNo); -typedef void (*GUIControl_RadioButton_SetText)(void *addonData, GUIHANDLE handle, const char *label); -typedef void (*GUIControl_RadioButton_SetSelected)(void *addonData, GUIHANDLE handle, bool yesNo); -typedef bool (*GUIControl_RadioButton_IsSelected)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_Progress_SetPercentage)(void *addonData, GUIHANDLE handle, float fPercent); -typedef float (*GUIControl_Progress_GetPercentage)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_Progress_SetInfo)(void *addonData, GUIHANDLE handle, int iInfo); -typedef int (*GUIControl_Progress_GetInfo)(void *addonData, GUIHANDLE handle); -typedef const char* (*GUIControl_Progress_GetDescription)(void *addonData, GUIHANDLE handle); -typedef GUIHANDLE (*GUIWindow_GetControl_Slider)(void *addonData, GUIHANDLE handle, int controlId); -typedef void (*GUIControl_Slider_SetVisible)(void *addonData, GUIHANDLE handle, bool yesNo); -typedef const char *(*GUIControl_Slider_GetDescription)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_Slider_SetIntRange)(void *addonData, GUIHANDLE handle, int iStart, int iEnd); -typedef void (*GUIControl_Slider_SetIntValue)(void *addonData, GUIHANDLE handle, int iValue); -typedef int (*GUIControl_Slider_GetIntValue)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_Slider_SetIntInterval)(void *addonData, GUIHANDLE handle, int iInterval); -typedef void (*GUIControl_Slider_SetPercentage)(void *addonData, GUIHANDLE handle, float fPercent); -typedef float (*GUIControl_Slider_GetPercentage)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_Slider_SetFloatRange)(void *addonData, GUIHANDLE handle, float fStart, float fEnd); -typedef void (*GUIControl_Slider_SetFloatValue)(void *addonData, GUIHANDLE handle, float fValue); -typedef float (*GUIControl_Slider_GetFloatValue)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_Slider_SetFloatInterval)(void *addonData, GUIHANDLE handle, float fInterval); -typedef GUIHANDLE (*GUIWindow_GetControl_SettingsSlider)(void *addonData, GUIHANDLE handle, int controlId); -typedef void (*GUIControl_SettingsSlider_SetVisible)(void *addonData, GUIHANDLE handle, bool yesNo); -typedef void (*GUIControl_SettingsSlider_SetText)(void *addonData, GUIHANDLE handle, const char *label); -typedef const char *(*GUIControl_SettingsSlider_GetDescription)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_SettingsSlider_SetIntRange)(void *addonData, GUIHANDLE handle, int iStart, int iEnd); -typedef void (*GUIControl_SettingsSlider_SetIntValue)(void *addonData, GUIHANDLE handle, int iValue); -typedef int (*GUIControl_SettingsSlider_GetIntValue)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_SettingsSlider_SetIntInterval)(void *addonData, GUIHANDLE handle, int iInterval); -typedef void (*GUIControl_SettingsSlider_SetPercentage)(void *addonData, GUIHANDLE handle, float fPercent); -typedef float (*GUIControl_SettingsSlider_GetPercentage)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_SettingsSlider_SetFloatRange)(void *addonData, GUIHANDLE handle, float fStart, float fEnd); -typedef void (*GUIControl_SettingsSlider_SetFloatValue)(void *addonData, GUIHANDLE handle, float fValue); -typedef float (*GUIControl_SettingsSlider_GetFloatValue)(void *addonData, GUIHANDLE handle); -typedef void (*GUIControl_SettingsSlider_SetFloatInterval)(void *addonData, GUIHANDLE handle, float fInterval); -typedef GUIHANDLE (*GUIListItem_Create)(void *addonData, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path); -typedef const char* (*GUIListItem_GetLabel)(void *addonData, GUIHANDLE handle); -typedef void (*GUIListItem_SetLabel)(void *addonData, GUIHANDLE handle, const char *label); -typedef const char* (*GUIListItem_GetLabel2)(void *addonData, GUIHANDLE handle); -typedef void (*GUIListItem_SetLabel2)(void *addonData, GUIHANDLE handle, const char *label); -typedef void (*GUIListItem_SetIconImage)(void *addonData, GUIHANDLE handle, const char *image); -typedef void (*GUIListItem_SetThumbnailImage)(void *addonData, GUIHANDLE handle, const char *image); -typedef void (*GUIListItem_SetInfo)(void *addonData, GUIHANDLE handle, const char *info); -typedef void (*GUIListItem_SetProperty)(void *addonData, GUIHANDLE handle, const char *key, const char *value); -typedef const char* (*GUIListItem_GetProperty)(void *addonData, GUIHANDLE handle, const char *key); -typedef void (*GUIListItem_SetPath)(void *addonData, GUIHANDLE handle, const char *path); -typedef void (*GUIRenderAddon_SetCallbacks)(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*createCB)(GUIHANDLE,int,int,int,int,void*), void (*renderCB)(GUIHANDLE), void (*stopCB)(GUIHANDLE), bool (*dirtyCB)(GUIHANDLE)); -typedef void (*GUIRenderAddon_Delete)(void *addonData, GUIHANDLE handle); -typedef void (*GUIRenderAddon_MarkDirty)(void *addonData, GUIHANDLE handle); - -typedef bool (*GUIDialog_Keyboard_ShowAndGetInputWithHead)(char &strTextString, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs); -typedef bool (*GUIDialog_Keyboard_ShowAndGetInput)(char &strTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs); -typedef bool (*GUIDialog_Keyboard_ShowAndGetNewPasswordWithHead)(char &newPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs); -typedef bool (*GUIDialog_Keyboard_ShowAndGetNewPassword)(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); -typedef bool (*GUIDialog_Keyboard_ShowAndVerifyNewPasswordWithHead)(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmpty, unsigned int autoCloseMs); -typedef bool (*GUIDialog_Keyboard_ShowAndVerifyNewPassword)(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); -typedef int (*GUIDialog_Keyboard_ShowAndVerifyPassword)(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs); -typedef bool (*GUIDialog_Keyboard_ShowAndGetFilter)(char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs); -typedef bool (*GUIDialog_Keyboard_SendTextToActiveKeyboard)(const char *aTextString, bool closeKeyboard); -typedef bool (*GUIDialog_Keyboard_isKeyboardActivated)(); - -typedef bool (*GUIDialog_Numeric_ShowAndVerifyNewPassword)(char &strNewPassword, unsigned int iMaxStringSize); -typedef int (*GUIDialog_Numeric_ShowAndVerifyPassword)(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries); -typedef bool (*GUIDialog_Numeric_ShowAndVerifyInput)(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput); -typedef bool (*GUIDialog_Numeric_ShowAndGetTime)(tm &time, const char *strHeading); -typedef bool (*GUIDialog_Numeric_ShowAndGetDate)(tm &date, const char *strHeading); -typedef bool (*GUIDialog_Numeric_ShowAndGetIPAddress)(char &strIPAddress, unsigned int iMaxStringSize, const char *strHeading); -typedef bool (*GUIDialog_Numeric_ShowAndGetNumber)(char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs); -typedef bool (*GUIDialog_Numeric_ShowAndGetSeconds)(char &timeString, unsigned int iMaxStringSize, const char *strHeading); - -typedef bool (*GUIDialog_FileBrowser_ShowAndGetFile)(const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList); - -typedef void (*GUIDialog_OK_ShowAndGetInputSingleText)(const char *heading, const char *text); -typedef void (*GUIDialog_OK_ShowAndGetInputLineText)(const char *heading, const char *line0, const char *line1, const char *line2); - -typedef bool (*GUIDialog_YesNo_ShowAndGetInputSingleText)(const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel); -typedef bool (*GUIDialog_YesNo_ShowAndGetInputLineText)(const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel); -typedef bool (*GUIDialog_YesNo_ShowAndGetInputLineButtonText)(const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel); - -typedef void (*GUIDialog_TextViewer)(const char *heading, const char *text); - -typedef int (*GUIDialog_Select)(const char *heading, const char *entries[], unsigned int size, int selected); - -typedef struct CB_GUILib -{ - GUILock Lock; - GUIUnlock Unlock; - GUIGetScreenHeight GetScreenHeight; - GUIGetScreenWidth GetScreenWidth; - GUIGetVideoResolution GetVideoResolution; - GUIWindow_New Window_New; - GUIWindow_Delete Window_Delete; - GUIWindow_SetCallbacks Window_SetCallbacks; - GUIWindow_Show Window_Show; - GUIWindow_Close Window_Close; - GUIWindow_DoModal Window_DoModal; - GUIWindow_SetFocusId Window_SetFocusId; - GUIWindow_GetFocusId Window_GetFocusId; - GUIWindow_SetCoordinateResolution Window_SetCoordinateResolution; - GUIWindow_SetProperty Window_SetProperty; - GUIWindow_SetPropertyInt Window_SetPropertyInt; - GUIWindow_SetPropertyBool Window_SetPropertyBool; - GUIWindow_SetPropertyDouble Window_SetPropertyDouble; - GUIWindow_GetProperty Window_GetProperty; - GUIWindow_GetPropertyInt Window_GetPropertyInt; - GUIWindow_GetPropertyBool Window_GetPropertyBool; - GUIWindow_GetPropertyDouble Window_GetPropertyDouble; - GUIWindow_ClearProperties Window_ClearProperties; - GUIWindow_GetListSize Window_GetListSize; - GUIWindow_ClearList Window_ClearList; - GUIWindow_AddItem Window_AddItem; - GUIWindow_AddStringItem Window_AddStringItem; - GUIWindow_RemoveItem Window_RemoveItem; - GUIWindow_GetListItem Window_GetListItem; - GUIWindow_SetCurrentListPosition Window_SetCurrentListPosition; - GUIWindow_GetCurrentListPosition Window_GetCurrentListPosition; - GUIWindow_GetControl_Spin Window_GetControl_Spin; - GUIWindow_GetControl_Button Window_GetControl_Button; - GUIWindow_GetControl_RadioButton Window_GetControl_RadioButton; - GUIWindow_GetControl_Edit Window_GetControl_Edit; - GUIWindow_GetControl_Progress Window_GetControl_Progress; - GUIWindow_GetControl_RenderAddon Window_GetControl_RenderAddon; - GUIWindow_SetControlLabel Window_SetControlLabel; - GUIWindow_MarkDirtyRegion Window_MarkDirtyRegion; - GUIControl_Spin_SetVisible Control_Spin_SetVisible; - GUIControl_Spin_SetText Control_Spin_SetText; - GUIControl_Spin_Clear Control_Spin_Clear; - GUIControl_Spin_AddLabel Control_Spin_AddLabel; - GUIControl_Spin_GetValue Control_Spin_GetValue; - GUIControl_Spin_SetValue Control_Spin_SetValue; - GUIControl_RadioButton_SetVisible Control_RadioButton_SetVisible; - GUIControl_RadioButton_SetText Control_RadioButton_SetText; - GUIControl_RadioButton_SetSelected Control_RadioButton_SetSelected; - GUIControl_RadioButton_IsSelected Control_RadioButton_IsSelected; - GUIControl_Progress_SetPercentage Control_Progress_SetPercentage; - GUIControl_Progress_GetPercentage Control_Progress_GetPercentage; - GUIControl_Progress_SetInfo Control_Progress_SetInfo; - GUIControl_Progress_GetInfo Control_Progress_GetInfo; - GUIControl_Progress_GetDescription Control_Progress_GetDescription; - GUIListItem_Create ListItem_Create; - GUIListItem_GetLabel ListItem_GetLabel; - GUIListItem_SetLabel ListItem_SetLabel; - GUIListItem_GetLabel2 ListItem_GetLabel2; - GUIListItem_SetLabel2 ListItem_SetLabel2; - GUIListItem_SetIconImage ListItem_SetIconImage; - GUIListItem_SetThumbnailImage ListItem_SetThumbnailImage; - GUIListItem_SetInfo ListItem_SetInfo; - GUIListItem_SetProperty ListItem_SetProperty; - GUIListItem_GetProperty ListItem_GetProperty; - GUIListItem_SetPath ListItem_SetPath; - GUIRenderAddon_SetCallbacks RenderAddon_SetCallbacks; - GUIRenderAddon_Delete RenderAddon_Delete; - - GUIWindow_GetControl_Slider Window_GetControl_Slider; - GUIControl_Slider_SetVisible Control_Slider_SetVisible; - GUIControl_Slider_GetDescription Control_Slider_GetDescription; - GUIControl_Slider_SetIntRange Control_Slider_SetIntRange; - GUIControl_Slider_SetIntValue Control_Slider_SetIntValue; - GUIControl_Slider_GetIntValue Control_Slider_GetIntValue; - GUIControl_Slider_SetIntInterval Control_Slider_SetIntInterval; - GUIControl_Slider_SetPercentage Control_Slider_SetPercentage; - GUIControl_Slider_GetPercentage Control_Slider_GetPercentage; - GUIControl_Slider_SetFloatRange Control_Slider_SetFloatRange; - GUIControl_Slider_SetFloatValue Control_Slider_SetFloatValue; - GUIControl_Slider_GetFloatValue Control_Slider_GetFloatValue; - GUIControl_Slider_SetFloatInterval Control_Slider_SetFloatInterval; - - GUIWindow_GetControl_SettingsSlider Window_GetControl_SettingsSlider; - GUIControl_SettingsSlider_SetVisible Control_SettingsSlider_SetVisible; - GUIControl_SettingsSlider_SetText Control_SettingsSlider_SetText; - GUIControl_SettingsSlider_GetDescription Control_SettingsSlider_GetDescription; - GUIControl_SettingsSlider_SetIntRange Control_SettingsSlider_SetIntRange; - GUIControl_SettingsSlider_SetIntValue Control_SettingsSlider_SetIntValue; - GUIControl_SettingsSlider_GetIntValue Control_SettingsSlider_GetIntValue; - GUIControl_SettingsSlider_SetIntInterval Control_SettingsSlider_SetIntInterval; - GUIControl_SettingsSlider_SetPercentage Control_SettingsSlider_SetPercentage; - GUIControl_SettingsSlider_GetPercentage Control_SettingsSlider_GetPercentage; - GUIControl_SettingsSlider_SetFloatRange Control_SettingsSlider_SetFloatRange; - GUIControl_SettingsSlider_SetFloatValue Control_SettingsSlider_SetFloatValue; - GUIControl_SettingsSlider_GetFloatValue Control_SettingsSlider_GetFloatValue; - GUIControl_SettingsSlider_SetFloatInterval Control_SettingsSlider_SetFloatInterval; - - GUIDialog_Keyboard_ShowAndGetInputWithHead Dialog_Keyboard_ShowAndGetInputWithHead; - GUIDialog_Keyboard_ShowAndGetInput Dialog_Keyboard_ShowAndGetInput; - GUIDialog_Keyboard_ShowAndGetNewPasswordWithHead Dialog_Keyboard_ShowAndGetNewPasswordWithHead; - GUIDialog_Keyboard_ShowAndGetNewPassword Dialog_Keyboard_ShowAndGetNewPassword; - GUIDialog_Keyboard_ShowAndVerifyNewPasswordWithHead Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead; - GUIDialog_Keyboard_ShowAndVerifyNewPassword Dialog_Keyboard_ShowAndVerifyNewPassword; - GUIDialog_Keyboard_ShowAndVerifyPassword Dialog_Keyboard_ShowAndVerifyPassword; - GUIDialog_Keyboard_ShowAndGetFilter Dialog_Keyboard_ShowAndGetFilter; - GUIDialog_Keyboard_SendTextToActiveKeyboard Dialog_Keyboard_SendTextToActiveKeyboard; - GUIDialog_Keyboard_isKeyboardActivated Dialog_Keyboard_isKeyboardActivated; - - GUIDialog_Numeric_ShowAndVerifyNewPassword Dialog_Numeric_ShowAndVerifyNewPassword; - GUIDialog_Numeric_ShowAndVerifyPassword Dialog_Numeric_ShowAndVerifyPassword; - GUIDialog_Numeric_ShowAndVerifyInput Dialog_Numeric_ShowAndVerifyInput; - GUIDialog_Numeric_ShowAndGetTime Dialog_Numeric_ShowAndGetTime; - GUIDialog_Numeric_ShowAndGetDate Dialog_Numeric_ShowAndGetDate; - GUIDialog_Numeric_ShowAndGetIPAddress Dialog_Numeric_ShowAndGetIPAddress; - GUIDialog_Numeric_ShowAndGetNumber Dialog_Numeric_ShowAndGetNumber; - GUIDialog_Numeric_ShowAndGetSeconds Dialog_Numeric_ShowAndGetSeconds; - - GUIDialog_FileBrowser_ShowAndGetFile Dialog_FileBrowser_ShowAndGetFile; - - GUIDialog_OK_ShowAndGetInputSingleText Dialog_OK_ShowAndGetInputSingleText; - GUIDialog_OK_ShowAndGetInputLineText Dialog_OK_ShowAndGetInputLineText; - - GUIDialog_YesNo_ShowAndGetInputSingleText Dialog_YesNo_ShowAndGetInputSingleText; - GUIDialog_YesNo_ShowAndGetInputLineText Dialog_YesNo_ShowAndGetInputLineText; - GUIDialog_YesNo_ShowAndGetInputLineButtonText Dialog_YesNo_ShowAndGetInputLineButtonText; - - GUIDialog_TextViewer Dialog_TextViewer; - GUIDialog_Select Dialog_Select; -} CB_GUILib; - -typedef void (*PVRTransferEpgEntry)(void *userData, const ADDON_HANDLE handle, const EPG_TAG *epgentry); -typedef void (*PVRTransferChannelEntry)(void *userData, const ADDON_HANDLE handle, const PVR_CHANNEL *chan); -typedef void (*PVRTransferTimerEntry)(void *userData, const ADDON_HANDLE handle, const PVR_TIMER *timer); -typedef void (*PVRTransferRecordingEntry)(void *userData, const ADDON_HANDLE handle, const PVR_RECORDING *recording); -typedef void (*PVRAddMenuHook)(void *addonData, PVR_MENUHOOK *hook); -typedef void (*PVRRecording)(void *addonData, const char *Name, const char *FileName, bool On); -typedef void (*PVRTriggerChannelUpdate)(void *addonData); -typedef void (*PVRTriggerTimerUpdate)(void *addonData); -typedef void (*PVRTriggerRecordingUpdate)(void *addonData); -typedef void (*PVRTriggerChannelGroupsUpdate)(void *addonData); -typedef void (*PVRTriggerEpgUpdate)(void *addonData, unsigned int iChannelUid); - -typedef void (*PVRTransferChannelGroup)(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP *group); -typedef void (*PVRTransferChannelGroupMember)(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP_MEMBER *member); - -typedef void (*PVRFreeDemuxPacket)(void *addonData, DemuxPacket* pPacket); -typedef DemuxPacket* (*PVRAllocateDemuxPacket)(void *addonData, int iDataSize); - -typedef struct CB_PVRLib -{ - PVRTransferEpgEntry TransferEpgEntry; - PVRTransferChannelEntry TransferChannelEntry; - PVRTransferTimerEntry TransferTimerEntry; - PVRTransferRecordingEntry TransferRecordingEntry; - PVRAddMenuHook AddMenuHook; - PVRRecording Recording; - PVRTriggerChannelUpdate TriggerChannelUpdate; - PVRTriggerTimerUpdate TriggerTimerUpdate; - PVRTriggerRecordingUpdate TriggerRecordingUpdate; - PVRTriggerChannelGroupsUpdate TriggerChannelGroupsUpdate; - PVRTriggerEpgUpdate TriggerEpgUpdate; - PVRFreeDemuxPacket FreeDemuxPacket; - PVRAllocateDemuxPacket AllocateDemuxPacket; - PVRTransferChannelGroup TransferChannelGroup; - PVRTransferChannelGroupMember TransferChannelGroupMember; - -} CB_PVRLib; - - -typedef CB_AddOnLib* (*XBMCAddOnLib_RegisterMe)(void *addonData); -typedef void (*XBMCAddOnLib_UnRegisterMe)(void *addonData, CB_AddOnLib *cbTable); -typedef CB_CODECLib* (*XBMCCODECLib_RegisterMe)(void *addonData); -typedef void (*XBMCCODECLib_UnRegisterMe)(void *addonData, CB_CODECLib *cbTable); -typedef CB_GUILib* (*XBMCGUILib_RegisterMe)(void *addonData); -typedef void (*XBMCGUILib_UnRegisterMe)(void *addonData, CB_GUILib *cbTable); -typedef CB_PVRLib* (*XBMCPVRLib_RegisterMe)(void *addonData); -typedef void (*XBMCPVRLib_UnRegisterMe)(void *addonData, CB_PVRLib *cbTable); - -typedef struct AddonCB -{ - const char *libBasePath; ///> Never, never change this!!! - void *addonData; - XBMCAddOnLib_RegisterMe AddOnLib_RegisterMe; - XBMCAddOnLib_UnRegisterMe AddOnLib_UnRegisterMe; - XBMCCODECLib_RegisterMe CODECLib_RegisterMe; - XBMCCODECLib_UnRegisterMe CODECLib_UnRegisterMe; - XBMCGUILib_RegisterMe GUILib_RegisterMe; - XBMCGUILib_UnRegisterMe GUILib_UnRegisterMe; - XBMCPVRLib_RegisterMe PVRLib_RegisterMe; - XBMCPVRLib_UnRegisterMe PVRLib_UnRegisterMe; -} AddonCB; - - -namespace ADDON -{ - -class CAddon; -class CAddonCallbacksAddon; -class CAddonCallbacksCodec; -class CAddonCallbacksGUI; -class CAddonCallbacksPVR; - -class CAddonCallbacks -{ -public: - CAddonCallbacks(CAddon* addon); - ~CAddonCallbacks(); - AddonCB *GetCallbacks() { return m_callbacks; } - - static CB_AddOnLib* AddOnLib_RegisterMe(void *addonData); - static void AddOnLib_UnRegisterMe(void *addonData, CB_AddOnLib *cbTable); - static CB_CODECLib* CODECLib_RegisterMe(void *addonData); - static void CODECLib_UnRegisterMe(void *addonData, CB_CODECLib *cbTable); - static CB_GUILib* GUILib_RegisterMe(void *addonData); - static void GUILib_UnRegisterMe(void *addonData, CB_GUILib *cbTable); - static CB_PVRLib* PVRLib_RegisterMe(void *addonData); - static void PVRLib_UnRegisterMe(void *addonData, CB_PVRLib *cbTable); - - CAddonCallbacksAddon *GetHelperAddon() { return m_helperAddon; } - CAddonCallbacksCodec *GetHelperCodec() { return m_helperCODEC; } - CAddonCallbacksGUI *GetHelperGUI() { return m_helperGUI; } - CAddonCallbacksPVR *GetHelperPVR() { return m_helperPVR; } - -private: - AddonCB *m_callbacks; - CAddon *m_addon; - CAddonCallbacksAddon *m_helperAddon; - CAddonCallbacksCodec *m_helperCODEC; - CAddonCallbacksGUI *m_helperGUI; - CAddonCallbacksPVR *m_helperPVR; -}; - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksAddon.cpp b/xbmc/addons/AddonCallbacksAddon.cpp deleted file mode 100644 index e54aebe..0000000 --- a/xbmc/addons/AddonCallbacksAddon.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "Application.h" -#include "Addon.h" -#include "AddonCallbacksAddon.h" -#include "utils/log.h" -#include "LangInfo.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "filesystem/File.h" -#include "filesystem/Directory.h" -#include "utils/URIUtils.h" -#include "FileItem.h" -#include "network/Network.h" -#include "utils/CharsetConverter.h" -#include "utils/StringUtils.h" -#include "utils/XMLUtils.h" -#include "cores/dvdplayer/DVDCodecs/DVDCodecs.h" - -using namespace XFILE; - -namespace ADDON -{ - -CAddonCallbacksAddon::CAddonCallbacksAddon(CAddon* addon) -{ - m_addon = addon; - m_callbacks = new CB_AddOnLib; - - /* write XBMC addon-on specific add-on function addresses to the callback table */ - m_callbacks->Log = AddOnLog; - m_callbacks->QueueNotification = QueueNotification; - m_callbacks->WakeOnLan = WakeOnLan; - m_callbacks->GetSetting = GetAddonSetting; - m_callbacks->UnknownToUTF8 = UnknownToUTF8; - m_callbacks->GetLocalizedString = GetLocalizedString; - m_callbacks->GetDVDMenuLanguage = GetDVDMenuLanguage; - m_callbacks->FreeString = FreeString; - - m_callbacks->OpenFile = OpenFile; - m_callbacks->OpenFileForWrite = OpenFileForWrite; - m_callbacks->ReadFile = ReadFile; - m_callbacks->ReadFileString = ReadFileString; - m_callbacks->WriteFile = WriteFile; - m_callbacks->FlushFile = FlushFile; - m_callbacks->SeekFile = SeekFile; - m_callbacks->TruncateFile = TruncateFile; - m_callbacks->GetFilePosition = GetFilePosition; - m_callbacks->GetFileLength = GetFileLength; - m_callbacks->CloseFile = CloseFile; - m_callbacks->GetFileChunkSize = GetFileChunkSize; - m_callbacks->FileExists = FileExists; - m_callbacks->StatFile = StatFile; - m_callbacks->DeleteFile = DeleteFile; - - m_callbacks->CanOpenDirectory = CanOpenDirectory; - m_callbacks->CreateDirectory = CreateDirectory; - m_callbacks->DirectoryExists = DirectoryExists; - m_callbacks->RemoveDirectory = RemoveDirectory; -} - -CAddonCallbacksAddon::~CAddonCallbacksAddon() -{ - /* delete the callback table */ - delete m_callbacks; -} - -void CAddonCallbacksAddon::AddOnLog(void *addonData, const addon_log_t addonLogLevel, const char *strMessage) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL || strMessage == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - called with a null pointer", __FUNCTION__); - return; - } - - CAddonCallbacksAddon* addonHelper = addon->GetHelperAddon(); - - try - { - int xbmcLogLevel = LOGNONE; - switch (addonLogLevel) - { - case LOG_ERROR: - xbmcLogLevel = LOGERROR; - break; - case LOG_INFO: - xbmcLogLevel = LOGINFO; - break; - case LOG_NOTICE: - xbmcLogLevel = LOGNOTICE; - break; - case LOG_DEBUG: - default: - xbmcLogLevel = LOGDEBUG; - break; - } - - std::string strXbmcMessage = StringUtils::Format("AddOnLog: %s: %s", addonHelper->m_addon->Name().c_str(), strMessage); - CLog::Log(xbmcLogLevel, "%s", strXbmcMessage.c_str()); - } - catch (std::exception &e) - { - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - exception '%s' caught in call in add-on '%s'. please contact the developer of this addon: %s", - __FUNCTION__, e.what(), addonHelper->m_addon->Name().c_str(), addonHelper->m_addon->Author().c_str()); - } -} - -void CAddonCallbacksAddon::QueueNotification(void *addonData, const queue_msg_t type, const char *strMessage) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL || strMessage == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - called with a null pointer", __FUNCTION__); - return; - } - - CAddonCallbacksAddon* addonHelper = addon->GetHelperAddon(); - - try - { - switch (type) - { - case QUEUE_WARNING: - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, addonHelper->m_addon->Name(), strMessage, 3000, true); - CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - %s - Warning Message: '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strMessage); - break; - - case QUEUE_ERROR: - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, addonHelper->m_addon->Name(), strMessage, 3000, true); - CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - %s - Error Message : '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strMessage); - break; - - case QUEUE_INFO: - default: - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, addonHelper->m_addon->Name(), strMessage, 3000, false); - CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - %s - Info Message : '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strMessage); - break; - } - } - catch (std::exception &e) - { - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - exception '%s' caught in call in add-on '%s'. please contact the developer of this addon: %s", - __FUNCTION__, e.what(), addonHelper->m_addon->Name().c_str(), addonHelper->m_addon->Author().c_str()); - } -} - -bool CAddonCallbacksAddon::WakeOnLan(const char *mac) -{ - return g_application.getNetwork().WakeOnLan(mac); -} - -bool CAddonCallbacksAddon::GetAddonSetting(void *addonData, const char *strSettingName, void *settingValue) -{ - CAddonCallbacks* addon = (CAddonCallbacks*) addonData; - if (addon == NULL || strSettingName == NULL || settingValue == NULL) - { - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - called with a null pointer", __FUNCTION__); - return false; - } - - CAddonCallbacksAddon* addonHelper = addon->GetHelperAddon(); - - try - { - CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - add-on '%s' requests setting '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strSettingName); - - if (!addonHelper->m_addon->ReloadSettings()) - { - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - could't get settings for add-on '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str()); - return false; - } - - const TiXmlElement *category = addonHelper->m_addon->GetSettingsXML()->FirstChildElement("category"); - if (!category) // add a default one... - category = addonHelper->m_addon->GetSettingsXML(); - - while (category) - { - const TiXmlElement *setting = category->FirstChildElement("setting"); - while (setting) - { - const std::string id = XMLUtils::GetAttribute(setting, "id"); - const std::string type = XMLUtils::GetAttribute(setting, "type"); - - if (id == strSettingName && !type.empty()) - { - if (type == "text" || type == "ipaddress" || - type == "folder" || type == "action" || - type == "music" || type == "pictures" || - type == "programs" || type == "fileenum" || - type == "file") - { - strcpy((char*) settingValue, addonHelper->m_addon->GetSetting(id).c_str()); - return true; - } - else if (type == "number" || type == "enum" || - type == "labelenum") - { - *(int*) settingValue = (int) atoi(addonHelper->m_addon->GetSetting(id).c_str()); - return true; - } - else if (type == "bool") - { - *(bool*) settingValue = (bool) (addonHelper->m_addon->GetSetting(id) == "true" ? true : false); - return true; - } - else if (type == "slider") - { - const char *option = setting->Attribute("option"); - if (option && strcmpi(option, "int") == 0) - { - *(int*) settingValue = (int) atoi(addonHelper->m_addon->GetSetting(id).c_str()); - return true; - } - else - { - *(float*) settingValue = (float) atof(addonHelper->m_addon->GetSetting(id).c_str()); - return true; - } - } - } - setting = setting->NextSiblingElement("setting"); - } - category = category->NextSiblingElement("category"); - } - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - can't find setting '%s' in '%s'", __FUNCTION__, strSettingName, addonHelper->m_addon->Name().c_str()); - } - catch (std::exception &e) - { - CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - exception '%s' caught in call in add-on '%s'. please contact the developer of this addon: %s", - __FUNCTION__, e.what(), addonHelper->m_addon->Name().c_str(), addonHelper->m_addon->Author().c_str()); - } - - return false; -} - -char* CAddonCallbacksAddon::UnknownToUTF8(const char *strSource) -{ - std::string string; - if (strSource != NULL) - g_charsetConverter.unknownToUTF8(strSource, string); - else - string = ""; - char* buffer = strdup(string.c_str()); - return buffer; -} - -char* CAddonCallbacksAddon::GetLocalizedString(const void* addonData, long dwCode) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || g_application.m_bStop) - return NULL; - - CAddonCallbacksAddon* addonHelper = helper->GetHelperAddon(); - - std::string string; - if (dwCode >= 30000 && dwCode <= 30999) - string = addonHelper->m_addon->GetString(dwCode).c_str(); - else if (dwCode >= 32000 && dwCode <= 32999) - string = addonHelper->m_addon->GetString(dwCode).c_str(); - else - string = g_localizeStrings.Get(dwCode).c_str(); - - char* buffer = strdup(string.c_str()); - return buffer; -} - -char* CAddonCallbacksAddon::GetDVDMenuLanguage(const void* addonData) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return NULL; - - std::string string = g_langInfo.GetDVDMenuLanguage(); - - char* buffer = strdup(string.c_str()); - return buffer; -} - -void CAddonCallbacksAddon::FreeString(const void* addonData, char* str) -{ - free(str); -} - -void* CAddonCallbacksAddon::OpenFile(const void* addonData, const char* strFileName, unsigned int flags) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return NULL; - - CFile* file = new CFile; - if (file->Open(strFileName, flags)) - return ((void*)file); - - delete file; - return NULL; -} - -void* CAddonCallbacksAddon::OpenFileForWrite(const void* addonData, const char* strFileName, bool bOverwrite) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return NULL; - - CFile* file = new CFile; - if (file->OpenForWrite(strFileName, bOverwrite)) - return ((void*)file); - - delete file; - return NULL; -} - -ssize_t CAddonCallbacksAddon::ReadFile(const void* addonData, void* file, void* lpBuf, size_t uiBufSize) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return 0; - - CFile* cfile = (CFile*)file; - if (!cfile) - return 0; - - return cfile->Read(lpBuf, uiBufSize); -} - -bool CAddonCallbacksAddon::ReadFileString(const void* addonData, void* file, char *szLine, int iLineLength) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CFile* cfile = (CFile*)file; - if (!cfile) - return false; - - return cfile->ReadString(szLine, iLineLength); -} - -ssize_t CAddonCallbacksAddon::WriteFile(const void* addonData, void* file, const void* lpBuf, size_t uiBufSize) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return -1; - - CFile* cfile = (CFile*)file; - if (!cfile) - return -1; - - return cfile->Write(lpBuf, uiBufSize); -} - -void CAddonCallbacksAddon::FlushFile(const void* addonData, void* file) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CFile* cfile = (CFile*)file; - if (!cfile) - return; - - cfile->Flush(); -} - -int64_t CAddonCallbacksAddon::SeekFile(const void* addonData, void* file, int64_t iFilePosition, int iWhence) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return 0; - - CFile* cfile = (CFile*)file; - if (!cfile) - return 0; - - return cfile->Seek(iFilePosition, iWhence); -} - -int CAddonCallbacksAddon::TruncateFile(const void* addonData, void* file, int64_t iSize) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return 0; - - CFile* cfile = (CFile*)file; - if (!cfile) - return 0; - - return cfile->Truncate(iSize); -} - -int64_t CAddonCallbacksAddon::GetFilePosition(const void* addonData, void* file) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return 0; - - CFile* cfile = (CFile*)file; - if (!cfile) - return 0; - - return cfile->GetPosition(); -} - -int64_t CAddonCallbacksAddon::GetFileLength(const void* addonData, void* file) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return 0; - - CFile* cfile = (CFile*)file; - if (!cfile) - return 0; - - return cfile->GetLength(); -} - -void CAddonCallbacksAddon::CloseFile(const void* addonData, void* file) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CFile* cfile = (CFile*)file; - if (cfile) - { - cfile->Close(); - delete cfile; - } -} - -int CAddonCallbacksAddon::GetFileChunkSize(const void* addonData, void* file) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return 0; - - CFile* cfile = (CFile*)file; - if (!cfile) - return 0; - - return cfile->GetChunkSize(); -} - -bool CAddonCallbacksAddon::FileExists(const void* addonData, const char *strFileName, bool bUseCache) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - return CFile::Exists(strFileName, bUseCache); -} - -int CAddonCallbacksAddon::StatFile(const void* addonData, const char *strFileName, struct __stat64* buffer) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return -1; - - return CFile::Stat(strFileName, buffer); -} - -bool CAddonCallbacksAddon::DeleteFile(const void* addonData, const char *strFileName) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - return CFile::Delete(strFileName); -} - -bool CAddonCallbacksAddon::CanOpenDirectory(const void* addonData, const char* strURL) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CFileItemList items; - return CDirectory::GetDirectory(strURL, items); -} - -bool CAddonCallbacksAddon::CreateDirectory(const void* addonData, const char *strPath) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - return CDirectory::Create(strPath); -} - -bool CAddonCallbacksAddon::DirectoryExists(const void* addonData, const char *strPath) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - return CDirectory::Exists(strPath); -} - -bool CAddonCallbacksAddon::RemoveDirectory(const void* addonData, const char *strPath) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - // Empty directory - CFileItemList fileItems; - CDirectory::GetDirectory(strPath, fileItems); - for (int i = 0; i < fileItems.Size(); ++i) - CFile::Delete(fileItems.Get(i)->GetPath()); - - return CDirectory::Remove(strPath); -} - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksAddon.h b/xbmc/addons/AddonCallbacksAddon.h deleted file mode 100644 index 6eed7cd..0000000 --- a/xbmc/addons/AddonCallbacksAddon.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "AddonCallbacks.h" - -namespace ADDON -{ - -class CAddonCallbacksAddon -{ -public: - CAddonCallbacksAddon(CAddon* addon); - ~CAddonCallbacksAddon(); - - /*! - * @return The callback table. - */ - CB_AddOnLib *GetCallbacks() { return m_callbacks; } - - static void AddOnLog(void *addonData, const addon_log_t addonLogLevel, const char *strMessage); - static bool GetAddonSetting(void *addonData, const char *strSettingName, void *settingValue); - static void QueueNotification(void *addonData, const queue_msg_t type, const char *strMessage); - static bool WakeOnLan(const char *mac); - static char* UnknownToUTF8(const char *strSource); - static char* GetLocalizedString(const void* addonData, long dwCode); - static char* GetDVDMenuLanguage(const void* addonData); - static void FreeString(const void* addonData, char* str); - - // 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 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 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); - static int64_t GetFilePosition(const void* addonData, void* file); - static int64_t GetFileLength(const void* addonData, void* file); - static void CloseFile(const void* addonData, void* file); - static int GetFileChunkSize(const void* addonData, void* file); - static bool FileExists(const void* addonData, const char *strFileName, bool bUseCache); - static int StatFile(const void* addonData, const char *strFileName, struct __stat64* buffer); - static bool DeleteFile(const void* addonData, const char *strFileName); - static bool CanOpenDirectory(const void* addonData, const char* strURL); - static bool CreateDirectory(const void* addonData, const char *strPath); - static bool DirectoryExists(const void* addonData, const char *strPath); - static bool RemoveDirectory(const void* addonData, const char *strPath); - -private: - CB_AddOnLib *m_callbacks; /*!< callback addresses */ - CAddon *m_addon; /*!< the add-on */ -}; - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksCodec.cpp b/xbmc/addons/AddonCallbacksCodec.cpp deleted file mode 100644 index 9c7be30..0000000 --- a/xbmc/addons/AddonCallbacksCodec.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "Application.h" -#include "Addon.h" -#include "AddonCallbacksCodec.h" -#include "utils/StringUtils.h" - -extern "C" { -#include "libavcodec/avcodec.h" -#include "libavformat/avformat.h" -} - -namespace ADDON -{ -class CCodecIds -{ -public: - virtual ~CCodecIds(void) {} - - static CCodecIds& Get(void) - { - static CCodecIds _instance; - return _instance; - } - - xbmc_codec_t GetCodecByName(const char* strCodecName) - { - xbmc_codec_t retVal = XBMC_INVALID_CODEC; - if (strlen(strCodecName) == 0) - return retVal; - - std::string strUpperCodecName = strCodecName; - StringUtils::ToUpper(strUpperCodecName); - - std::map::const_iterator it = m_lookup.find(strUpperCodecName); - if (it != m_lookup.end()) - retVal = it->second; - - return retVal; - } - -private: - CCodecIds(void) - { - // get ids and names - AVCodec* codec = NULL; - xbmc_codec_t tmp; - while ((codec = av_codec_next(codec))) - { - if (av_codec_is_decoder(codec)) - { - tmp.codec_type = (xbmc_codec_type_t)codec->type; - tmp.codec_id = codec->id; - - std::string strUpperCodecName = codec->name; - StringUtils::ToUpper(strUpperCodecName); - - m_lookup.insert(std::make_pair(strUpperCodecName, tmp)); - } - } - - // teletext is not returned by av_codec_next. we got our own decoder - tmp.codec_type = XBMC_CODEC_TYPE_SUBTITLE; - tmp.codec_id = AV_CODEC_ID_DVB_TELETEXT; - m_lookup.insert(std::make_pair("TELETEXT", tmp)); - - // rds is not returned by av_codec_next. we got our own decoder - tmp.codec_type = XBMC_CODEC_TYPE_RDS; - tmp.codec_id = AV_CODEC_ID_NONE; - m_lookup.insert(std::make_pair("RDS", tmp)); - } - - std::map m_lookup; -}; - -CAddonCallbacksCodec::CAddonCallbacksCodec(CAddon* addon) -{ - m_addon = addon; - m_callbacks = new CB_CODECLib; - - /* write XBMC addon-on specific add-on function addresses to the callback table */ - m_callbacks->GetCodecByName = GetCodecByName; -} - -CAddonCallbacksCodec::~CAddonCallbacksCodec() -{ - /* delete the callback table */ - delete m_callbacks; -} - -xbmc_codec_t CAddonCallbacksCodec::GetCodecByName(const void* addonData, const char* strCodecName) -{ - (void)addonData; - return CCodecIds::Get().GetCodecByName(strCodecName); -} - -}; /* namespace ADDON */ - diff --git a/xbmc/addons/AddonCallbacksCodec.h b/xbmc/addons/AddonCallbacksCodec.h deleted file mode 100644 index 5b816fe..0000000 --- a/xbmc/addons/AddonCallbacksCodec.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "AddonCallbacks.h" - -namespace ADDON -{ - -class CAddonCallbacksCodec -{ -public: - CAddonCallbacksCodec(CAddon* addon); - ~CAddonCallbacksCodec(); - - /*! - * @return The callback table. - */ - CB_CODECLib *GetCallbacks() { return m_callbacks; } - - static xbmc_codec_t GetCodecByName(const void* addonData, const char* strCodecName); - -private: - CB_CODECLib* m_callbacks; /*!< callback addresses */ - CAddon* m_addon; /*!< the add-on */ -}; - -}; /* namespace ADDON */ - diff --git a/xbmc/addons/AddonCallbacksGUI.cpp b/xbmc/addons/AddonCallbacksGUI.cpp deleted file mode 100644 index 3069039..0000000 --- a/xbmc/addons/AddonCallbacksGUI.cpp +++ /dev/null @@ -1,2281 +0,0 @@ -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "Application.h" -#include "ApplicationMessenger.h" -#include "Addon.h" -#include "AddonCallbacksGUI.h" -#include "utils/log.h" -#include "Skin.h" -#include "FileItem.h" -#include "filesystem/File.h" -#include "utils/URIUtils.h" -#include "utils/TimeUtils.h" -#include "utils/StringUtils.h" -#include "guilib/GUIWindowManager.h" -#include "input/Key.h" -#include "guilib/TextureManager.h" -#include "guilib/GUISpinControlEx.h" -#include "guilib/GUIRadioButtonControl.h" -#include "guilib/GUISettingsSliderControl.h" -#include "guilib/GUIEditControl.h" -#include "guilib/GUIProgressControl.h" -#include "guilib/GUIRenderingControl.h" -#include "guilib/GUIKeyboardFactory.h" -#include "dialogs/GUIDialogNumeric.h" -#include "dialogs/GUIDialogOK.h" -#include "dialogs/GUIDialogYesNo.h" -#include "dialogs/GUIDialogFileBrowser.h" -#include "dialogs/GUIDialogTextViewer.h" -#include "dialogs/GUIDialogSelect.h" - -#define CONTROL_BTNVIEWASICONS 2 -#define CONTROL_BTNSORTBY 3 -#define CONTROL_BTNSORTASC 4 -#define CONTROL_LABELFILES 12 - -using namespace std; - -namespace ADDON -{ - -static int iXBMCGUILockRef = 0; - -CAddonCallbacksGUI::CAddonCallbacksGUI(CAddon* addon) -{ - m_addon = addon; - m_callbacks = new CB_GUILib; - - /* GUI Helper functions */ - m_callbacks->Lock = CAddonCallbacksGUI::Lock; - m_callbacks->Unlock = CAddonCallbacksGUI::Unlock; - m_callbacks->GetScreenHeight = CAddonCallbacksGUI::GetScreenHeight; - m_callbacks->GetScreenWidth = CAddonCallbacksGUI::GetScreenWidth; - m_callbacks->GetVideoResolution = CAddonCallbacksGUI::GetVideoResolution; - m_callbacks->Window_New = CAddonCallbacksGUI::Window_New; - m_callbacks->Window_Delete = CAddonCallbacksGUI::Window_Delete; - m_callbacks->Window_SetCallbacks = CAddonCallbacksGUI::Window_SetCallbacks; - m_callbacks->Window_Show = CAddonCallbacksGUI::Window_Show; - m_callbacks->Window_Close = CAddonCallbacksGUI::Window_Close; - m_callbacks->Window_DoModal = CAddonCallbacksGUI::Window_DoModal; - m_callbacks->Window_SetFocusId = CAddonCallbacksGUI::Window_SetFocusId; - m_callbacks->Window_GetFocusId = CAddonCallbacksGUI::Window_GetFocusId; - m_callbacks->Window_SetCoordinateResolution = CAddonCallbacksGUI::Window_SetCoordinateResolution; - m_callbacks->Window_SetProperty = CAddonCallbacksGUI::Window_SetProperty; - m_callbacks->Window_SetPropertyInt = CAddonCallbacksGUI::Window_SetPropertyInt; - m_callbacks->Window_SetPropertyBool = CAddonCallbacksGUI::Window_SetPropertyBool; - m_callbacks->Window_SetPropertyDouble = CAddonCallbacksGUI::Window_SetPropertyDouble; - m_callbacks->Window_GetProperty = CAddonCallbacksGUI::Window_GetProperty; - m_callbacks->Window_GetPropertyInt = CAddonCallbacksGUI::Window_GetPropertyInt; - m_callbacks->Window_GetPropertyBool = CAddonCallbacksGUI::Window_GetPropertyBool; - m_callbacks->Window_GetPropertyDouble = CAddonCallbacksGUI::Window_GetPropertyDouble; - m_callbacks->Window_ClearProperties = CAddonCallbacksGUI::Window_ClearProperties; - - m_callbacks->Window_GetListSize = CAddonCallbacksGUI::Window_GetListSize; - m_callbacks->Window_ClearList = CAddonCallbacksGUI::Window_ClearList; - m_callbacks->Window_AddItem = CAddonCallbacksGUI::Window_AddItem; - m_callbacks->Window_AddStringItem = CAddonCallbacksGUI::Window_AddStringItem; - m_callbacks->Window_RemoveItem = CAddonCallbacksGUI::Window_RemoveItem; - m_callbacks->Window_GetListItem = CAddonCallbacksGUI::Window_GetListItem; - m_callbacks->Window_SetCurrentListPosition = CAddonCallbacksGUI::Window_SetCurrentListPosition; - m_callbacks->Window_GetCurrentListPosition = CAddonCallbacksGUI::Window_GetCurrentListPosition; - - m_callbacks->Window_GetControl_Spin = CAddonCallbacksGUI::Window_GetControl_Spin; - m_callbacks->Window_GetControl_Button = CAddonCallbacksGUI::Window_GetControl_Button; - m_callbacks->Window_GetControl_RadioButton = CAddonCallbacksGUI::Window_GetControl_RadioButton; - m_callbacks->Window_GetControl_Edit = CAddonCallbacksGUI::Window_GetControl_Edit; - m_callbacks->Window_GetControl_Progress = CAddonCallbacksGUI::Window_GetControl_Progress; - m_callbacks->Window_GetControl_RenderAddon = CAddonCallbacksGUI::Window_GetControl_RenderAddon; - m_callbacks->Window_GetControl_Slider = CAddonCallbacksGUI::Window_GetControl_Slider; - m_callbacks->Window_GetControl_SettingsSlider= CAddonCallbacksGUI::Window_GetControl_SettingsSlider; - - m_callbacks->Window_SetControlLabel = CAddonCallbacksGUI::Window_SetControlLabel; - m_callbacks->Window_MarkDirtyRegion = CAddonCallbacksGUI::Window_MarkDirtyRegion; - - m_callbacks->Control_Spin_SetVisible = CAddonCallbacksGUI::Control_Spin_SetVisible; - m_callbacks->Control_Spin_SetText = CAddonCallbacksGUI::Control_Spin_SetText; - m_callbacks->Control_Spin_Clear = CAddonCallbacksGUI::Control_Spin_Clear; - m_callbacks->Control_Spin_AddLabel = CAddonCallbacksGUI::Control_Spin_AddLabel; - m_callbacks->Control_Spin_GetValue = CAddonCallbacksGUI::Control_Spin_GetValue; - m_callbacks->Control_Spin_SetValue = CAddonCallbacksGUI::Control_Spin_SetValue; - - m_callbacks->Control_RadioButton_SetVisible = CAddonCallbacksGUI::Control_RadioButton_SetVisible; - m_callbacks->Control_RadioButton_SetText = CAddonCallbacksGUI::Control_RadioButton_SetText; - m_callbacks->Control_RadioButton_SetSelected= CAddonCallbacksGUI::Control_RadioButton_SetSelected; - m_callbacks->Control_RadioButton_IsSelected = CAddonCallbacksGUI::Control_RadioButton_IsSelected; - - m_callbacks->Control_Progress_SetPercentage = CAddonCallbacksGUI::Control_Progress_SetPercentage; - m_callbacks->Control_Progress_GetPercentage = CAddonCallbacksGUI::Control_Progress_GetPercentage; - m_callbacks->Control_Progress_SetInfo = CAddonCallbacksGUI::Control_Progress_SetInfo; - m_callbacks->Control_Progress_GetInfo = CAddonCallbacksGUI::Control_Progress_GetInfo; - m_callbacks->Control_Progress_GetDescription= CAddonCallbacksGUI::Control_Progress_GetDescription; - - m_callbacks->ListItem_Create = CAddonCallbacksGUI::ListItem_Create; - m_callbacks->ListItem_GetLabel = CAddonCallbacksGUI::ListItem_GetLabel; - m_callbacks->ListItem_SetLabel = CAddonCallbacksGUI::ListItem_SetLabel; - m_callbacks->ListItem_GetLabel2 = CAddonCallbacksGUI::ListItem_GetLabel2; - m_callbacks->ListItem_SetLabel2 = CAddonCallbacksGUI::ListItem_SetLabel2; - m_callbacks->ListItem_SetIconImage = CAddonCallbacksGUI::ListItem_SetIconImage; - m_callbacks->ListItem_SetThumbnailImage = CAddonCallbacksGUI::ListItem_SetThumbnailImage; - m_callbacks->ListItem_SetInfo = CAddonCallbacksGUI::ListItem_SetInfo; - m_callbacks->ListItem_SetProperty = CAddonCallbacksGUI::ListItem_SetProperty; - m_callbacks->ListItem_GetProperty = CAddonCallbacksGUI::ListItem_GetProperty; - m_callbacks->ListItem_SetPath = CAddonCallbacksGUI::ListItem_SetPath; - - m_callbacks->RenderAddon_SetCallbacks = CAddonCallbacksGUI::RenderAddon_SetCallbacks; - m_callbacks->RenderAddon_Delete = CAddonCallbacksGUI::RenderAddon_Delete; - - m_callbacks->Control_Slider_SetVisible = CAddonCallbacksGUI::Control_Slider_SetVisible; - m_callbacks->Control_Slider_GetDescription = CAddonCallbacksGUI::Control_Slider_GetDescription; - m_callbacks->Control_Slider_SetIntRange = CAddonCallbacksGUI::Control_Slider_SetIntRange; - m_callbacks->Control_Slider_SetIntValue = CAddonCallbacksGUI::Control_Slider_SetIntValue; - m_callbacks->Control_Slider_GetIntValue = CAddonCallbacksGUI::Control_Slider_GetIntValue; - m_callbacks->Control_Slider_SetIntInterval = CAddonCallbacksGUI::Control_Slider_SetIntInterval; - m_callbacks->Control_Slider_SetPercentage = CAddonCallbacksGUI::Control_Slider_SetPercentage; - m_callbacks->Control_Slider_GetPercentage = CAddonCallbacksGUI::Control_Slider_GetPercentage; - m_callbacks->Control_Slider_SetFloatRange = CAddonCallbacksGUI::Control_Slider_SetFloatRange; - m_callbacks->Control_Slider_SetFloatValue = CAddonCallbacksGUI::Control_Slider_SetFloatValue; - m_callbacks->Control_Slider_GetFloatValue = CAddonCallbacksGUI::Control_Slider_GetFloatValue; - m_callbacks->Control_Slider_SetFloatInterval = CAddonCallbacksGUI::Control_Slider_SetFloatInterval; - - m_callbacks->Control_SettingsSlider_SetVisible = CAddonCallbacksGUI::Control_SettingsSlider_SetVisible; - m_callbacks->Control_SettingsSlider_SetText = CAddonCallbacksGUI::Control_SettingsSlider_SetText; - m_callbacks->Control_SettingsSlider_GetDescription = CAddonCallbacksGUI::Control_SettingsSlider_GetDescription; - m_callbacks->Control_SettingsSlider_SetIntRange = CAddonCallbacksGUI::Control_SettingsSlider_SetIntRange; - m_callbacks->Control_SettingsSlider_SetIntValue = CAddonCallbacksGUI::Control_SettingsSlider_SetIntValue; - m_callbacks->Control_SettingsSlider_GetIntValue = CAddonCallbacksGUI::Control_SettingsSlider_GetIntValue; - m_callbacks->Control_SettingsSlider_SetIntInterval = CAddonCallbacksGUI::Control_SettingsSlider_SetIntInterval; - m_callbacks->Control_SettingsSlider_SetPercentage = CAddonCallbacksGUI::Control_SettingsSlider_SetPercentage; - m_callbacks->Control_SettingsSlider_GetPercentage = CAddonCallbacksGUI::Control_SettingsSlider_GetPercentage; - m_callbacks->Control_SettingsSlider_SetFloatRange = CAddonCallbacksGUI::Control_SettingsSlider_SetFloatRange; - m_callbacks->Control_SettingsSlider_SetFloatValue = CAddonCallbacksGUI::Control_SettingsSlider_SetFloatValue; - m_callbacks->Control_SettingsSlider_GetFloatValue = CAddonCallbacksGUI::Control_SettingsSlider_GetFloatValue; - m_callbacks->Control_SettingsSlider_SetFloatInterval = CAddonCallbacksGUI::Control_SettingsSlider_SetFloatInterval; - - m_callbacks->Dialog_Keyboard_ShowAndGetInputWithHead = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInputWithHead; - m_callbacks->Dialog_Keyboard_ShowAndGetInput = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInput; - m_callbacks->Dialog_Keyboard_ShowAndGetNewPasswordWithHead = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPasswordWithHead; - m_callbacks->Dialog_Keyboard_ShowAndGetNewPassword = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPassword; - m_callbacks->Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead; - m_callbacks->Dialog_Keyboard_ShowAndVerifyNewPassword = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPassword; - m_callbacks->Dialog_Keyboard_ShowAndVerifyPassword = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyPassword; - m_callbacks->Dialog_Keyboard_ShowAndGetFilter = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetFilter; - m_callbacks->Dialog_Keyboard_SendTextToActiveKeyboard = CAddonCallbacksGUI::Dialog_Keyboard_SendTextToActiveKeyboard; - m_callbacks->Dialog_Keyboard_isKeyboardActivated = CAddonCallbacksGUI::Dialog_Keyboard_isKeyboardActivated; - - m_callbacks->Dialog_Numeric_ShowAndVerifyNewPassword = CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyNewPassword; - m_callbacks->Dialog_Numeric_ShowAndVerifyPassword = CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyPassword; - m_callbacks->Dialog_Numeric_ShowAndVerifyInput = CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyInput; - m_callbacks->Dialog_Numeric_ShowAndGetTime = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetTime; - m_callbacks->Dialog_Numeric_ShowAndGetDate = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetDate; - m_callbacks->Dialog_Numeric_ShowAndGetIPAddress = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetIPAddress; - m_callbacks->Dialog_Numeric_ShowAndGetNumber = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetNumber; - m_callbacks->Dialog_Numeric_ShowAndGetSeconds = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetSeconds; - - m_callbacks->Dialog_FileBrowser_ShowAndGetFile = CAddonCallbacksGUI::Dialog_FileBrowser_ShowAndGetFile; - - m_callbacks->Dialog_OK_ShowAndGetInputSingleText = CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputSingleText; - m_callbacks->Dialog_OK_ShowAndGetInputLineText = CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputLineText; - - m_callbacks->Dialog_YesNo_ShowAndGetInputSingleText = CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputSingleText; - m_callbacks->Dialog_YesNo_ShowAndGetInputLineText = CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineText; - m_callbacks->Dialog_YesNo_ShowAndGetInputLineButtonText = CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineButtonText; - - m_callbacks->Dialog_TextViewer = CAddonCallbacksGUI::Dialog_TextViewer; - - m_callbacks->Dialog_Select = CAddonCallbacksGUI::Dialog_Select; -} - -CAddonCallbacksGUI::~CAddonCallbacksGUI() -{ - delete m_callbacks; -} - -void CAddonCallbacksGUI::Lock() -{ - if (iXBMCGUILockRef == 0) g_graphicsContext.Lock(); - iXBMCGUILockRef++; -} - -void CAddonCallbacksGUI::Unlock() -{ - if (iXBMCGUILockRef > 0) - { - iXBMCGUILockRef--; - if (iXBMCGUILockRef == 0) g_graphicsContext.Unlock(); - } -} - -int CAddonCallbacksGUI::GetScreenHeight() -{ - return g_graphicsContext.GetHeight(); -} - -int CAddonCallbacksGUI::GetScreenWidth() -{ - return g_graphicsContext.GetWidth(); -} - -int CAddonCallbacksGUI::GetVideoResolution() -{ - return (int)g_graphicsContext.GetVideoResolution(); -} - -GUIHANDLE CAddonCallbacksGUI::Window_New(void *addonData, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return NULL; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - RESOLUTION_INFO res; - std::string strSkinPath; - if (!forceFallback) - { - /* Check to see if the XML file exists in current skin. If not use - fallback path to find a skin for the addon */ - strSkinPath = g_SkinInfo->GetSkinPath(xmlFilename, &res); - - if (!XFILE::CFile::Exists(strSkinPath)) - { - /* Check for the matching folder for the skin in the fallback skins folder */ - std::string basePath = URIUtils::AddFileToFolder(guiHelper->m_addon->Path(), "resources"); - basePath = URIUtils::AddFileToFolder(basePath, "skins"); - basePath = URIUtils::AddFileToFolder(basePath, URIUtils::GetFileName(g_SkinInfo->Path())); - strSkinPath = g_SkinInfo->GetSkinPath(xmlFilename, &res, basePath); - if (!XFILE::CFile::Exists(strSkinPath)) - { - /* Finally fallback to the DefaultSkin as it didn't exist in either the - XBMC Skin folder or the fallback skin folder */ - forceFallback = true; - } - } - } - - if (forceFallback) - { - //FIXME make this static method of current skin? - std::string str("none"); - AddonProps props(str, ADDON_SKIN, str, str); - std::string basePath = URIUtils::AddFileToFolder(guiHelper->m_addon->Path(), "resources"); - basePath = URIUtils::AddFileToFolder(basePath, "skins"); - basePath = URIUtils::AddFileToFolder(basePath, defaultSkin); - props.path = basePath; - - CSkinInfo skinInfo(props); - skinInfo.Start(); - strSkinPath = skinInfo.GetSkinPath(xmlFilename, &res, basePath); - - if (!XFILE::CFile::Exists(strSkinPath)) - { - CLog::Log(LOGERROR, "Window_New: %s/%s - XML File '%s' for Window is missing, contact Developer '%s' of this AddOn", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str(), strSkinPath.c_str(), guiHelper->m_addon->Author().c_str()); - return NULL; - } - } - // window id's 14000 - 14100 are reserved for addons - // get first window id that is not in use - int id = WINDOW_ADDON_START; - // if window 14099 is in use it means addon can't create more windows - Lock(); - if (g_windowManager.GetWindow(WINDOW_ADDON_END)) - { - Unlock(); - CLog::Log(LOGERROR, "Window_New: %s/%s - maximum number of windows reached", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return NULL; - } - while(id < WINDOW_ADDON_END && g_windowManager.GetWindow(id) != NULL) id++; - Unlock(); - - CGUIWindow *window; - if (!asDialog) - window = new CGUIAddonWindow(id, strSkinPath, guiHelper->m_addon); - else - window = new CGUIAddonWindowDialog(id, strSkinPath, guiHelper->m_addon); - - Lock(); - g_windowManager.Add(window); - Unlock(); - - window->SetCoordsRes(res); - - return window; -} - -void CAddonCallbacksGUI::Window_Delete(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "Window_Show: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return; - - Lock(); - // first change to an existing window - if (g_windowManager.GetActiveWindow() == pAddonWindow->m_iWindowId && !g_application.m_bStop) - { - if(g_windowManager.GetWindow(pAddonWindow->m_iOldWindowId)) - g_windowManager.ActivateWindow(pAddonWindow->m_iOldWindowId); - else // old window does not exist anymore, switch to home - g_windowManager.ActivateWindow(WINDOW_HOME); - } - // Free any window properties - pAddonWindow->ClearProperties(); - // free the window's resources and unload it (free all guicontrols) - pAddonWindow->FreeResources(true); - - g_windowManager.Remove(pAddonWindow->GetID()); - delete pAddonWindow; - Unlock(); -} - -void CAddonCallbacksGUI::Window_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*initCB)(GUIHANDLE), bool (*clickCB)(GUIHANDLE, int), bool (*focusCB)(GUIHANDLE, int), bool (*onActionCB)(GUIHANDLE handle, int)) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - Lock(); - pAddonWindow->m_clientHandle = clienthandle; - pAddonWindow->CBOnInit = initCB; - pAddonWindow->CBOnClick = clickCB; - pAddonWindow->CBOnFocus = focusCB; - pAddonWindow->CBOnAction = onActionCB; - Unlock(); -} - -bool CAddonCallbacksGUI::Window_Show(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "Window_Show: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return false; - - if (pAddonWindow->m_iOldWindowId != pAddonWindow->m_iWindowId && pAddonWindow->m_iWindowId != g_windowManager.GetActiveWindow()) - pAddonWindow->m_iOldWindowId = g_windowManager.GetActiveWindow(); - - Lock(); - if (pAddonWindow->IsDialog()) - ((CGUIAddonWindowDialog*)pAddonWindow)->Show(); - else - g_windowManager.ActivateWindow(pAddonWindow->m_iWindowId); - Unlock(); - - return true; -} - -bool CAddonCallbacksGUI::Window_Close(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "Window_Close: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return false; - - pAddonWindow->m_bModal = false; - if (pAddonWindow->IsDialog()) - ((CGUIAddonWindowDialog*)pAddonWindow)->PulseActionEvent(); - else - ((CGUIAddonWindow*)pAddonWindow)->PulseActionEvent(); - - Lock(); - // if it's a dialog, we have to close it a bit different - if (pAddonWindow->IsDialog()) - ((CGUIAddonWindowDialog*)pAddonWindow)->Show(false); - else - g_windowManager.ActivateWindow(pAddonWindow->m_iOldWindowId); - pAddonWindow->m_iOldWindowId = 0; - - Unlock(); - - return true; -} - -bool CAddonCallbacksGUI::Window_DoModal(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "Window_DoModal: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return false; - - pAddonWindow->m_bModal = true; - - if (pAddonWindow->m_iWindowId != g_windowManager.GetActiveWindow()) - Window_Show(addonData, handle); - - return true; -} - -bool CAddonCallbacksGUI::Window_SetFocusId(void *addonData, GUIHANDLE handle, int iControlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "Window_SetFocusId: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return false; - - if(!pWindow->GetControl(iControlId)) - { - CLog::Log(LOGERROR, "Window_SetFocusId: %s/%s - Control does not exist in window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - Lock(); - CGUIMessage msg = CGUIMessage(GUI_MSG_SETFOCUS, pAddonWindow->m_iWindowId, iControlId); - pWindow->OnMessage(msg); - Unlock(); - - return true; -} - -int CAddonCallbacksGUI::Window_GetFocusId(void *addonData, GUIHANDLE handle) -{ - int iControlId = -1; - - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return iControlId; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "Window_GetFocusId: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return iControlId; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return iControlId; - - Lock(); - iControlId = pWindow->GetFocusedControlID(); - Unlock(); - - if (iControlId == -1) - { - CLog::Log(LOGERROR, "Window_GetFocusId: %s/%s - No control in this window has focus", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return iControlId; - } - - return iControlId; -} - -bool CAddonCallbacksGUI::Window_SetCoordinateResolution(void *addonData, GUIHANDLE handle, int res) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "SetCoordinateResolution: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - if (res < RES_HDTV_1080i || res > RES_AUTORES) - { - CLog::Log(LOGERROR, "SetCoordinateResolution: %s/%s - Invalid resolution", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return false; - - pWindow->SetCoordsRes((RESOLUTION)res); - - return true; -} - -void CAddonCallbacksGUI::Window_SetProperty(void *addonData, GUIHANDLE handle, const char *key, const char *value) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key || !value) - { - CLog::Log(LOGERROR, "Window_SetProperty: %s/%s - No Window or NULL key or value", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - pWindow->SetProperty(lowerKey, value); - Unlock(); -} - -void CAddonCallbacksGUI::Window_SetPropertyInt(void *addonData, GUIHANDLE handle, const char *key, int value) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key) - { - CLog::Log(LOGERROR, "Window_SetPropertyInt: %s/%s - No Window or NULL key", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - pWindow->SetProperty(lowerKey, value); - Unlock(); -} - -void CAddonCallbacksGUI::Window_SetPropertyBool(void *addonData, GUIHANDLE handle, const char *key, bool value) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key) - { - CLog::Log(LOGERROR, "Window_SetPropertyBool: %s/%s - No Window or NULL key", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - pWindow->SetProperty(lowerKey, value); - Unlock(); -} - -void CAddonCallbacksGUI::Window_SetPropertyDouble(void *addonData, GUIHANDLE handle, const char *key, double value) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key) - { - CLog::Log(LOGERROR, "Window_SetPropertyDouble: %s/%s - No Window or NULL key", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - pWindow->SetProperty(lowerKey, value); - Unlock(); -} - -const char* CAddonCallbacksGUI::Window_GetProperty(void *addonData, GUIHANDLE handle, const char *key) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return NULL; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key) - { - CLog::Log(LOGERROR, "Window_GetProperty: %s/%s - No Window or NULL key", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return NULL; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return NULL; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - string value = pWindow->GetProperty(lowerKey).asString(); - Unlock(); - - return strdup(value.c_str()); -} - -int CAddonCallbacksGUI::Window_GetPropertyInt(void *addonData, GUIHANDLE handle, const char *key) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return -1; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key) - { - CLog::Log(LOGERROR, "Window_GetPropertyInt: %s/%s - No Window or NULL key", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return -1; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return -1; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - int value = (int)pWindow->GetProperty(lowerKey).asInteger(); - Unlock(); - - return value; -} - -bool CAddonCallbacksGUI::Window_GetPropertyBool(void *addonData, GUIHANDLE handle, const char *key) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return false; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key) - { - CLog::Log(LOGERROR, "Window_GetPropertyBool: %s/%s - No Window or NULL key", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return false; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return false; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - bool value = pWindow->GetProperty(lowerKey).asBoolean(); - Unlock(); - - return value; -} - -double CAddonCallbacksGUI::Window_GetPropertyDouble(void *addonData, GUIHANDLE handle, const char *key) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return 0.0; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle || !key) - { - CLog::Log(LOGERROR, "Window_GetPropertyDouble: %s/%s - No Window or NULL key", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return 0.0; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return 0.0; - - std::string lowerKey = key; - StringUtils::ToLower(lowerKey); - - Lock(); - double value = pWindow->GetProperty(lowerKey).asDouble(); - Unlock(); - - return value; -} - -void CAddonCallbacksGUI::Window_ClearProperties(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - - if (!handle) - { - CLog::Log(LOGERROR, "Window_ClearProperties: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return; - } - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIWindow *pWindow = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId); - if (!pWindow) - return; - - Lock(); - pWindow->ClearProperties(); - Unlock(); -} - -int CAddonCallbacksGUI::Window_GetListSize(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return -1; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - Lock(); - int listSize = pAddonWindow->GetListSize(); - Unlock(); - - return listSize; -} - -void CAddonCallbacksGUI::Window_ClearList(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - Lock(); - pAddonWindow->ClearList(); - Unlock(); - - return; -} - -GUIHANDLE CAddonCallbacksGUI::Window_AddItem(void *addonData, GUIHANDLE handle, GUIHANDLE item, int itemPosition) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle || !item) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CFileItemPtr pItem((CFileItem*)item); - Lock(); - pAddonWindow->AddItem(pItem, itemPosition); - Unlock(); - - return item; -} - -GUIHANDLE CAddonCallbacksGUI::Window_AddStringItem(void *addonData, GUIHANDLE handle, const char *itemName, int itemPosition) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle || !itemName) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CFileItemPtr item(new CFileItem(itemName)); - Lock(); - pAddonWindow->AddItem(item, itemPosition); - Unlock(); - - return item.get(); -} - -void CAddonCallbacksGUI::Window_RemoveItem(void *addonData, GUIHANDLE handle, int itemPosition) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - Lock(); - pAddonWindow->RemoveItem(itemPosition); - Unlock(); - - return; -} - -GUIHANDLE CAddonCallbacksGUI::Window_GetListItem(void *addonData, GUIHANDLE handle, int listPos) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI(); - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - Lock(); - CFileItemPtr fi = pAddonWindow->GetListItem(listPos); - if (fi == NULL) - { - Unlock(); - CLog::Log(LOGERROR, "Window_GetListItem: %s/%s - Index out of range", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str()); - return NULL; - } - Unlock(); - - return fi.get(); -} - -void CAddonCallbacksGUI::Window_SetCurrentListPosition(void *addonData, GUIHANDLE handle, int listPos) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - Lock(); - pAddonWindow->SetCurrentListPosition(listPos); - Unlock(); - - return; -} - -int CAddonCallbacksGUI::Window_GetCurrentListPosition(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return -1; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - Lock(); - int listPos = pAddonWindow->GetCurrentListPosition(); - Unlock(); - - return listPos; -} - -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Spin(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_SPINEX) - return NULL; - - return pGUIControl; -} - -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Button(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_BUTTON) - return NULL; - - return pGUIControl; -} - -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_RadioButton(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_RADIO) - return NULL; - - return pGUIControl; -} - -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Edit(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_EDIT) - return NULL; - - return pGUIControl; -} - -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Progress(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_PROGRESS) - return NULL; - - return pGUIControl; -} - -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_RenderAddon(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_RENDERADDON) - return NULL; - - CGUIAddonRenderingControl *pProxyControl; - pProxyControl = new CGUIAddonRenderingControl((CGUIRenderingControl*)pGUIControl); - return pProxyControl; -} - -void CAddonCallbacksGUI::Window_SetControlLabel(void *addonData, GUIHANDLE handle, int controlId, const char *label) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - CGUIMessage msg(GUI_MSG_LABEL_SET, pAddonWindow->m_iWindowId, controlId); - msg.SetLabel(label); - pAddonWindow->OnMessage(msg); -} - -void CAddonCallbacksGUI::Window_MarkDirtyRegion(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - - pAddonWindow->MarkDirtyRegion(); -} - -void CAddonCallbacksGUI::Control_Spin_SetVisible(void *addonData, GUIHANDLE spinhandle, bool yesNo) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !spinhandle) - return; - - CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle; - pSpin->SetVisible(yesNo); -} - -void CAddonCallbacksGUI::Control_Spin_SetText(void *addonData, GUIHANDLE spinhandle, const char *label) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !spinhandle) - return; - - CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle; - pSpin->SetText(label); -} - -void CAddonCallbacksGUI::Control_Spin_Clear(void *addonData, GUIHANDLE spinhandle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !spinhandle) - return; - - CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle; - pSpin->Clear(); -} - -void CAddonCallbacksGUI::Control_Spin_AddLabel(void *addonData, GUIHANDLE spinhandle, const char *label, int iValue) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !spinhandle) - return; - - CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle; - pSpin->AddLabel(label, iValue); -} - -int CAddonCallbacksGUI::Control_Spin_GetValue(void *addonData, GUIHANDLE spinhandle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !spinhandle) - return -1; - - CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle; - return pSpin->GetValue(); -} - -void CAddonCallbacksGUI::Control_Spin_SetValue(void *addonData, GUIHANDLE spinhandle, int iValue) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !spinhandle) - return; - - CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle; - pSpin->SetValue(iValue); -} - -void CAddonCallbacksGUI::Control_RadioButton_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle; - pRadioButton->SetVisible(yesNo); -} - -void CAddonCallbacksGUI::Control_RadioButton_SetText(void *addonData, GUIHANDLE handle, const char *label) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle; - pRadioButton->SetLabel(label); -} - -void CAddonCallbacksGUI::Control_RadioButton_SetSelected(void *addonData, GUIHANDLE handle, bool yesNo) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle; - pRadioButton->SetSelected(yesNo); -} - -bool CAddonCallbacksGUI::Control_RadioButton_IsSelected(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return false; - - CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle; - return pRadioButton->IsSelected(); -} - -void CAddonCallbacksGUI::Control_Progress_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIProgressControl *pControl = (CGUIProgressControl*)handle; - pControl->SetPercentage(fPercent); -} - -float CAddonCallbacksGUI::Control_Progress_GetPercentage(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return 0.0; - - CGUIProgressControl *pControl = (CGUIProgressControl*)handle; - return pControl->GetPercentage(); -} - -void CAddonCallbacksGUI::Control_Progress_SetInfo(void *addonData, GUIHANDLE handle, int iInfo) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIProgressControl *pControl = (CGUIProgressControl*)handle; - pControl->SetInfo(iInfo); -} - -int CAddonCallbacksGUI::Control_Progress_GetInfo(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return -1; - - CGUIProgressControl *pControl = (CGUIProgressControl*)handle; - return pControl->GetInfo(); -} - -const char* CAddonCallbacksGUI::Control_Progress_GetDescription(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIProgressControl *pControl = (CGUIProgressControl*)handle; - std::string string = pControl->GetDescription(); - - char *buffer = (char*) malloc (string.length()+1); - strcpy(buffer, string.c_str()); - return buffer; -} - -/* - * GUI slider control callback functions - */ -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Slider(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_SLIDER) - return NULL; - - return pGUIControl; -} - -void CAddonCallbacksGUI::Control_Slider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIControl *pControl = (CGUIControl*)handle; - pControl->SetVisible(yesNo); -} - -const char* CAddonCallbacksGUI::Control_Slider_GetDescription(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - std::string string = pControl->GetDescription(); - - char *buffer = (char*) malloc (string.length()+1); - strcpy(buffer, string.c_str()); - return buffer; -} - -void CAddonCallbacksGUI::Control_Slider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - pControl->SetRange(iStart, iEnd); -} - -void CAddonCallbacksGUI::Control_Slider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - pControl->SetType(SPIN_CONTROL_TYPE_INT); - pControl->SetIntValue(iValue); -} - -int CAddonCallbacksGUI::Control_Slider_GetIntValue(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return 0; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - return pControl->GetIntValue(); -} - -void CAddonCallbacksGUI::Control_Slider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - pControl->SetIntInterval(iInterval); -} - -void CAddonCallbacksGUI::Control_Slider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); - pControl->SetPercentage(fPercent); -} - -float CAddonCallbacksGUI::Control_Slider_GetPercentage(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return 0.0f; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - return pControl->GetPercentage(); -} - -void CAddonCallbacksGUI::Control_Slider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - pControl->SetFloatRange(fStart, fEnd); -} - -void CAddonCallbacksGUI::Control_Slider_SetFloatValue(void *addonData, GUIHANDLE handle, float iValue) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); - pControl->SetFloatValue(iValue); -} - -float CAddonCallbacksGUI::Control_Slider_GetFloatValue(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return 0.0f; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - return pControl->GetFloatValue(); -} - -void CAddonCallbacksGUI::Control_Slider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISliderControl *pControl = (CGUISliderControl*)handle; - pControl->SetFloatInterval(fInterval); -} - -/* - * GUI settings slider control callback functions - */ -GUIHANDLE CAddonCallbacksGUI::Window_GetControl_SettingsSlider(void *addonData, GUIHANDLE handle, int controlId) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; - CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); - if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_SETTINGS_SLIDER) - return NULL; - - return pGUIControl; -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIControl *pControl = (CGUIControl*)handle; - pControl->SetVisible(yesNo); -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetText(void *addonData, GUIHANDLE handle, const char *label) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetText(label); -} - -const char* CAddonCallbacksGUI::Control_SettingsSlider_GetDescription(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - std::string string = pControl->GetDescription(); - - char *buffer = (char*) malloc (string.length()+1); - strcpy(buffer, string.c_str()); - return buffer; -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetRange(iStart, iEnd); -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetType(SPIN_CONTROL_TYPE_INT); - pControl->SetIntValue(iValue); -} - -int CAddonCallbacksGUI::Control_SettingsSlider_GetIntValue(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return 0; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - return pControl->GetIntValue(); -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetIntInterval(iInterval); -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); - pControl->SetPercentage(fPercent); -} - -float CAddonCallbacksGUI::Control_SettingsSlider_GetPercentage(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return 0.0f; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - return pControl->GetPercentage(); -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetFloatRange(fStart, fEnd); -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetFloatValue(void *addonData, GUIHANDLE handle, float fValue) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); - pControl->SetFloatValue(fValue); -} - -float CAddonCallbacksGUI::Control_SettingsSlider_GetFloatValue(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return 0.0f; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - return pControl->GetFloatValue(); -} - -void CAddonCallbacksGUI::Control_SettingsSlider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; - pControl->SetFloatInterval(fInterval); -} - -/* - * GUI list item control callback functions - */ -GUIHANDLE CAddonCallbacksGUI::ListItem_Create(void *addonData, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper) - return NULL; - - // create CFileItem - CFileItem *pItem = new CFileItem(); - if (!pItem) - return NULL; - - if (label) - pItem->SetLabel(label); - if (label2) - pItem->SetLabel2(label2); - if (iconImage) - pItem->SetIconImage(iconImage); - if (thumbnailImage) - pItem->SetArt("thumb", thumbnailImage); - if (path) - pItem->SetPath(path); - - return pItem; -} - -const char* CAddonCallbacksGUI::ListItem_GetLabel(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - std::string string = ((CFileItem*)handle)->GetLabel(); - char *buffer = (char*) malloc (string.length()+1); - strcpy(buffer, string.c_str()); - return buffer; -} - -void CAddonCallbacksGUI::ListItem_SetLabel(void *addonData, GUIHANDLE handle, const char *label) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - ((CFileItem*)handle)->SetLabel(label); -} - -const char* CAddonCallbacksGUI::ListItem_GetLabel2(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - std::string string = ((CFileItem*)handle)->GetLabel2(); - - char *buffer = (char*) malloc (string.length()+1); - strcpy(buffer, string.c_str()); - return buffer; -} - -void CAddonCallbacksGUI::ListItem_SetLabel2(void *addonData, GUIHANDLE handle, const char *label) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - ((CFileItem*)handle)->SetLabel2(label); -} - -void CAddonCallbacksGUI::ListItem_SetIconImage(void *addonData, GUIHANDLE handle, const char *image) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - ((CFileItem*)handle)->SetIconImage(image); -} - -void CAddonCallbacksGUI::ListItem_SetThumbnailImage(void *addonData, GUIHANDLE handle, const char *image) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - ((CFileItem*)handle)->SetArt("thumb", image); -} - -void CAddonCallbacksGUI::ListItem_SetInfo(void *addonData, GUIHANDLE handle, const char *info) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - -} - -void CAddonCallbacksGUI::ListItem_SetProperty(void *addonData, GUIHANDLE handle, const char *key, const char *value) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - ((CFileItem*)handle)->SetProperty(key, value); -} - -const char* CAddonCallbacksGUI::ListItem_GetProperty(void *addonData, GUIHANDLE handle, const char *key) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return NULL; - - string string = ((CFileItem*)handle)->GetProperty(key).asString(); - char *buffer = (char*) malloc (string.length()+1); - strcpy(buffer, string.c_str()); - return buffer; -} - -void CAddonCallbacksGUI::ListItem_SetPath(void *addonData, GUIHANDLE handle, const char *path) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - ((CFileItem*)handle)->SetPath(path); -} - -void CAddonCallbacksGUI::RenderAddon_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*createCB)(GUIHANDLE,int,int,int,int,void*), void (*renderCB)(GUIHANDLE), void (*stopCB)(GUIHANDLE), bool (*dirtyCB)(GUIHANDLE)) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonRenderingControl *pAddonControl = (CGUIAddonRenderingControl*)handle; - - Lock(); - pAddonControl->m_clientHandle = clienthandle; - pAddonControl->CBCreate = createCB; - pAddonControl->CBRender = renderCB; - pAddonControl->CBStop = stopCB; - pAddonControl->CBDirty = dirtyCB; - Unlock(); - - pAddonControl->m_pControl->InitCallback(pAddonControl); -} - -void CAddonCallbacksGUI::RenderAddon_Delete(void *addonData, GUIHANDLE handle) -{ - CAddonCallbacks* helper = (CAddonCallbacks*) addonData; - if (!helper || !handle) - return; - - CGUIAddonRenderingControl *pAddonControl = (CGUIAddonRenderingControl*)handle; - - Lock(); - pAddonControl->Delete(); - Unlock(); -} - -/*! @name GUI Keyboard functions */ -//@{ -bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInputWithHead(char &aTextString, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs) -{ - std::string str = &aTextString; - bool bRet = CGUIKeyboardFactory::ShowAndGetInput(str, strHeading, allowEmptyResult, hiddenInput, autoCloseMs); - if (bRet) - strncpy(&aTextString, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInput(char &aTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs) -{ - std::string str = &aTextString; - bool bRet = CGUIKeyboardFactory::ShowAndGetInput(str, allowEmptyResult, autoCloseMs); - if (bRet) - strncpy(&aTextString, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPasswordWithHead(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs) -{ - std::string str = &strNewPassword; - bool bRet = CGUIKeyboardFactory::ShowAndGetNewPassword(str, strHeading, allowEmptyResult, autoCloseMs); - if (bRet) - strncpy(&strNewPassword, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs) -{ - std::string str = &strNewPassword; - bool bRet = CGUIKeyboardFactory::ShowAndGetNewPassword(str, autoCloseMs); - if (bRet) - strncpy(&strNewPassword, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs) -{ - std::string str = &strNewPassword; - bool bRet = CGUIKeyboardFactory::ShowAndVerifyNewPassword(str, strHeading, allowEmptyResult, autoCloseMs); - if (bRet) - strncpy(&strNewPassword, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs) -{ - std::string str = &strNewPassword; - bool bRet = CGUIKeyboardFactory::ShowAndVerifyNewPassword(str, autoCloseMs); - if (bRet) - strncpy(&strNewPassword, str.c_str(), iMaxStringSize); - return bRet; -} - -int CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs) -{ - std::string str = &strPassword; - int iRet = CGUIKeyboardFactory::ShowAndVerifyPassword(str, strHeading, iRetries, autoCloseMs); - if (iRet) - strncpy(&strPassword, str.c_str(), iMaxStringSize); - return iRet; -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetFilter(char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs) -{ - std::string strText = &aTextString; - bool bRet = CGUIKeyboardFactory::ShowAndGetFilter(strText, searching, autoCloseMs); - if (bRet) - strncpy(&aTextString, strText.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_SendTextToActiveKeyboard(const char *aTextString, bool closeKeyboard) -{ - return CGUIKeyboardFactory::SendTextToActiveKeyboard(aTextString, closeKeyboard); -} - -bool CAddonCallbacksGUI::Dialog_Keyboard_isKeyboardActivated() -{ - return CGUIKeyboardFactory::isKeyboardActivated(); -} -//@} - -/*! @name GUI Numeric functions */ -//@{ -bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize) -{ - std::string str = &strNewPassword; - bool bRet = CGUIDialogNumeric::ShowAndVerifyNewPassword(str); - if (bRet) - strncpy(&strNewPassword, str.c_str(), iMaxStringSize); - return bRet; -} - -int CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries) -{ - std::string str = &strPassword; - int bRet = CGUIDialogNumeric::ShowAndVerifyPassword(str, strHeading, iRetries); - if (bRet) - strncpy(&strPassword, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyInput(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput) -{ - std::string str = &strPassword; - bool bRet = CGUIDialogNumeric::ShowAndVerifyInput(str, strHeading, bGetUserInput); - if (bRet) - strncpy(&strPassword, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetTime(tm &time, const char *strHeading) -{ - SYSTEMTIME systemTime; - CDateTime dateTime(time); - dateTime.GetAsSystemTime(systemTime); - if (CGUIDialogNumeric::ShowAndGetTime(systemTime, strHeading)) - { - dateTime = systemTime; - dateTime.GetAsTm(time); - return true; - } - return false; -} - -bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetDate(tm &date, const char *strHeading) -{ - SYSTEMTIME systemTime; - CDateTime dateTime(date); - dateTime.GetAsSystemTime(systemTime); - if (CGUIDialogNumeric::ShowAndGetDate(systemTime, strHeading)) - { - dateTime = systemTime; - dateTime.GetAsTm(date); - return true; - } - return false; -} - -bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetIPAddress(char &strIPAddress, unsigned int iMaxStringSize, const char *strHeading) -{ - std::string strIP = &strIPAddress; - bool bRet = CGUIDialogNumeric::ShowAndGetIPAddress(strIP, strHeading); - if (bRet) - strncpy(&strIPAddress, strIP.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetNumber(char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs) -{ - std::string str = &strInput; - bool bRet = CGUIDialogNumeric::ShowAndGetNumber(str, strHeading, iAutoCloseTimeoutMs); - if (bRet) - strncpy(&strInput, str.c_str(), iMaxStringSize); - return bRet; -} - -bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetSeconds(char &timeString, unsigned int iMaxStringSize, const char *strHeading) -{ - std::string str = &timeString; - bool bRet = CGUIDialogNumeric::ShowAndGetSeconds(str, strHeading); - if (bRet) - strncpy(&timeString, str.c_str(), iMaxStringSize); - return bRet; -} -//@} - -/*! @name GUI File browser functions */ -//@{ -bool CAddonCallbacksGUI::Dialog_FileBrowser_ShowAndGetFile(const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList) -{ - std::string strPath = &path; - bool bRet = CGUIDialogFileBrowser::ShowAndGetFile(directory, mask, heading, strPath, useThumbs, useFileDirectories, singleList); - if (bRet) - strncpy(&path, strPath.c_str(), iMaxStringSize); - return bRet; -} -//@} - -/*! @name GUI OK Dialog */ -//@{ -void CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputSingleText(const char *heading, const char *text) -{ - CGUIDialogOK::ShowAndGetInput(heading, text); -} - -void CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2) -{ - CGUIDialogOK::ShowAndGetInput(heading, line0, line1, line2); -} -//@} - -/*! @name GUI Yes No Dialog */ -//@{ -bool CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputSingleText(const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel) -{ - return CGUIDialogYesNo::ShowAndGetInput(heading, text, bCanceled, noLabel, yesLabel); -} - -bool CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel) -{ - return CGUIDialogYesNo::ShowAndGetInput(heading, line0, line1, line2, noLabel, yesLabel); -} - -bool CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineButtonText(const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel) -{ - return CGUIDialogYesNo::ShowAndGetInput(heading, line0, line1, line2, bCanceled, noLabel, yesLabel); -} -//@} - -/*! @name GUI Text viewer Dialog */ -//@{ -void CAddonCallbacksGUI::Dialog_TextViewer(const char *heading, const char *text) -{ - CGUIDialogTextViewer* pDialog = (CGUIDialogTextViewer*)g_windowManager.GetWindow(WINDOW_DIALOG_TEXT_VIEWER); - pDialog->SetHeading(heading); - pDialog->SetText(text); - pDialog->DoModal(); -} -//@} - -/*! @name GUI select Dialog */ -//@{ -int CAddonCallbacksGUI::Dialog_Select(const char *heading, const char *entries[], unsigned int size, int selected) -{ - CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); - pDialog->Reset(); - pDialog->SetHeading(heading); - - for (unsigned int i = 0; i < size; i++) - pDialog->Add(entries[i]); - - if (selected > 0) - pDialog->SetSelected(selected); - - pDialog->DoModal(); - return pDialog->GetSelectedLabel(); -} -//@} - -CGUIAddonWindow::CGUIAddonWindow(int id, const std::string& strXML, CAddon* addon) - : CGUIMediaWindow(id, strXML.c_str()) - , m_iWindowId(id) - , m_iOldWindowId(0) - , m_bModal(false) - , m_bIsDialog(false) - , m_actionEvent(true) - , m_addon(addon) -{ - m_loadType = LOAD_ON_GUI_INIT; - CBOnInit = NULL; - CBOnFocus = NULL; - CBOnClick = NULL; - CBOnAction = NULL; -} - -CGUIAddonWindow::~CGUIAddonWindow(void) -{ -} - -bool CGUIAddonWindow::OnAction(const CAction &action) -{ - // Let addon decide whether it wants to hande action first - if (CBOnAction && CBOnAction(m_clientHandle, action.GetID())) - return true; - - return CGUIWindow::OnAction(action); -} - -bool CGUIAddonWindow::OnMessage(CGUIMessage& message) -{ - // TODO: We shouldn't be dropping down to CGUIWindow in any of this ideally. - // We have to make up our minds about what python should be doing and - // what this side of things should be doing - switch (message.GetMessage()) - { - case GUI_MSG_WINDOW_DEINIT: - { - return CGUIMediaWindow::OnMessage(message); - } - break; - - case GUI_MSG_WINDOW_INIT: - { - CGUIMediaWindow::OnMessage(message); - if (CBOnInit) - CBOnInit(m_clientHandle); - - return true; - } - break; - - case GUI_MSG_SETFOCUS: - { - if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != (int)message.GetControlId()) - { - m_viewControl.SetFocused(); - return true; - } - // check if our focused control is one of our category buttons - int iControl = message.GetControlId(); - if (CBOnFocus) - { - CBOnFocus(m_clientHandle, iControl); - } - } - break; - - case GUI_MSG_FOCUSED: - { - if (HasID(message.GetSenderId()) && CBOnFocus) - { - CBOnFocus(m_clientHandle, message.GetControlId()); - } - } - break; - - case GUI_MSG_CLICKED: - { - int iControl=message.GetSenderId(); - // Handle Sort/View internally. Scripters shouldn't use ID 2, 3 or 4. - if (iControl == CONTROL_BTNSORTASC) // sort asc - { - CLog::Log(LOGINFO, "WindowXML: Internal asc/dsc button not implemented"); - /*if (m_guiState.get()) - m_guiState->SetNextSortOrder(); - UpdateFileList();*/ - return true; - } - else if (iControl == CONTROL_BTNSORTBY) // sort by - { - CLog::Log(LOGINFO, "WindowXML: Internal sort button not implemented"); - /*if (m_guiState.get()) - m_guiState->SetNextSortMethod(); - UpdateFileList();*/ - return true; - } - - if (CBOnClick && iControl && iControl != (int)this->GetID()) - { - CGUIControl* controlClicked = (CGUIControl*)this->GetControl(iControl); - - // The old python way used to check list AND SELECITEM method or if its a button, checkmark. - // Its done this way for now to allow other controls without a python version like togglebutton to still raise a onAction event - if (controlClicked) // Will get problems if we the id is not on the window and we try to do GetControlType on it. So check to make sure it exists - { - if ((controlClicked->IsContainer() && (message.GetParam1() == ACTION_SELECT_ITEM || - message.GetParam1() == ACTION_MOUSE_LEFT_CLICK)) || - !controlClicked->IsContainer()) - { - if (CBOnClick(m_clientHandle, iControl)) - return true; - } - else if (controlClicked->IsContainer() && message.GetParam1() == ACTION_MOUSE_RIGHT_CLICK) - { -// PyXBMCAction* inf = new PyXBMCAction; -// inf->pObject = Action_FromAction(CAction(ACTION_CONTEXT_MENU)); -// inf->pCallbackWindow = pCallbackWindow; -// -// // aquire lock? -// PyXBMC_AddPendingCall(Py_XBMC_Event_OnAction, inf); -// PulseActionEvent(); - } - } - } - } - break; - } - - return CGUIMediaWindow::OnMessage(message); -} - -void CGUIAddonWindow::AllocResources(bool forceLoad /*= FALSE */) -{ - std::string tmpDir = URIUtils::GetDirectory(GetProperty("xmlfile").asString()); - std::string fallbackMediaPath; - URIUtils::GetParentPath(tmpDir, fallbackMediaPath); - URIUtils::RemoveSlashAtEnd(fallbackMediaPath); - m_mediaDir = fallbackMediaPath; - - //CLog::Log(LOGDEBUG, "CGUIPythonWindowXML::AllocResources called: %s", fallbackMediaPath.c_str()); - g_TextureManager.AddTexturePath(m_mediaDir); - CGUIMediaWindow::AllocResources(forceLoad); - g_TextureManager.RemoveTexturePath(m_mediaDir); -} - -void CGUIAddonWindow::FreeResources(bool forceUnLoad /*= FALSE */) -{ - CGUIMediaWindow::FreeResources(forceUnLoad); -} - -void CGUIAddonWindow::Render() -{ - g_TextureManager.AddTexturePath(m_mediaDir); - CGUIMediaWindow::Render(); - g_TextureManager.RemoveTexturePath(m_mediaDir); -} - -void CGUIAddonWindow::Update() -{ -} - -void CGUIAddonWindow::AddItem(CFileItemPtr fileItem, int itemPosition) -{ - if (itemPosition == -1 || itemPosition > m_vecItems->Size()) - { - m_vecItems->Add(fileItem); - } - else if (itemPosition < -1 && !(itemPosition-1 < m_vecItems->Size())) - { - m_vecItems->AddFront(fileItem,0); - } - else - { - m_vecItems->AddFront(fileItem,itemPosition); - } - m_viewControl.SetItems(*m_vecItems); - UpdateButtons(); -} - -void CGUIAddonWindow::RemoveItem(int itemPosition) -{ - m_vecItems->Remove(itemPosition); - m_viewControl.SetItems(*m_vecItems); - UpdateButtons(); -} - -int CGUIAddonWindow::GetCurrentListPosition() -{ - return m_viewControl.GetSelectedItem(); -} - -void CGUIAddonWindow::SetCurrentListPosition(int item) -{ - m_viewControl.SetSelectedItem(item); -} - -int CGUIAddonWindow::GetListSize() -{ - return m_vecItems->Size(); -} - -CFileItemPtr CGUIAddonWindow::GetListItem(int position) -{ - if (position < 0 || position >= m_vecItems->Size()) return CFileItemPtr(); - return m_vecItems->Get(position); -} - -void CGUIAddonWindow::ClearList() -{ - ClearFileItems(); - - m_viewControl.SetItems(*m_vecItems); - UpdateButtons(); -} - -void CGUIAddonWindow::GetContextButtons(int itemNumber, CContextButtons &buttons) -{ - // maybe on day we can make an easy way to do this context menu - // with out this method overriding the MediaWindow version, it will display 'Add to Favorites' -} - -void CGUIAddonWindow::WaitForActionEvent(unsigned int timeout) -{ - m_actionEvent.WaitMSec(timeout); - m_actionEvent.Reset(); -} - -void CGUIAddonWindow::PulseActionEvent() -{ - m_actionEvent.Set(); -} - -bool CGUIAddonWindow::OnClick(int iItem) -{ - // Hook Over calling CGUIMediaWindow::OnClick(iItem) results in it trying to PLAY the file item - // which if its not media is BAD and 99 out of 100 times undesireable. - return false; -} - -// SetupShares(); -/* - CGUIMediaWindow::OnWindowLoaded() calls SetupShares() so override it -and just call UpdateButtons(); -*/ -void CGUIAddonWindow::SetupShares() -{ - UpdateButtons(); -} - - -CGUIAddonWindowDialog::CGUIAddonWindowDialog(int id, const std::string& strXML, CAddon* addon) -: CGUIAddonWindow(id,strXML,addon) -{ - m_bRunning = false; - m_bIsDialog = true; -} - -CGUIAddonWindowDialog::~CGUIAddonWindowDialog(void) -{ -} - -bool CGUIAddonWindowDialog::OnMessage(CGUIMessage &message) -{ - if (message.GetMessage() == GUI_MSG_WINDOW_DEINIT) - { - CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow()); - if (pWindow) - g_windowManager.ShowOverlay(pWindow->GetOverlayState()); - return CGUIWindow::OnMessage(message); - } - return CGUIAddonWindow::OnMessage(message); -} - -void CGUIAddonWindowDialog::Show(bool show /* = true */) -{ - unsigned int iCount = g_graphicsContext.exit(); - ThreadMessage tMsg = {TMSG_GUI_ADDON_DIALOG, 1, show ? 1 : 0}; - tMsg.lpVoid = this; - CApplicationMessenger::Get().SendMessage(tMsg, true); - g_graphicsContext.restore(iCount); -} - -void CGUIAddonWindowDialog::Show_Internal(bool show /* = true */) -{ - if (show) - { - m_bModal = true; - m_bRunning = true; - g_windowManager.RouteToWindow(this); - - // active this window... - CGUIMessage msg(GUI_MSG_WINDOW_INIT, 0, 0, WINDOW_INVALID, m_iWindowId); - OnMessage(msg); - - // this dialog is derived from GUiMediaWindow - // make sure it is rendered last - m_renderOrder = 1; - while (m_bRunning && !g_application.m_bStop) - { - g_windowManager.ProcessRenderLoop(); - } - } - else // hide - { - m_bRunning = false; - - CGUIMessage msg(GUI_MSG_WINDOW_DEINIT,0,0); - OnMessage(msg); - - g_windowManager.RemoveDialog(GetID()); - } -} - -CGUIAddonRenderingControl::CGUIAddonRenderingControl(CGUIRenderingControl *pControl) -{ - m_pControl = pControl; - m_refCount = 1; -} - -bool CGUIAddonRenderingControl::Create(int x, int y, int w, int h, void *device) -{ - if (CBCreate) - { - if (CBCreate(m_clientHandle, x, y, w, h, device)) - { - m_refCount++; - return true; - } - } - return false; -} - -void CGUIAddonRenderingControl::Render() -{ - if (CBRender) - { - g_graphicsContext.BeginPaint(); - CBRender(m_clientHandle); - g_graphicsContext.EndPaint(); - } -} - -void CGUIAddonRenderingControl::Stop() -{ - if (CBStop) - { - CBStop(m_clientHandle); - } - m_refCount--; - if (m_refCount <= 0) - delete this; -} - -void CGUIAddonRenderingControl::Delete() -{ - m_refCount--; - if (m_refCount <= 0) - delete this; -} - -bool CGUIAddonRenderingControl::IsDirty() -{ - bool ret = true; - if (CBDirty) - { - ret = CBDirty(m_clientHandle); - } - return ret; -} - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksGUI.h b/xbmc/addons/AddonCallbacksGUI.h deleted file mode 100644 index ae032a7..0000000 --- a/xbmc/addons/AddonCallbacksGUI.h +++ /dev/null @@ -1,272 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - - -#include "AddonCallbacks.h" -#include "windows/GUIMediaWindow.h" -#include "threads/Event.h" -#include "guilib/IRenderingCallback.h" - -class CGUISpinControlEx; -class CGUIButtonControl; -class CGUIRadioButtonControl; -class CGUISliderControl; -class CGUISettingsSliderControl; -class CGUIEditControl; -class CGUIRenderingControl; - -namespace ADDON -{ - -class CAddonCallbacksGUI -{ -public: - CAddonCallbacksGUI(CAddon* addon); - ~CAddonCallbacksGUI(); - - /**! \name General Functions */ - CB_GUILib *GetCallbacks() { return m_callbacks; } - - static void Lock(); - static void Unlock(); - static int GetScreenHeight(); - static int GetScreenWidth(); - static int GetVideoResolution(); - - static GUIHANDLE Window_New(void *addonData, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog); - static void Window_Delete(void *addonData, GUIHANDLE handle); - static void Window_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*initCB)(GUIHANDLE), bool (*clickCB)(GUIHANDLE, int), bool (*focusCB)(GUIHANDLE, int), bool (*onActionCB)(GUIHANDLE handle, int)); - static bool Window_Show(void *addonData, GUIHANDLE handle); - static bool Window_Close(void *addonData, GUIHANDLE handle); - static bool Window_DoModal(void *addonData, GUIHANDLE handle); - static bool Window_SetFocusId(void *addonData, GUIHANDLE handle, int iControlId); - static int Window_GetFocusId(void *addonData, GUIHANDLE handle); - static bool Window_SetCoordinateResolution(void *addonData, GUIHANDLE handle, int res); - static void Window_SetProperty(void *addonData, GUIHANDLE handle, const char *key, const char *value); - static void Window_SetPropertyInt(void *addonData, GUIHANDLE handle, const char *key, int value); - static void Window_SetPropertyBool(void *addonData, GUIHANDLE handle, const char *key, bool value); - static void Window_SetPropertyDouble(void *addonData, GUIHANDLE handle, const char *key, double value); - static const char * Window_GetProperty(void *addonData, GUIHANDLE handle, const char *key); - static int Window_GetPropertyInt(void *addonData, GUIHANDLE handle, const char *key); - static bool Window_GetPropertyBool(void *addonData, GUIHANDLE handle, const char *key); - static double Window_GetPropertyDouble(void *addonData, GUIHANDLE handle, const char *key); - static void Window_ClearProperties(void *addonData, GUIHANDLE handle); - static int Window_GetListSize(void *addonData, GUIHANDLE handle); - static void Window_ClearList(void *addonData, GUIHANDLE handle); - static GUIHANDLE Window_AddItem(void *addonData, GUIHANDLE handle, GUIHANDLE item, int itemPosition); - static GUIHANDLE Window_AddStringItem(void *addonData, GUIHANDLE handle, const char *itemName, int itemPosition); - static void Window_RemoveItem(void *addonData, GUIHANDLE handle, int itemPosition); - static GUIHANDLE Window_GetListItem(void *addonData, GUIHANDLE handle, int listPos); - static void Window_SetCurrentListPosition(void *addonData, GUIHANDLE handle, int listPos); - static int Window_GetCurrentListPosition(void *addonData, GUIHANDLE handle); - static GUIHANDLE Window_GetControl_Spin(void *addonData, GUIHANDLE handle, int controlId); - static GUIHANDLE Window_GetControl_Button(void *addonData, GUIHANDLE handle, int controlId); - static GUIHANDLE Window_GetControl_RadioButton(void *addonData, GUIHANDLE handle, int controlId); - static GUIHANDLE Window_GetControl_Edit(void *addonData, GUIHANDLE handle, int controlId); - static GUIHANDLE Window_GetControl_Progress(void *addonData, GUIHANDLE handle, int controlId); - static GUIHANDLE Window_GetControl_RenderAddon(void *addonData, GUIHANDLE handle, int controlId); - static void Window_SetControlLabel(void *addonData, GUIHANDLE handle, int controlId, const char *label); - static void Window_MarkDirtyRegion(void *addonData, GUIHANDLE handle); - static void Control_Spin_SetVisible(void *addonData, GUIHANDLE spinhandle, bool yesNo); - static void Control_Spin_SetText(void *addonData, GUIHANDLE spinhandle, const char *label); - static void Control_Spin_Clear(void *addonData, GUIHANDLE spinhandle); - static void Control_Spin_AddLabel(void *addonData, GUIHANDLE spinhandle, const char *label, int iValue); - static int Control_Spin_GetValue(void *addonData, GUIHANDLE spinhandle); - static void Control_Spin_SetValue(void *addonData, GUIHANDLE spinhandle, int iValue); - static void Control_RadioButton_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo); - static void Control_RadioButton_SetText(void *addonData, GUIHANDLE handle, const char *label); - static void Control_RadioButton_SetSelected(void *addonData, GUIHANDLE handle, bool yesNo); - static bool Control_RadioButton_IsSelected(void *addonData, GUIHANDLE handle); - static void Control_Progress_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent); - static float Control_Progress_GetPercentage(void *addonData, GUIHANDLE handle); - static void Control_Progress_SetInfo(void *addonData, GUIHANDLE handle, int iInfo); - static int Control_Progress_GetInfo(void *addonData, GUIHANDLE handle); - static const char * Control_Progress_GetDescription(void *addonData, GUIHANDLE handle); - - static GUIHANDLE Window_GetControl_Slider(void *addonData, GUIHANDLE handle, int controlId); - static void Control_Slider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo); - static const char * Control_Slider_GetDescription(void *addonData, GUIHANDLE handle); - static void Control_Slider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd); - static void Control_Slider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue); - static int Control_Slider_GetIntValue(void *addonData, GUIHANDLE handle); - static void Control_Slider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval); - static void Control_Slider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent); - static float Control_Slider_GetPercentage(void *addonData, GUIHANDLE handle); - static void Control_Slider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd); - static void Control_Slider_SetFloatValue(void *addonData, GUIHANDLE handle, float fValue); - static float Control_Slider_GetFloatValue(void *addonData, GUIHANDLE handle); - static void Control_Slider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval); - - static GUIHANDLE Window_GetControl_SettingsSlider(void *addonData, GUIHANDLE handle, int controlId); - static void Control_SettingsSlider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo); - static void Control_SettingsSlider_SetText(void *addonData, GUIHANDLE handle, const char *label); - static const char * Control_SettingsSlider_GetDescription(void *addonData, GUIHANDLE handle); - static void Control_SettingsSlider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd); - static void Control_SettingsSlider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue); - static int Control_SettingsSlider_GetIntValue(void *addonData, GUIHANDLE handle); - static void Control_SettingsSlider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval); - static void Control_SettingsSlider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent); - static float Control_SettingsSlider_GetPercentage(void *addonData, GUIHANDLE handle); - static void Control_SettingsSlider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd); - static void Control_SettingsSlider_SetFloatValue(void *addonData, GUIHANDLE handle, float fValue); - static float Control_SettingsSlider_GetFloatValue(void *addonData, GUIHANDLE handle); - static void Control_SettingsSlider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval); - - static GUIHANDLE ListItem_Create(void *addonData, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path); - static const char * ListItem_GetLabel(void *addonData, GUIHANDLE handle); - static void ListItem_SetLabel(void *addonData, GUIHANDLE handle, const char *label); - static const char * ListItem_GetLabel2(void *addonData, GUIHANDLE handle); - static void ListItem_SetLabel2(void *addonData, GUIHANDLE handle, const char *label); - static void ListItem_SetIconImage(void *addonData, GUIHANDLE handle, const char *image); - static void ListItem_SetThumbnailImage(void *addonData, GUIHANDLE handle, const char *image); - static void ListItem_SetInfo(void *addonData, GUIHANDLE handle, const char *info); - static void ListItem_SetProperty(void *addonData, GUIHANDLE handle, const char *key, const char *value); - static const char * ListItem_GetProperty(void *addonData, GUIHANDLE handle, const char *key); - static void ListItem_SetPath(void *addonData, GUIHANDLE handle, const char *path); - static void RenderAddon_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*createCB)(GUIHANDLE,int,int,int,int,void*), void (*renderCB)(GUIHANDLE), void (*stopCB)(GUIHANDLE), bool (*dirtyCB)(GUIHANDLE)); - static void RenderAddon_Delete(void *addonData, GUIHANDLE handle); - static void RenderAddon_MarkDirty(void *addonData, GUIHANDLE handle); - - static bool Dialog_Keyboard_ShowAndGetInput(char &aTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs); - static bool Dialog_Keyboard_ShowAndGetInputWithHead(char &aTextString, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs); - static bool Dialog_Keyboard_ShowAndGetNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); - static bool Dialog_Keyboard_ShowAndGetNewPasswordWithHead(char &newPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs); - static bool Dialog_Keyboard_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); - static bool Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmpty, unsigned int autoCloseMs); - static int Dialog_Keyboard_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs); - static bool Dialog_Keyboard_ShowAndGetFilter(char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs); - static bool Dialog_Keyboard_SendTextToActiveKeyboard(const char *aTextString, bool closeKeyboard); - static bool Dialog_Keyboard_isKeyboardActivated(); - - static bool Dialog_Numeric_ShowAndVerifyNewPassword(char &strNewPasswor, unsigned int iMaxStringSized); - static int Dialog_Numeric_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries); - static bool Dialog_Numeric_ShowAndVerifyInput(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput); - static bool Dialog_Numeric_ShowAndGetTime(tm &time, const char *strHeading); - static bool Dialog_Numeric_ShowAndGetDate(tm &date, const char *strHeading); - static bool Dialog_Numeric_ShowAndGetIPAddress(char &strIPAddress, unsigned int iMaxStringSize, const char *strHeading); - static bool Dialog_Numeric_ShowAndGetNumber(char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs); - static bool Dialog_Numeric_ShowAndGetSeconds(char &timeString, unsigned int iMaxStringSize, const char *strHeading); - - static bool Dialog_FileBrowser_ShowAndGetFile(const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList); - - static void Dialog_OK_ShowAndGetInputSingleText(const char *heading, const char *text); - static void Dialog_OK_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2); - - static bool Dialog_YesNo_ShowAndGetInputSingleText(const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel); - static bool Dialog_YesNo_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel); - static bool Dialog_YesNo_ShowAndGetInputLineButtonText(const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel); - - static void Dialog_TextViewer(const char *heading, const char *text); - static int Dialog_Select(const char *heading, const char *entries[], unsigned int size, int selected); - -private: - CB_GUILib *m_callbacks; - CAddon *m_addon; -}; - -class CGUIAddonWindow : public CGUIMediaWindow -{ -friend class CAddonCallbacksGUI; - -public: - CGUIAddonWindow(int id, const std::string& strXML, CAddon* addon); - virtual ~CGUIAddonWindow(void); - - virtual bool OnMessage(CGUIMessage& message); - virtual bool OnAction(const CAction &action); - virtual void AllocResources(bool forceLoad = false); - virtual void FreeResources(bool forceUnLoad = false); - virtual void Render(); - void WaitForActionEvent(unsigned int timeout); - void PulseActionEvent(); - void AddItem(CFileItemPtr fileItem, int itemPosition); - void RemoveItem(int itemPosition); - void ClearList(); - CFileItemPtr GetListItem(int position); - int GetListSize(); - int GetCurrentListPosition(); - void SetCurrentListPosition(int item); - virtual bool OnClick(int iItem); - -protected: - virtual void Update(); - virtual void GetContextButtons(int itemNumber, CContextButtons &buttons); - void SetupShares(); - - bool (*CBOnInit)(GUIHANDLE cbhdl); - bool (*CBOnFocus)(GUIHANDLE cbhdl, int controlId); - bool (*CBOnClick)(GUIHANDLE cbhdl, int controlId); - bool (*CBOnAction)(GUIHANDLE cbhdl, int); - - GUIHANDLE m_clientHandle; - const int m_iWindowId; - int m_iOldWindowId; - bool m_bModal; - bool m_bIsDialog; - -private: - CEvent m_actionEvent; - CAddon *m_addon; - std::string m_mediaDir; -}; - -class CGUIAddonWindowDialog : public CGUIAddonWindow -{ -public: - CGUIAddonWindowDialog(int id, const std::string& strXML, CAddon* addon); - virtual ~CGUIAddonWindowDialog(void); - - void Show(bool show = true); - virtual bool OnMessage(CGUIMessage &message); - virtual bool IsDialogRunning() const { return m_bRunning; } - virtual bool IsDialog() const { return true;}; - virtual bool IsModalDialog() const { return true; }; - virtual bool IsMediaWindow() const { return false; }; - - void Show_Internal(bool show = true); - -private: - bool m_bRunning; -}; - -class CGUIAddonRenderingControl : public IRenderingCallback -{ -friend class CAddonCallbacksGUI; -public: - CGUIAddonRenderingControl(CGUIRenderingControl *pControl); - virtual ~CGUIAddonRenderingControl() {} - virtual bool Create(int x, int y, int w, int h, void *device); - virtual void Render(); - virtual void Stop(); - virtual bool IsDirty(); - virtual void Delete(); -protected: - bool (*CBCreate) (GUIHANDLE cbhdl, int x, int y, int w, int h, void *device); - void (*CBRender)(GUIHANDLE cbhdl); - void (*CBStop)(GUIHANDLE cbhdl); - bool (*CBDirty)(GUIHANDLE cbhdl); - - GUIHANDLE m_clientHandle; - CGUIRenderingControl *m_pControl; - int m_refCount; -}; - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksPVR.cpp b/xbmc/addons/AddonCallbacksPVR.cpp deleted file mode 100644 index 1d769e1..0000000 --- a/xbmc/addons/AddonCallbacksPVR.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "Application.h" -#include "AddonCallbacksPVR.h" -#include "settings/AdvancedSettings.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "dialogs/GUIDialogKaiToast.h" - -#include "epg/EpgContainer.h" -#include "pvr/PVRManager.h" -#include "pvr/channels/PVRChannelGroupsContainer.h" -#include "pvr/channels/PVRChannelGroupInternal.h" -#include "pvr/addons/PVRClient.h" -#include "pvr/recordings/PVRRecordings.h" -#include "pvr/timers/PVRTimers.h" -#include "pvr/timers/PVRTimerInfoTag.h" - -using namespace PVR; -using namespace EPG; - -namespace ADDON -{ - -CAddonCallbacksPVR::CAddonCallbacksPVR(CAddon* addon) -{ - m_addon = addon; - m_callbacks = new CB_PVRLib; - - /* write XBMC PVR specific add-on function addresses to callback table */ - m_callbacks->TransferEpgEntry = PVRTransferEpgEntry; - m_callbacks->TransferChannelEntry = PVRTransferChannelEntry; - m_callbacks->TransferTimerEntry = PVRTransferTimerEntry; - m_callbacks->TransferRecordingEntry = PVRTransferRecordingEntry; - m_callbacks->AddMenuHook = PVRAddMenuHook; - m_callbacks->Recording = PVRRecording; - m_callbacks->TriggerChannelUpdate = PVRTriggerChannelUpdate; - m_callbacks->TriggerChannelGroupsUpdate = PVRTriggerChannelGroupsUpdate; - m_callbacks->TriggerTimerUpdate = PVRTriggerTimerUpdate; - m_callbacks->TriggerRecordingUpdate = PVRTriggerRecordingUpdate; - m_callbacks->TriggerEpgUpdate = PVRTriggerEpgUpdate; - m_callbacks->FreeDemuxPacket = PVRFreeDemuxPacket; - m_callbacks->AllocateDemuxPacket = PVRAllocateDemuxPacket; - m_callbacks->TransferChannelGroup = PVRTransferChannelGroup; - m_callbacks->TransferChannelGroupMember = PVRTransferChannelGroupMember; -} - -CAddonCallbacksPVR::~CAddonCallbacksPVR() -{ - /* delete the callback table */ - delete m_callbacks; -} - -CPVRClient *CAddonCallbacksPVR::GetPVRClient(void *addonData) -{ - CAddonCallbacks *addon = static_cast(addonData); - if (!addon || !addon->GetHelperPVR()) - { - CLog::Log(LOGERROR, "PVR - %s - called with a null pointer", __FUNCTION__); - return NULL; - } - - return dynamic_cast(addon->GetHelperPVR()->m_addon); -} - -void CAddonCallbacksPVR::PVRTransferChannelGroup(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP *group) -{ - if (!handle) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CPVRChannelGroups *xbmcGroups = static_cast(handle->dataAddress); - if (!group || !xbmcGroups) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - if (strlen(group->strGroupName) == 0) - { - CLog::Log(LOGERROR, "PVR - %s - empty group name", __FUNCTION__); - return; - } - - /* transfer this entry to the groups container */ - CPVRChannelGroup transferGroup(*group); - xbmcGroups->UpdateFromClient(transferGroup); -} - -void CAddonCallbacksPVR::PVRTransferChannelGroupMember(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP_MEMBER *member) -{ - if (!handle) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CPVRClient *client = GetPVRClient(addonData); - CPVRChannelGroup *group = static_cast(handle->dataAddress); - if (!member || !client || !group) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(member->iChannelUniqueId, client->GetID()); - if (!channel) - { - CLog::Log(LOGERROR, "PVR - %s - cannot find group '%s' or channel '%d'", __FUNCTION__, member->strGroupName, member->iChannelUniqueId); - } - else if (group->IsRadio() == channel->IsRadio()) - { - /* transfer this entry to the group */ - group->AddToGroup(channel, member->iChannelNumber); - } -} - -void CAddonCallbacksPVR::PVRTransferEpgEntry(void *addonData, const ADDON_HANDLE handle, const EPG_TAG *epgentry) -{ - if (!handle) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CEpg *xbmcEpg = static_cast(handle->dataAddress); - if (!xbmcEpg) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - /* transfer this entry to the epg */ - xbmcEpg->UpdateEntry(epgentry, handle->dataIdentifier == 1 /* update db */); -} - -void CAddonCallbacksPVR::PVRTransferChannelEntry(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL *channel) -{ - if (!handle) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CPVRClient *client = GetPVRClient(addonData); - CPVRChannelGroupInternal *xbmcChannels = static_cast(handle->dataAddress); - if (!channel || !client || !xbmcChannels) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - /* transfer this entry to the internal channels group */ - CPVRChannelPtr transferChannel(new CPVRChannel(*channel, client->GetID())); - xbmcChannels->UpdateFromClient(transferChannel); -} - -void CAddonCallbacksPVR::PVRTransferRecordingEntry(void *addonData, const ADDON_HANDLE handle, const PVR_RECORDING *recording) -{ - if (!handle) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CPVRClient *client = GetPVRClient(addonData); - CPVRRecordings *xbmcRecordings = static_cast(handle->dataAddress); - if (!recording || !client || !xbmcRecordings) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - /* transfer this entry to the recordings container */ - CPVRRecordingPtr transferRecording(new CPVRRecording(*recording, client->GetID())); - xbmcRecordings->UpdateFromClient(transferRecording); -} - -void CAddonCallbacksPVR::PVRTransferTimerEntry(void *addonData, const ADDON_HANDLE handle, const PVR_TIMER *timer) -{ - if (!handle) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CPVRClient *client = GetPVRClient(addonData); - CPVRTimers *xbmcTimers = static_cast(handle->dataAddress); - if (!timer || !client || !xbmcTimers) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(timer->iClientChannelUid, client->GetID()); - if (!channel) - { - CLog::Log(LOGERROR, "PVR - %s - cannot find channel %d on client %d", __FUNCTION__, timer->iClientChannelUid, client->GetID()); - return; - } - - /* transfer this entry to the timers container */ - CPVRTimerInfoTag transferTimer(*timer, channel, client->GetID()); - xbmcTimers->UpdateFromClient(transferTimer); -} - -void CAddonCallbacksPVR::PVRAddMenuHook(void *addonData, PVR_MENUHOOK *hook) -{ - CPVRClient *client = GetPVRClient(addonData); - if (!hook || !client) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - PVR_MENUHOOKS *hooks = client->GetMenuHooks(); - if (hooks) - { - PVR_MENUHOOK hookInt; - hookInt.iHookId = hook->iHookId; - hookInt.iLocalizedStringId = hook->iLocalizedStringId; - hookInt.category = hook->category; - - /* add this new hook */ - hooks->push_back(hookInt); - } -} - -void CAddonCallbacksPVR::PVRRecording(void *addonData, const char *strName, const char *strFileName, bool bOnOff) -{ - CPVRClient *client = GetPVRClient(addonData); - if (!client || !strFileName) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - std::string strLine1; - if (bOnOff) - strLine1 = StringUtils::Format(g_localizeStrings.Get(19197).c_str(), client->Name().c_str()); - else - strLine1 = StringUtils::Format(g_localizeStrings.Get(19198).c_str(), client->Name().c_str()); - - std::string strLine2; - if (strName) - strLine2 = strName; - else if (strFileName) - strLine2 = strFileName; - - /* display a notification for 5 seconds */ - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, strLine1, strLine2, 5000, false); - - CLog::Log(LOGDEBUG, "PVR - %s - recording %s on client '%s'. name='%s' filename='%s'", - __FUNCTION__, bOnOff ? "started" : "finished", client->Name().c_str(), strName, strFileName); -} - -void CAddonCallbacksPVR::PVRTriggerChannelUpdate(void *addonData) -{ - /* update the channels table in the next iteration of the pvrmanager's main loop */ - g_PVRManager.TriggerChannelsUpdate(); -} - -void CAddonCallbacksPVR::PVRTriggerTimerUpdate(void *addonData) -{ - /* update the timers table in the next iteration of the pvrmanager's main loop */ - g_PVRManager.TriggerTimersUpdate(); -} - -void CAddonCallbacksPVR::PVRTriggerRecordingUpdate(void *addonData) -{ - /* update the recordings table in the next iteration of the pvrmanager's main loop */ - g_PVRManager.TriggerRecordingsUpdate(); -} - -void CAddonCallbacksPVR::PVRTriggerChannelGroupsUpdate(void *addonData) -{ - /* update all channel groups in the next iteration of the pvrmanager's main loop */ - g_PVRManager.TriggerChannelGroupsUpdate(); -} - -void CAddonCallbacksPVR::PVRTriggerEpgUpdate(void *addonData, unsigned int iChannelUid) -{ - // get the client - CPVRClient *client = GetPVRClient(addonData); - if (!client) - { - CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__); - return; - } - - g_EpgContainer.UpdateRequest(client->GetID(), iChannelUid); -} - -void CAddonCallbacksPVR::PVRFreeDemuxPacket(void *addonData, DemuxPacket* pPacket) -{ - CDVDDemuxUtils::FreeDemuxPacket(pPacket); -} - -DemuxPacket* CAddonCallbacksPVR::PVRAllocateDemuxPacket(void *addonData, int iDataSize) -{ - return CDVDDemuxUtils::AllocateDemuxPacket(iDataSize); -} - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksPVR.h b/xbmc/addons/AddonCallbacksPVR.h deleted file mode 100644 index 3fa48ec..0000000 --- a/xbmc/addons/AddonCallbacksPVR.h +++ /dev/null @@ -1,166 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "AddonCallbacks.h" -#include "include/xbmc_pvr_types.h" - -namespace PVR -{ - class CPVRClient; -} - -namespace ADDON -{ - -/*! - * Callbacks for a PVR add-on to XBMC. - * - * Also translates the addon's C structures to XBMC's C++ structures. - */ -class CAddonCallbacksPVR -{ -public: - CAddonCallbacksPVR(CAddon* addon); - ~CAddonCallbacksPVR(void); - - /*! - * @return The callback table. - */ - CB_PVRLib *GetCallbacks() { return m_callbacks; } - - /*! - * @brief Transfer a channel group from the add-on to XBMC. The group will be created if it doesn't exist. - * @param addonData A pointer to the add-on. - * @param handle The handle parameter that XBMC used when requesting the channel groups list - * @param entry The entry to transfer to XBMC - */ - static void PVRTransferChannelGroup(void* addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP* entry); - - /*! - * @brief Transfer a channel group member entry from the add-on to XBMC. The channel will be added to the group if the group can be found. - * @param addonData A pointer to the add-on. - * @param handle The handle parameter that XBMC used when requesting the channel group members list - * @param entry The entry to transfer to XBMC - */ - static void PVRTransferChannelGroupMember(void* addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP_MEMBER* entry); - - /*! - * @brief Transfer an EPG tag from the add-on to XBMC - * @param addonData A pointer to the add-on. - * @param handle The handle parameter that XBMC used when requesting the EPG data - * @param entry The entry to transfer to XBMC - */ - static void PVRTransferEpgEntry(void* addonData, const ADDON_HANDLE handle, const EPG_TAG* entry); - - /*! - * @brief Transfer a channel entry from the add-on to XBMC - * @param addonData A pointer to the add-on. - * @param handle The handle parameter that XBMC used when requesting the channel list - * @param entry The entry to transfer to XBMC - */ - static void PVRTransferChannelEntry(void* addonData, const ADDON_HANDLE handle, const PVR_CHANNEL* entry); - - /*! - * @brief Transfer a timer entry from the add-on to XBMC - * @param addonData A pointer to the add-on. - * @param handle The handle parameter that XBMC used when requesting the timers list - * @param entry The entry to transfer to XBMC - */ - static void PVRTransferTimerEntry(void* addonData, const ADDON_HANDLE handle, const PVR_TIMER* entry); - - /*! - * @brief Transfer a recording entry from the add-on to XBMC - * @param addonData A pointer to the add-on. - * @param handle The handle parameter that XBMC used when requesting the recordings list - * @param entry The entry to transfer to XBMC - */ - static void PVRTransferRecordingEntry(void* addonData, const ADDON_HANDLE handle, const PVR_RECORDING* entry); - - /*! - * @brief Add or replace a menu hook for the context menu for this add-on - * @param addonData A pointer to the add-on. - * @param hook The hook to add. - */ - static void PVRAddMenuHook(void* addonData, PVR_MENUHOOK* hook); - - /*! - * @brief Display a notification in XBMC that a recording started or stopped on the server - * @param addonData A pointer to the add-on. - * @param strName The name of the recording to display - * @param strFileName The filename of the recording - * @param bOnOff True when recording started, false when it stopped - */ - static void PVRRecording(void* addonData, const char* strName, const char* strFileName, bool bOnOff); - - /*! - * @brief Request XBMC to update it's list of channels - * @param addonData A pointer to the add-on. - */ - static void PVRTriggerChannelUpdate(void* addonData); - - /*! - * @brief Request XBMC to update it's list of timers - * @param addonData A pointer to the add-on. - */ - static void PVRTriggerTimerUpdate(void* addonData); - - /*! - * @brief Request XBMC to update it's list of recordings - * @param addonData A pointer to the add-on. - */ - static void PVRTriggerRecordingUpdate(void* addonData); - - /*! - * @brief Request XBMC to update it's list of channel groups - * @param addonData A pointer to the add-on. - */ - static void PVRTriggerChannelGroupsUpdate(void* addonData); - - /*! - * @brief Schedule an EPG update for the given channel channel - * @param addonData A pointer to the add-on - * @param iChannelUid The unique id of the channel for this add-on - */ - static void PVRTriggerEpgUpdate(void* addonData, unsigned int iChannelUid); - - /*! - * @brief Free a packet that was allocated with AllocateDemuxPacket - * @param addonData A pointer to the add-on. - * @param pPacket The packet to free. - */ - static void PVRFreeDemuxPacket(void* addonData, DemuxPacket* pPacket); - - /*! - * @brief Allocate a demux packet. Free with FreeDemuxPacket - * @param addonData A pointer to the add-on. - * @param iDataSize The size of the data that will go into the packet - * @return The allocated packet. - */ - static DemuxPacket* PVRAllocateDemuxPacket(void* addonData, int iDataSize = 0); - -private: - static PVR::CPVRClient* GetPVRClient(void* addonData); - - CB_PVRLib *m_callbacks; /*!< callback addresses */ - CAddon *m_addon; /*!< the addon */ -}; - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp deleted file mode 100644 index 69b47ea..0000000 --- a/xbmc/addons/AddonDatabase.cpp +++ /dev/null @@ -1,797 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "AddonDatabase.h" -#include "addons/AddonManager.h" -#include "utils/log.h" -#include "utils/Variant.h" -#include "utils/StringUtils.h" -#include "XBDateTime.h" -#include "dbwrappers/dataset.h" -#include "addons/ContextItemAddon.h" - -using namespace ADDON; -using namespace std; - -CAddonDatabase::CAddonDatabase() -{ -} - -CAddonDatabase::~CAddonDatabase() -{ -} - -bool CAddonDatabase::Open() -{ - return CDatabase::Open(); -} - -void CAddonDatabase::CreateTables() -{ - CLog::Log(LOGINFO, "create addon table"); - m_pDS->exec("CREATE TABLE addon (id integer primary key, type text," - "name text, summary text, description text, stars integer," - "path text, addonID text, icon text, version text, " - "changelog text, fanart text, author text, disclaimer text," - "minversion text)\n"); - - CLog::Log(LOGINFO, "create addonextra table"); - m_pDS->exec("CREATE TABLE addonextra (id integer, key text, value text)\n"); - - CLog::Log(LOGINFO, "create dependencies table"); - m_pDS->exec("CREATE TABLE dependencies (id integer, addon text, version text, optional boolean)\n"); - - CLog::Log(LOGINFO, "create repo table"); - m_pDS->exec("CREATE TABLE repo (id integer primary key, addonID text," - "checksum text, lastcheck text, version text)\n"); - - CLog::Log(LOGINFO, "create addonlinkrepo table"); - m_pDS->exec("CREATE TABLE addonlinkrepo (idRepo integer, idAddon integer)\n"); - - CLog::Log(LOGINFO, "create disabled table"); - m_pDS->exec("CREATE TABLE disabled (id integer primary key, addonID text)\n"); - - CLog::Log(LOGINFO, "create broken table"); - m_pDS->exec("CREATE TABLE broken (id integer primary key, addonID text, reason text)\n"); - - CLog::Log(LOGINFO, "create blacklist table"); - m_pDS->exec("CREATE TABLE blacklist (id integer primary key, addonID text, version text)\n"); - - CLog::Log(LOGINFO, "create package table"); - m_pDS->exec("CREATE TABLE package (id integer primary key, addonID text, filename text, hash text)\n"); -} - -void CAddonDatabase::CreateAnalytics() -{ - CLog::Log(LOGINFO, "%s creating indicies", __FUNCTION__); - m_pDS->exec("CREATE INDEX idxAddon ON addon(addonID)"); - m_pDS->exec("CREATE INDEX idxAddonExtra ON addonextra(id)"); - m_pDS->exec("CREATE INDEX idxDependencies ON dependencies(id)"); - m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_1 ON addonlinkrepo ( idAddon, idRepo )\n"); - m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_2 ON addonlinkrepo ( idRepo, idAddon )\n"); - m_pDS->exec("CREATE UNIQUE INDEX idxDisabled ON disabled(addonID)"); - m_pDS->exec("CREATE UNIQUE INDEX idxBroken ON broken(addonID)"); - m_pDS->exec("CREATE UNIQUE INDEX idxBlack ON blacklist(addonID)"); - m_pDS->exec("CREATE UNIQUE INDEX idxPackage ON package(filename)"); -} - -void CAddonDatabase::UpdateTables(int version) -{ - if (version < 16) - { - m_pDS->exec("CREATE TABLE package (id integer primary key, addonID text, filename text, hash text)\n"); - } - if (version < 17) - { - m_pDS->exec("DELETE FROM repo"); - m_pDS->exec("ALTER TABLE repo ADD version text"); - } -} - -int CAddonDatabase::AddAddon(const AddonPtr& addon, - int idRepo) -{ - try - { - if (NULL == m_pDB.get()) return -1; - if (NULL == m_pDS.get()) return -1; - - std::string sql = PrepareSQL("insert into addon (id, type, name, summary," - "description, stars, path, icon, changelog, " - "fanart, addonID, version, author, disclaimer, minversion)" - " values(NULL, '%s', '%s', '%s', '%s', %i," - "'%s', '%s', '%s', '%s', '%s','%s','%s','%s','%s')", - TranslateType(addon->Type(),false).c_str(), - addon->Name().c_str(), addon->Summary().c_str(), - addon->Description().c_str(),addon->Stars(), - addon->Path().c_str(), addon->Props().icon.c_str(), - addon->ChangeLog().c_str(),addon->FanArt().c_str(), - addon->ID().c_str(), addon->Version().asString().c_str(), - addon->Author().c_str(),addon->Disclaimer().c_str(), - addon->MinVersion().asString().c_str()); - m_pDS->exec(sql.c_str()); - int idAddon = (int)m_pDS->lastinsertid(); - - sql = PrepareSQL("insert into addonlinkrepo (idRepo, idAddon) values (%i,%i)",idRepo,idAddon); - m_pDS->exec(sql.c_str()); - - const InfoMap &info = addon->ExtraInfo(); - for (InfoMap::const_iterator i = info.begin(); i != info.end(); ++i) - { - sql = PrepareSQL("insert into addonextra(id, key, value) values (%i, '%s', '%s')", idAddon, i->first.c_str(), i->second.c_str()); - m_pDS->exec(sql.c_str()); - } - const ADDONDEPS &deps = addon->GetDeps(); - for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i) - { - sql = PrepareSQL("insert into dependencies(id, addon, version, optional) values (%i, '%s', '%s', %i)", idAddon, i->first.c_str(), i->second.first.asString().c_str(), i->second.second ? 1 : 0); - m_pDS->exec(sql.c_str()); - } - return idAddon; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon '%s'", __FUNCTION__, addon->Name().c_str()); - } - return -1; -} - -AddonVersion CAddonDatabase::GetAddonVersion(const std::string &id) -{ - AddonVersion maxversion("0.0.0"); - try - { - if (NULL == m_pDB.get()) return maxversion; - if (NULL == m_pDS2.get()) return maxversion; - - // there may be multiple addons with this id (eg from different repositories) in the database, - // so we want to retrieve the latest version. Order by version won't work as the database - // won't know that 1.10 > 1.2, so grab them all and order outside - std::string sql = PrepareSQL("select version from addon where addonID='%s'",id.c_str()); - m_pDS2->query(sql.c_str()); - - if (m_pDS2->eof()) - return maxversion; - - while (!m_pDS2->eof()) - { - AddonVersion version(m_pDS2->fv(0).get_asString()); - if (version > maxversion) - maxversion = version; - m_pDS2->next(); - } - return maxversion; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon %s", __FUNCTION__, id.c_str()); - } - return maxversion; -} - -bool CAddonDatabase::GetAddon(const std::string& id, AddonPtr& addon) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS2.get()) return false; - - // there may be multiple addons with this id (eg from different repositories) in the database, - // so we want to retrieve the latest version. Order by version won't work as the database - // won't know that 1.10 > 1.2, so grab them all and order outside - std::string sql = PrepareSQL("select id,version from addon where addonID='%s'",id.c_str()); - m_pDS2->query(sql.c_str()); - - if (m_pDS2->eof()) - return false; - - AddonVersion maxversion("0.0.0"); - int maxid = 0; - while (!m_pDS2->eof()) - { - AddonVersion version(m_pDS2->fv(1).get_asString()); - if (version > maxversion) - { - maxid = m_pDS2->fv(0).get_asInt(); - maxversion = version; - } - m_pDS2->next(); - } - return GetAddon(maxid,addon); - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon %s", __FUNCTION__, id.c_str()); - } - addon.reset(); - return false; -} - -bool CAddonDatabase::GetRepoForAddon(const std::string& addonID, std::string& repo) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS2.get()) return false; - - std::string sql = PrepareSQL("select repo.addonID from repo join addonlinkrepo on repo.id=addonlinkrepo.idRepo join addon on addonlinkrepo.idAddon=addon.id where addon.addonID like '%s'", addonID.c_str()); - m_pDS2->query(sql.c_str()); - if (!m_pDS2->eof()) - { - repo = m_pDS2->fv(0).get_asString(); - m_pDS2->close(); - return true; - } - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed for addon %s", __FUNCTION__, addonID.c_str()); - } - return false; -} - -bool CAddonDatabase::GetAddon(int id, AddonPtr &addon) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS2.get()) return false; - - std::string sql = "SELECT addon.*," - " broken.reason," - " addonextra.key, addonextra.value," - " dependencies.addon, dependencies.version, dependencies.optional" - " FROM addon" - " LEFT JOIN broken" - " ON broken.addonID = addon.addonID" - " LEFT JOIN addonextra" - " ON addonextra.id = addon.id" - " LEFT JOIN dependencies" - " ON dependencies.id = addon.id"; - - sql += PrepareSQL(" WHERE addon.id=%i", id); - - m_pDS2->query(sql.c_str()); - if (!m_pDS2->eof()) - { - const dbiplus::query_data &data = m_pDS2->get_result_set().records; - const dbiplus::sql_record* const record = data[0]; - AddonProps props(record->at(addon_addonID).get_asString(), - TranslateType(record->at(addon_type).get_asString()), - record->at(addon_version).get_asString(), - record->at(addon_minversion).get_asString()); - props.name = record->at(addon_name).get_asString(); - props.summary = record->at(addon_summary).get_asString(); - props.description = record->at(addon_description).get_asString(); - props.changelog = record->at(addon_changelog).get_asString(); - props.path = record->at(addon_path).get_asString(); - props.icon = record->at(addon_icon).get_asString(); - props.fanart = record->at(addon_fanart).get_asString(); - props.author = record->at(addon_author).get_asString(); - props.disclaimer = record->at(addon_disclaimer).get_asString(); - props.broken = record->at(broken_reason).get_asString(); - - /* while this is a cartesion join and we'll typically get multiple rows, we rely on the fact that - extrainfo and dependencies are maps, so insert() will insert the first instance only */ - for (dbiplus::query_data::const_iterator i = data.begin(); i != data.end(); ++i) - { - const dbiplus::sql_record* const record = *i; - if (!record->at(addonextra_key).get_asString().empty()) - props.extrainfo.insert(make_pair(record->at(addonextra_key).get_asString(), record->at(addonextra_value).get_asString())); - if (!m_pDS2->fv(dependencies_addon).get_asString().empty()) - props.dependencies.insert(make_pair(record->at(dependencies_addon).get_asString(), make_pair(AddonVersion(record->at(dependencies_version).get_asString()), record->at(dependencies_optional).get_asBool()))); - } - - addon = CAddonMgr::AddonFromProps(props); - return NULL != addon.get(); - } - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon %i", __FUNCTION__, id); - } - addon.reset(); - return false; -} - -bool CAddonDatabase::GetAddons(VECADDONS& addons) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS2.get()) return false; - - std::string sql = PrepareSQL("select distinct addonID from addon"); - m_pDS->query(sql.c_str()); - while (!m_pDS->eof()) - { - AddonPtr addon; - if (GetAddon(m_pDS->fv(0).get_asString(),addon)) - addons.push_back(addon); - m_pDS->next(); - } - m_pDS->close(); - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed", __FUNCTION__); - } - return false; -} - -void CAddonDatabase::DeleteRepository(const std::string& id) -{ - try - { - if (NULL == m_pDB.get()) return; - if (NULL == m_pDS.get()) return; - - std::string sql = PrepareSQL("select id from repo where addonID='%s'",id.c_str()); - m_pDS->query(sql.c_str()); - if (!m_pDS->eof()) - DeleteRepository(m_pDS->fv(0).get_asInt()); - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on repo '%s'", __FUNCTION__, id.c_str()); - } -} - -void CAddonDatabase::DeleteRepository(int idRepo) -{ - try - { - if (NULL == m_pDB.get()) return; - if (NULL == m_pDS.get()) return; - - std::string sql = PrepareSQL("delete from repo where id=%i",idRepo); - m_pDS->exec(sql.c_str()); - sql = PrepareSQL("delete from addon where id in (select idAddon from addonlinkrepo where idRepo=%i)",idRepo); - m_pDS->exec(sql.c_str()); - sql = PrepareSQL("delete from addonextra where id in (select idAddon from addonlinkrepo where idRepo=%i)",idRepo); - m_pDS->exec(sql.c_str()); - sql = PrepareSQL("delete from dependencies where id in (select idAddon from addonlinkrepo where idRepo=%i)",idRepo); - m_pDS->exec(sql.c_str()); - sql = PrepareSQL("delete from addonlinkrepo where idRepo=%i",idRepo); - m_pDS->exec(sql.c_str()); - - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on repo %i", __FUNCTION__, idRepo); - } -} - -int CAddonDatabase::AddRepository(const std::string& id, const VECADDONS& addons, const std::string& checksum, const AddonVersion& version) -{ - try - { - if (NULL == m_pDB.get()) return -1; - if (NULL == m_pDS.get()) return -1; - - std::string sql; - int idRepo = GetRepoChecksum(id,sql); - if (idRepo > -1) - DeleteRepository(idRepo); - - BeginTransaction(); - - CDateTime time = CDateTime::GetCurrentDateTime(); - sql = PrepareSQL("insert into repo (id,addonID,checksum,lastcheck,version) values (NULL,'%s','%s','%s','%s')", - id.c_str(), checksum.c_str(), time.GetAsDBDateTime().c_str(), version.asString().c_str()); - m_pDS->exec(sql.c_str()); - idRepo = (int)m_pDS->lastinsertid(); - for (unsigned int i=0;iquery(strSQL.c_str()); - if (!m_pDS->eof()) - { - checksum = m_pDS->fv("checksum").get_asString(); - return m_pDS->fv("id").get_asInt(); - } - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on repo '%s'", __FUNCTION__, id.c_str()); - } - checksum.clear(); - return -1; -} - -CDateTime CAddonDatabase::GetRepoTimestamp(const std::string& id) -{ - CDateTime date; - try - { - if (NULL == m_pDB.get()) return date; - if (NULL == m_pDS.get()) return date; - - std::string strSQL = PrepareSQL("select * from repo where addonID='%s'",id.c_str()); - m_pDS->query(strSQL.c_str()); - if (!m_pDS->eof()) - { - date.SetFromDBDateTime(m_pDS->fv("lastcheck").get_asString()); - return date; - } - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on repo '%s'", __FUNCTION__, id.c_str()); - } - return date; -} - - -AddonVersion CAddonDatabase::GetRepoVersion(const std::string& id) -{ - AddonVersion version("0.0.0"); - try - { - if (NULL == m_pDB.get()) return version; - if (NULL == m_pDS2.get()) return version; - - std::string strSQL = PrepareSQL("select * from repo where addonID='%s'",id.c_str()); - m_pDS->query(strSQL.c_str()); - if (!m_pDS->eof()) - { - return AddonVersion(m_pDS->fv("version").get_asString()); - } - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon %s", __FUNCTION__, id.c_str()); - } - return version; -} - -bool CAddonDatabase::SetRepoTimestamp(const std::string& id, const std::string& time, const ADDON::AddonVersion& version) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - std::string sql = PrepareSQL("UPDATE repo SET lastcheck='%s', version='%s' WHERE addonID='%s'", - time.c_str(), version.asString().c_str(), id.c_str()); - m_pDS->exec(sql.c_str()); - - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on repo '%s'", __FUNCTION__, id.c_str()); - } - return false; -} - -bool CAddonDatabase::GetRepository(int id, VECADDONS& addons) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - std::string strSQL = PrepareSQL("select * from addonlinkrepo where idRepo=%i",id); - m_pDS->query(strSQL.c_str()); - while (!m_pDS->eof()) - { - AddonPtr addon; - if (GetAddon(m_pDS->fv("idAddon").get_asInt(),addon)) - addons.push_back(addon); - m_pDS->next(); - } - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on repo %i", __FUNCTION__, id); - } - return false; -} - -bool CAddonDatabase::GetRepository(const std::string& id, VECADDONS& addons) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - std::string strSQL = PrepareSQL("select id from repo where addonID='%s'",id.c_str()); - m_pDS->query(strSQL.c_str()); - if (!m_pDS->eof()) - return GetRepository(m_pDS->fv(0).get_asInt(),addons); - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on repo %s", __FUNCTION__, id.c_str()); - } - return false; -} - -bool CAddonDatabase::Search(const std::string& search, VECADDONS& addons) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - std::string strSQL; - strSQL=PrepareSQL("SELECT addonID FROM addon WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%'", search.c_str(), search.c_str(), search.c_str()); - CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - - if (!m_pDS->query(strSQL.c_str())) return false; - if (m_pDS->num_rows() == 0) return false; - - while (!m_pDS->eof()) - { - AddonPtr addon; - GetAddon(m_pDS->fv(0).get_asString(),addon); - if (addon->Type() >= ADDON_UNKNOWN+1 && addon->Type() < ADDON_SCRAPER_LIBRARY) - addons.push_back(addon); - m_pDS->next(); - } - m_pDS->close(); - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed", __FUNCTION__); - } - return false; -} - -void CAddonDatabase::SetPropertiesFromAddon(const AddonPtr& addon, - CFileItemPtr& pItem) -{ - pItem->SetProperty("Addon.ID", addon->ID()); - pItem->SetProperty("Addon.Type", TranslateType(addon->Type(),true)); - pItem->SetProperty("Addon.intType", TranslateType(addon->Type())); - pItem->SetProperty("Addon.Name", addon->Name()); - pItem->SetProperty("Addon.Version", addon->Version().asString()); - pItem->SetProperty("Addon.Summary", addon->Summary()); - pItem->SetProperty("Addon.Description", addon->Description()); - pItem->SetProperty("Addon.Creator", addon->Author()); - pItem->SetProperty("Addon.Disclaimer", addon->Disclaimer()); - pItem->SetProperty("Addon.Rating", addon->Stars()); - std::string starrating = StringUtils::Format("rating%d.png", addon->Stars()); - pItem->SetProperty("Addon.StarRating",starrating); - pItem->SetProperty("Addon.Path", addon->Path()); - if (addon->Props().broken == "DEPSNOTMET") - pItem->SetProperty("Addon.Broken", g_localizeStrings.Get(24044)); - else - pItem->SetProperty("Addon.Broken", addon->Props().broken); - std::map::iterator it = - addon->Props().extrainfo.find("language"); - if (it != addon->Props().extrainfo.end()) - pItem->SetProperty("Addon.Language", it->second); -} - -bool CAddonDatabase::DisableAddon(const std::string &addonID, bool disable /* = true */) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - if (disable) - { - if (!IsAddonDisabled(addonID)) // Enabled - { - std::string sql = PrepareSQL("insert into disabled(id, addonID) values(NULL, '%s')", addonID.c_str()); - m_pDS->exec(sql); - - // If the addon is a special, call the disabled handler - AddonPtr addon; - if ((CAddonMgr::Get().GetAddon(addonID, addon, ADDON_SERVICE, false) - || CAddonMgr::Get().GetAddon(addonID, addon, ADDON_PVRDLL, false) - || CAddonMgr::Get().GetAddon(addonID, addon, ADDON_CONTEXT_ITEM, false)) && addon) - addon->OnDisabled(); - - return true; - } - return false; // already disabled or failed query - } - else - { - bool disabled = IsAddonDisabled(addonID); //we need to know if service addon is running - std::string sql = PrepareSQL("delete from disabled where addonID='%s'", addonID.c_str()); - m_pDS->exec(sql); - - if (disabled) - { - // If the addon is a special, call the enabled handler - AddonPtr addon; - if ((CAddonMgr::Get().GetAddon(addonID, addon, ADDON_SERVICE, false) - || CAddonMgr::Get().GetAddon(addonID, addon, ADDON_PVRDLL, false) - || CAddonMgr::Get().GetAddon(addonID, addon, ADDON_CONTEXT_ITEM, false)) && addon) - addon->OnEnabled(); - } - } - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon '%s'", __FUNCTION__, addonID.c_str()); - } - return false; -} - -bool CAddonDatabase::BreakAddon(const std::string &addonID, const std::string& reason) -{ - if (reason.empty()) - return ExecuteQuery(PrepareSQL("DELETE FROM broken WHERE addonID='%s'", addonID.c_str())); - else - return ExecuteQuery(PrepareSQL("REPLACE INTO broken(addonID, reason) VALUES('%s', '%s')", - addonID.c_str(), reason.c_str())); -} - -bool CAddonDatabase::HasAddon(const std::string &addonID) -{ - std::string strWhereClause = PrepareSQL("addonID = '%s'", addonID.c_str()); - std::string strHasAddon = GetSingleValue("addon", "id", strWhereClause); - - return !strHasAddon.empty(); -} - -bool CAddonDatabase::IsAddonDisabled(const std::string &addonID) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - std::string sql = PrepareSQL("select id from disabled where addonID='%s'", addonID.c_str()); - m_pDS->query(sql.c_str()); - bool ret = !m_pDS->eof(); // in the disabled table -> disabled - m_pDS->close(); - return ret; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon %s", __FUNCTION__, addonID.c_str()); - } - return false; -} - -bool CAddonDatabase::IsSystemPVRAddonEnabled(const std::string &addonID) -{ - std::string strWhereClause = PrepareSQL("addonID = '%s'", addonID.c_str()); - std::string strEnabled = GetSingleValue("pvrenabled", "id", strWhereClause); - - return !strEnabled.empty(); -} - -std::string CAddonDatabase::IsAddonBroken(const std::string &addonID) -{ - return GetSingleValue(PrepareSQL("SELECT reason FROM broken WHERE addonID='%s'", addonID.c_str())); -} - -bool CAddonDatabase::HasDisabledAddons() -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - m_pDS->query("select count(id) from disabled"); - bool ret = !m_pDS->eof() && m_pDS->fv(0).get_asInt() > 0; // have rows -> have disabled addons - m_pDS->close(); - return ret; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed", __FUNCTION__); - } - return false; -} - -bool CAddonDatabase::BlacklistAddon(const std::string& addonID, - const std::string& version) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - std::string sql = PrepareSQL("insert into blacklist(id, addonID, version) values(NULL, '%s', '%s')", addonID.c_str(),version.c_str()); - m_pDS->exec(sql); - - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon '%s' for version '%s'", __FUNCTION__, addonID.c_str(),version.c_str()); - } - return false; -} - -bool CAddonDatabase::IsAddonBlacklisted(const std::string& addonID, - const std::string& version) -{ - std::string where = PrepareSQL("addonID='%s' and version='%s'",addonID.c_str(),version.c_str()); - return !GetSingleValue("blacklist","addonID",where).empty(); -} - -bool CAddonDatabase::RemoveAddonFromBlacklist(const std::string& addonID, - const std::string& version) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS.get()) return false; - - std::string sql = PrepareSQL("delete from blacklist where addonID='%s' and version='%s'",addonID.c_str(),version.c_str()); - m_pDS->exec(sql); - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed on addon '%s' for version '%s'", __FUNCTION__, addonID.c_str(),version.c_str()); - } - return false; -} - -bool CAddonDatabase::AddPackage(const std::string& addonID, - const std::string& packageFileName, - const std::string& hash) -{ - std::string sql = PrepareSQL("insert into package(id, addonID, filename, hash)" - "values(NULL, '%s', '%s', '%s')", - addonID.c_str(), packageFileName.c_str(), hash.c_str()); - return ExecuteQuery(sql); -} - -bool CAddonDatabase::GetPackageHash(const std::string& addonID, - const std::string& packageFileName, - std::string& hash) -{ - std::string where = PrepareSQL("addonID='%s' and filename='%s'", - addonID.c_str(), packageFileName.c_str()); - hash = GetSingleValue("package", "hash", where); - return !hash.empty(); -} - -bool CAddonDatabase::RemovePackage(const std::string& packageFileName) -{ - std::string sql = PrepareSQL("delete from package where filename='%s'", packageFileName.c_str()); - return ExecuteQuery(sql); -} - diff --git a/xbmc/addons/AddonDatabase.h b/xbmc/addons/AddonDatabase.h deleted file mode 100644 index b32f2a4..0000000 --- a/xbmc/addons/AddonDatabase.h +++ /dev/null @@ -1,175 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "dbwrappers/Database.h" -#include "addons/Addon.h" -#include "FileItem.h" -#include - -class CAddonDatabase : public CDatabase -{ -public: - CAddonDatabase(); - virtual ~CAddonDatabase(); - virtual bool Open(); - - int AddAddon(const ADDON::AddonPtr& item, int idRepo); - bool GetAddon(const std::string& addonID, ADDON::AddonPtr& addon); - bool GetAddons(ADDON::VECADDONS& addons); - - /*! \brief grab the (largest) add-on version for an add-on */ - ADDON::AddonVersion GetAddonVersion(const std::string &id); - - /*! \brief Grab the repository from which a given addon came - \param addonID - the id of the addon in question - \param repo [out] - the id of the repository - \return true if a repo was found, false otherwise. - */ - bool GetRepoForAddon(const std::string& addonID, std::string& repo); - int AddRepository(const std::string& id, const ADDON::VECADDONS& addons, const std::string& checksum, const ADDON::AddonVersion& version); - void DeleteRepository(const std::string& id); - void DeleteRepository(int id); - int GetRepoChecksum(const std::string& id, std::string& checksum); - bool GetRepository(const std::string& id, ADDON::VECADDONS& addons); - bool GetRepository(int id, ADDON::VECADDONS& addons); - bool SetRepoTimestamp(const std::string& id, const std::string& timestamp, const ADDON::AddonVersion& version); - - /*! \brief Retrieve the time a repository was last checked - \param id id of the repo - \return last time the repo was checked, current time if not available - \sa SetRepoTimestamp */ - CDateTime GetRepoTimestamp(const std::string& id); - - ADDON::AddonVersion GetRepoVersion(const std::string& id); - - bool Search(const std::string& search, ADDON::VECADDONS& items); - static void SetPropertiesFromAddon(const ADDON::AddonPtr& addon, CFileItemPtr& item); - - /*! \brief Disable an addon. - Sets a flag that this addon has been disabled. If disabled, it is usually still available on disk. - \param addonID id of the addon to disable - \param disable whether to enable or disable. Defaults to true (disable) - \return true on success, false on failure - \sa IsAddonDisabled, HasDisabledAddons */ - bool DisableAddon(const std::string &addonID, bool disable = true); - - /*! \brief Checks if an addon is in the database. - \param addonID id of the addon to be checked - \return true if addon is in database, false if addon is not in database yet */ - bool HasAddon(const std::string &addonID); - - /*! \brief Check whether an addon has been disabled via DisableAddon. - \param addonID id of the addon to check - \return true if the addon is disabled, false otherwise - \sa DisableAddon, HasDisabledAddons */ - bool IsAddonDisabled(const std::string &addonID); - - /*! \brief Check whether we have disabled addons. - \return true if we have disabled addons, false otherwise - \sa DisableAddon, IsAddonDisabled */ - bool HasDisabledAddons(); - - /*! @deprecated only here to allow clean upgrades from earlier pvr versions - */ - bool IsSystemPVRAddonEnabled(const std::string &addonID); - - /*! \brief Mark an addon as broken - Sets a flag that this addon has been marked as broken in the repository. - \param addonID id of the addon to mark as broken - \param reason why it is broken - if non empty we take it as broken. Defaults to empty - \return true on success, false on failure - \sa IsAddonBroken */ - bool BreakAddon(const std::string &addonID, const std::string& reason=""); - - /*! \brief Check whether an addon has been marked as broken via BreakAddon. - \param addonID id of the addon to check - \return reason if the addon is broken, blank otherwise - \sa BreakAddon */ - std::string IsAddonBroken(const std::string &addonID); - - bool BlacklistAddon(const std::string& addonID, const std::string& version); - bool IsAddonBlacklisted(const std::string& addonID, const std::string& version); - bool RemoveAddonFromBlacklist(const std::string& addonID, - const std::string& version); - - /*! \brief Store an addon's package filename and that file's hash for future verification - \param addonID id of the addon we're adding a package for - \param packageFileName filename of the package - \param hash MD5 checksum of the package - \return Whether or not the info successfully made it into the DB. - \sa GetPackageHash, RemovePackage - */ - bool AddPackage(const std::string& addonID, - const std::string& packageFileName, - const std::string& hash); - /*! \brief Query the MD5 checksum of the given given addon's given package - \param addonID id of the addon we're who's package we're querying - \param packageFileName filename of the package - \param hash return the MD5 checksum of the package - \return Whether or not we found a hash for the given addon's given package - \sa AddPackage, RemovePackage - */ - bool GetPackageHash(const std::string& addonID, - const std::string& packageFileName, - std::string& hash); - /*! \brief Remove a package's info from the database - \param packageFileName filename of the package - \return Whether or not we succeeded in removing the package - \sa AddPackage, GetPackageHash - */ - bool RemovePackage(const std::string& packageFileName); -protected: - virtual void CreateTables(); - virtual void CreateAnalytics(); - virtual void UpdateTables(int version); - virtual int GetMinSchemaVersion() const { return 15; } - virtual int GetSchemaVersion() const { return 17; } - const char *GetBaseDBName() const { return "Addons"; } - - bool GetAddon(int id, ADDON::AddonPtr& addon); - - /* keep in sync with the select in GetAddon */ - enum _AddonFields - { - addon_id=0, - addon_type, - addon_name, - addon_summary, - addon_description, - addon_stars, - addon_path, - addon_addonID, - addon_icon, - addon_version, - addon_changelog, - addon_fanart, - addon_author, - addon_disclaimer, - addon_minversion, - broken_reason, - addonextra_key, - addonextra_value, - dependencies_addon, - dependencies_version, - dependencies_optional - } AddonFields; -}; - diff --git a/xbmc/addons/AddonDll.h b/xbmc/addons/AddonDll.h deleted file mode 100644 index d5e4e9e..0000000 --- a/xbmc/addons/AddonDll.h +++ /dev/null @@ -1,572 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ -#include -#include - -#include "Addon.h" -#include "DllAddon.h" -#include "AddonManager.h" -#include "AddonStatusHandler.h" -#include "AddonCallbacks.h" -#include "utils/URIUtils.h" -#include "filesystem/File.h" -#include "filesystem/SpecialProtocol.h" -#include "filesystem/Directory.h" -#include "utils/log.h" -#include "interfaces/IAnnouncer.h" -#include "interfaces/AnnouncementManager.h" -#include "utils/XMLUtils.h" -#include "Util.h" - -namespace ADDON -{ - template - class CAddonDll : public CAddon, public ANNOUNCEMENT::IAnnouncer - { - public: - CAddonDll(const AddonProps &props); - CAddonDll(const cp_extension_t *ext); - CAddonDll(const CAddonDll &rhs); - virtual ~CAddonDll(); - virtual AddonPtr Clone() const; - virtual ADDON_STATUS GetStatus(); - - // addon settings - virtual void SaveSettings(); - virtual std::string GetSetting(const std::string& key); - - ADDON_STATUS Create(); - virtual void Stop(); - virtual bool CheckAPIVersion(void) { return true; } - void Destroy(); - - bool DllLoaded(void) const; - - void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); - - protected: - void HandleException(std::exception &e, const char* context); - bool Initialized() { return m_initialized; } - virtual void BuildLibName(const cp_extension_t *ext = NULL) {} - virtual bool LoadSettings(); - TheStruct* m_pStruct; - TheProps* m_pInfo; - CAddonCallbacks* m_pHelpers; - bool m_bIsChild; - - private: - TheDll* m_pDll; - bool m_initialized; - bool LoadDll(); - bool m_needsavedsettings; - - virtual ADDON_STATUS TransferSettings(); - TiXmlElement MakeSetting(DllSetting& setting) const; - - static void AddOnStatusCallback(void *userData, const ADDON_STATUS status, const char* msg); - static bool AddOnGetSetting(void *userData, const char *settingName, void *settingValue); - static void AddOnOpenSettings(const char *url, bool bReload); - static void AddOnOpenOwnSettings(void *userData, bool bReload); - static const char* AddOnGetAddonDirectory(void *userData); - static const char* AddOnGetUserDirectory(void *userData); - }; - -template -CAddonDll::CAddonDll(const cp_extension_t *ext) - : CAddon(ext), - m_bIsChild(false) -{ - // if library attribute isn't present, look for a system-dependent one - if (ext && m_strLibName.empty()) - { -#if defined(TARGET_ANDROID) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_android"); -#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_linux"); -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_windx"); -#elif defined(TARGET_DARWIN) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_osx"); -#endif - } - - m_pStruct = NULL; - m_initialized = false; - m_pDll = NULL; - m_pInfo = NULL; - m_pHelpers = NULL; - m_needsavedsettings = false; -} - -template -CAddonDll::CAddonDll(const AddonProps &props) - : CAddon(props), - m_bIsChild(false) -{ - m_pStruct = NULL; - m_initialized = false; - m_pDll = NULL; - m_pInfo = NULL; - m_pHelpers = NULL; - m_needsavedsettings = false; -} - -template -CAddonDll::CAddonDll(const CAddonDll &rhs) - : CAddon(rhs), - m_bIsChild(true) -{ - m_pStruct = rhs.m_pStruct; - m_initialized = rhs.m_initialized; - m_pDll = rhs.m_pDll; - m_pInfo = rhs.m_pInfo; - m_pHelpers = rhs.m_pHelpers; - m_needsavedsettings = rhs.m_needsavedsettings; -} - -template -CAddonDll::~CAddonDll() -{ - if (m_initialized) - Destroy(); -} - -template -AddonPtr CAddonDll::Clone() const -{ - return AddonPtr(new CAddonDll(*this)); -} - -template -bool CAddonDll::LoadDll() -{ - std::string strFileName; - if (!m_bIsChild) - { - strFileName = LibPath(); - } - else - { //FIXME hack to load same Dll twice - std::string extension = URIUtils::GetExtension(m_strLibName); - strFileName = "special://temp/" + m_strLibName; - URIUtils::RemoveExtension(strFileName); - strFileName += "-" + ID() + extension; - - if (!XFILE::CFile::Exists(strFileName)) - XFILE::CFile::Copy(LibPath(), strFileName); - - CLog::Log(LOGNOTICE, "ADDON: Loaded virtual child addon %s", strFileName.c_str()); - } - - /* Check if lib being loaded exists, else check in XBMC binary location */ -#if defined(TARGET_ANDROID) - // Android libs MUST live in this path, else multi-arch will break. - // The usual soname requirements apply. no subdirs, and filename is ^lib.*\.so$ - if (!XFILE::CFile::Exists(strFileName)) - { - std::string tempbin = getenv("XBMC_ANDROID_LIBS"); - strFileName = tempbin + "/" + m_strLibName; - } -#endif - if (!XFILE::CFile::Exists(strFileName)) - { - std::string temp = CSpecialProtocol::TranslatePath("special://xbmc/"); - std::string tempbin = CSpecialProtocol::TranslatePath("special://xbmcbin/"); - strFileName.erase(0, temp.size()); - strFileName = tempbin + strFileName; - if (!XFILE::CFile::Exists(strFileName)) - { - CLog::Log(LOGERROR, "ADDON: Could not locate %s", m_strLibName.c_str()); - return false; - } - } - - /* Load the Dll */ - m_pDll = new TheDll; - m_pDll->SetFile(strFileName); - m_pDll->EnableDelayedUnload(false); - if (!m_pDll->Load()) - { - delete m_pDll; - m_pDll = NULL; - new CAddonStatusHandler(ID(), ADDON_STATUS_UNKNOWN, "Can't load Dll", false); - return false; - } - - m_pStruct = (TheStruct*)malloc(sizeof(TheStruct)); - if (m_pStruct) - { - ZeroMemory(m_pStruct, sizeof(TheStruct)); - m_pDll->GetAddon(m_pStruct); - return true; - } - - return false; -} - -template -ADDON_STATUS CAddonDll::Create() -{ - ADDON_STATUS status(ADDON_STATUS_UNKNOWN); - CLog::Log(LOGDEBUG, "ADDON: Dll Initializing - %s", Name().c_str()); - m_initialized = false; - - if (!LoadDll() || !CheckAPIVersion()) - return ADDON_STATUS_PERMANENT_FAILURE; - - /* Allocate the helper function class to allow crosstalk over - helper libraries */ - m_pHelpers = new CAddonCallbacks(this); - - /* Call Create to make connections, initializing data or whatever is - needed to become the AddOn running */ - try - { - status = m_pDll->Create(m_pHelpers->GetCallbacks(), m_pInfo); - if (status == ADDON_STATUS_OK) - { - m_initialized = true; - ANNOUNCEMENT::CAnnouncementManager::Get().AddAnnouncer(this); - } - else if ((status == ADDON_STATUS_NEED_SETTINGS) || (status == ADDON_STATUS_NEED_SAVEDSETTINGS)) - { - m_needsavedsettings = (status == ADDON_STATUS_NEED_SAVEDSETTINGS); - if ((status = TransferSettings()) == ADDON_STATUS_OK) - m_initialized = true; - else - new CAddonStatusHandler(ID(), status, "", false); - } - else - { // Addon failed initialization - CLog::Log(LOGERROR, "ADDON: Dll %s - Client returned bad status (%i) from Create and is not usable", Name().c_str(), status); - new CAddonStatusHandler(ID(), status, "", false); - } - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Create"); - } - - if (!m_initialized) - SAFE_DELETE(m_pHelpers); - - return status; -} - -template -void CAddonDll::Stop() -{ - /* Inform dll to stop all activities */ - try - { - if (m_needsavedsettings) // If the addon supports it we save some settings to settings.xml before stop - { - char str_id[64] = ""; - char str_value[1024]; - CAddon::LoadUserSettings(); - for (unsigned int i=0; (strcmp(str_id,"###End") != 0); i++) - { - strcpy(str_id, "###GetSavedSettings"); - sprintf (str_value, "%i", i); - ADDON_STATUS status = m_pDll->SetSetting((const char*)&str_id, (void*)&str_value); - - if (status == ADDON_STATUS_UNKNOWN) - break; - - if (strcmp(str_id,"###End") != 0) UpdateSetting(str_id, str_value); - } - CAddon::SaveSettings(); - } - if (m_pDll) - { - m_pDll->Stop(); - CLog::Log(LOGINFO, "ADDON: Dll Stopped - %s", Name().c_str()); - } - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Stop"); - } -} - -template -void CAddonDll::Destroy() -{ - ANNOUNCEMENT::CAnnouncementManager::Get().RemoveAnnouncer(this); - - /* Unload library file */ - try - { - if (m_pDll) - { - m_pDll->Destroy(); - m_pDll->Unload(); - } - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Unload"); - } - delete m_pHelpers; - m_pHelpers = NULL; - free(m_pStruct); - m_pStruct = NULL; - if (m_pDll) - { - delete m_pDll; - m_pDll = NULL; - CLog::Log(LOGINFO, "ADDON: Dll Destroyed - %s", Name().c_str()); - } - m_initialized = false; -} - -template -bool CAddonDll::DllLoaded(void) const -{ - return m_pDll != NULL; -} - -template -ADDON_STATUS CAddonDll::GetStatus() -{ - try - { - return m_pDll->GetStatus(); - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->GetStatus()"); - } - return ADDON_STATUS_UNKNOWN; -} - -template -bool CAddonDll::LoadSettings() -{ - if (m_settingsLoaded) - return true; - - if (!LoadDll()) - return false; - - ADDON_StructSetting** sSet; - std::vector vSet; - unsigned entries = 0; - try - { - entries = m_pDll->GetSettings(&sSet); - DllUtils::StructToVec(entries, &sSet, &vSet); - m_pDll->FreeSettings(); - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->GetSettings()"); - return false; - } - - if (vSet.size()) - { - // regenerate XML doc - m_addonXmlDoc.Clear(); - TiXmlElement node("settings"); - m_addonXmlDoc.InsertEndChild(node); - - for (unsigned i=0; i < entries; i++) - { - DllSetting& setting = vSet[i]; - m_addonXmlDoc.RootElement()->InsertEndChild(MakeSetting(setting)); - } - CAddon::SettingsFromXML(m_addonXmlDoc, true); - } - else - return CAddon::LoadSettings(); - - m_settingsLoaded = true; - CAddon::LoadUserSettings(); - return true; -} - -template -TiXmlElement CAddonDll::MakeSetting(DllSetting& setting) const -{ - TiXmlElement node("setting"); - - switch (setting.type) - { - case DllSetting::CHECK: - { - node.SetAttribute("id", setting.id); - node.SetAttribute("type", "bool"); - node.SetAttribute("label", setting.label); - break; - } - case DllSetting::SPIN: - { - node.SetAttribute("id", setting.id); - node.SetAttribute("type", "enum"); - node.SetAttribute("label", setting.label); - std::string values; - for (unsigned int i = 0; i < setting.entry.size(); i++) - { - values.append(setting.entry[i]); - values.append("|"); - } - node.SetAttribute("values", values.c_str()); - break; - } - default: - break; - } - - return node; -} - -template -void CAddonDll::SaveSettings() -{ - // must save first, as TransferSettings() reloads saved settings! - CAddon::SaveSettings(); - if (m_initialized) - TransferSettings(); -} - -template -std::string CAddonDll::GetSetting(const std::string& key) -{ - return CAddon::GetSetting(key); -} - -template -ADDON_STATUS CAddonDll::TransferSettings() -{ - bool restart = false; - ADDON_STATUS reportStatus = ADDON_STATUS_OK; - - CLog::Log(LOGDEBUG, "Calling TransferSettings for: %s", Name().c_str()); - - LoadSettings(); - - const TiXmlElement *category = m_addonXmlDoc.RootElement() ? m_addonXmlDoc.RootElement()->FirstChildElement("category") : NULL; - if (!category) - category = m_addonXmlDoc.RootElement(); // no categories - - while (category) - { - const TiXmlElement *setting = category->FirstChildElement("setting"); - while (setting) - { - ADDON_STATUS status = ADDON_STATUS_OK; - const char *id = setting->Attribute("id"); - const std::string type = XMLUtils::GetAttribute(setting, "type"); - const char *option = setting->Attribute("option"); - - if (id && !type.empty()) - { - if (type == "sep" || type == "lsep") - { - /* Don't propagate separators */ - } - else if (type == "text" || type == "ipaddress" || - type == "video" || type == "audio" || - type == "image" || type == "folder" || - type == "executable" || type == "file" || - type == "action" || type == "date" || - type == "time" || type == "select" || - type == "addon" || type == "labelenum" || - type == "fileenum" ) - { - status = m_pDll->SetSetting(id, (const char*) GetSetting(id).c_str()); - } - else if (type == "enum" || type =="integer" || - type == "labelenum" || type == "rangeofnum") - { - int tmp = atoi(GetSetting(id).c_str()); - status = m_pDll->SetSetting(id, (int*) &tmp); - } - else if (type == "bool") - { - bool tmp = (GetSetting(id) == "true") ? true : false; - status = m_pDll->SetSetting(id, (bool*) &tmp); - } - else if (type == "rangeofnum" || type == "slider" || - type == "number") - { - float tmpf = (float)atof(GetSetting(id).c_str()); - int tmpi; - - if (option && strcmpi(option,"int") == 0) - { - tmpi = (int)floor(tmpf); - status = m_pDll->SetSetting(id, (int*) &tmpi); - } - else - { - status = m_pDll->SetSetting(id, (float*) &tmpf); - } - } - else - { - /* Log unknowns as an error, but go ahead and transfer the string */ - CLog::Log(LOGERROR, "Unknown setting type '%s' for %s", type.c_str(), Name().c_str()); - status = m_pDll->SetSetting(id, (const char*) GetSetting(id).c_str()); - } - - if (status == ADDON_STATUS_NEED_RESTART) - restart = true; - else if (status != ADDON_STATUS_OK) - reportStatus = status; - } - setting = setting->NextSiblingElement("setting"); - } - category = category->NextSiblingElement("category"); - } - - if (restart || reportStatus != ADDON_STATUS_OK) - { - new CAddonStatusHandler(ID(), restart ? ADDON_STATUS_NEED_RESTART : reportStatus, "", true); - } - - return ADDON_STATUS_OK; -} - -template -void CAddonDll::Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) -{ - try - { - m_pDll->Announce(ANNOUNCEMENT::AnnouncementFlagToString(flag), sender, message, &data); - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Announce()"); - } -} - -template -void CAddonDll::HandleException(std::exception &e, const char* context) -{ - m_initialized = false; - m_pDll->Unload(); - CLog::Log(LOGERROR, "ADDON: Dll %s, throws an exception '%s' during %s. Contact developer '%s' with bug reports", Name().c_str(), e.what(), context, Author().c_str()); -} - -}; /* namespace ADDON */ - diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp deleted file mode 100644 index f4a241c..0000000 --- a/xbmc/addons/AddonInstaller.cpp +++ /dev/null @@ -1,974 +0,0 @@ -/* - * Copyright (C) 2011-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 - * . - * - */ - -#include "AddonInstaller.h" -#include "utils/log.h" -#include "utils/FileUtils.h" -#include "utils/URIUtils.h" -#include "Util.h" -#include "guilib/LocalizeStrings.h" -#include "filesystem/Directory.h" -#include "settings/AdvancedSettings.h" -#include "settings/Settings.h" -#include "ApplicationMessenger.h" -#include "filesystem/FavouritesDirectory.h" -#include "utils/JobManager.h" -#include "dialogs/GUIDialogYesNo.h" -#include "addons/AddonManager.h" -#include "addons/Repository.h" -#include "guilib/GUIWindowManager.h" // for callback -#include "GUIUserMessages.h" // for callback -#include "utils/StringUtils.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "dialogs/GUIDialogOK.h" -#include "dialogs/GUIDialogProgress.h" -#include "URL.h" - -#include - -using namespace std; -using namespace XFILE; -using namespace ADDON; - - -struct find_map : public binary_function -{ - bool operator() (CAddonInstaller::JobMap::value_type t, unsigned int id) const - { - return (t.second.jobID == id); - } -}; - -CAddonInstaller::CAddonInstaller() - : m_repoUpdateJob(0) -{ } - -CAddonInstaller::~CAddonInstaller() -{ } - -CAddonInstaller &CAddonInstaller::Get() -{ - static CAddonInstaller addonInstaller; - return addonInstaller; -} - -void CAddonInstaller::OnJobComplete(unsigned int jobID, bool success, CJob* job) -{ - if (success) - CAddonMgr::Get().FindAddons(); - - CSingleLock lock(m_critSection); - if (strncmp(job->GetType(), "repoupdate", 10) == 0) - { - // repo job finished - m_repoUpdateDone.Set(); - m_repoUpdateJob = 0; - lock.Leave(); - } - else - { - // download job - JobMap::iterator i = find_if(m_downloadJobs.begin(), m_downloadJobs.end(), bind2nd(find_map(), jobID)); - if (i != m_downloadJobs.end()) - m_downloadJobs.erase(i); - lock.Leave(); - PrunePackageCache(); - } - - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); - g_windowManager.SendThreadMessage(msg); -} - -void CAddonInstaller::OnJobProgress(unsigned int jobID, unsigned int progress, unsigned int total, const CJob *job) -{ - CSingleLock lock(m_critSection); - JobMap::iterator i = find_if(m_downloadJobs.begin(), m_downloadJobs.end(), bind2nd(find_map(), jobID)); - if (i != m_downloadJobs.end()) - { - // update job progress - i->second.progress = progress; - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM); - msg.SetStringParam(i->first); - lock.Leave(); - g_windowManager.SendThreadMessage(msg); - } -} - -bool CAddonInstaller::IsDownloading() const -{ - CSingleLock lock(m_critSection); - return !m_downloadJobs.empty(); -} - -void CAddonInstaller::GetInstallList(VECADDONS &addons) const -{ - CSingleLock lock(m_critSection); - vector addonIDs; - for (JobMap::const_iterator i = m_downloadJobs.begin(); i != m_downloadJobs.end(); ++i) - { - if (i->second.jobID) - addonIDs.push_back(i->first); - } - lock.Leave(); - - CAddonDatabase database; - database.Open(); - for (vector::iterator it = addonIDs.begin(); it != addonIDs.end(); ++it) - { - AddonPtr addon; - if (database.GetAddon(*it, addon)) - addons.push_back(addon); - } -} - -bool CAddonInstaller::GetProgress(const std::string &addonID, unsigned int &percent) const -{ - CSingleLock lock(m_critSection); - JobMap::const_iterator i = m_downloadJobs.find(addonID); - if (i != m_downloadJobs.end()) - { - percent = i->second.progress; - return true; - } - return false; -} - -bool CAddonInstaller::Cancel(const std::string &addonID) -{ - CSingleLock lock(m_critSection); - JobMap::iterator i = m_downloadJobs.find(addonID); - if (i != m_downloadJobs.end()) - { - CJobManager::GetInstance().CancelJob(i->second.jobID); - m_downloadJobs.erase(i); - return true; - } - - return false; -} - -bool CAddonInstaller::InstallModal(const std::string &addonID, ADDON::AddonPtr &addon, bool promptForInstall /* = true */) -{ - if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) - return false; - - // we assume that addons that are enabled don't get to this routine (i.e. that GetAddon() has been called) - if (CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false)) - return false; // addon is installed but disabled, and the user has specifically activated something that needs - // the addon - should we enable it? - - // check we have it available - CAddonDatabase database; - database.Open(); - if (!database.GetAddon(addonID, addon)) - return false; - - // if specified ask the user if he wants it installed - if (promptForInstall && - !CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(24076), g_localizeStrings.Get(24100), - addon->Name().c_str(), g_localizeStrings.Get(24101))) - return false; - - if (!Install(addonID, true, "", false, true)) - return false; - - return CAddonMgr::Get().GetAddon(addonID, addon); -} - -bool CAddonInstaller::Install(const std::string &addonID, bool force /* = false */, const std::string &referer /* = "" */, bool background /* = true */, bool modal /* = false */) -{ - AddonPtr addon; - bool addonInstalled = CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false); - if (addonInstalled && !force) - return true; - - if (referer.empty()) - { - if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) - return false; - } - - // check whether we have it available in a repository - std::string hash; - if (!CAddonInstallJob::GetAddonWithHash(addonID, addon, hash)) - return false; - - return DoInstall(addon, hash, addonInstalled, referer, background, modal); -} - -bool CAddonInstaller::DoInstall(const AddonPtr &addon, const std::string &hash /* = "" */, bool update /* = false */, const std::string &referer /* = "" */, bool background /* = true */, bool modal /* = false */) -{ - // check whether we already have the addon installing - CSingleLock lock(m_critSection); - if (m_downloadJobs.find(addon->ID()) != m_downloadJobs.end()) - return false; - - CAddonInstallJob* installJob = new CAddonInstallJob(addon, hash, update, referer); - if (background) - { - unsigned int jobID = CJobManager::GetInstance().AddJob(installJob, this); - m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(jobID))); - return true; - } - - m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(0))); - lock.Leave(); - - bool result = false; - if (modal) - result = installJob->DoModal(); - else - result = installJob->DoWork(); - delete installJob; - - lock.Enter(); - JobMap::iterator i = m_downloadJobs.find(addon->ID()); - m_downloadJobs.erase(i); - - return result; -} - -bool CAddonInstaller::InstallFromZip(const std::string &path) -{ - if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) - return false; - - // grab the descriptive XML document from the zip, and read it in - CFileItemList items; - // BUG: some zip files return a single item (root folder) that we think is stored, so we don't use the zip:// protocol - CURL pathToUrl(path); - CURL zipDir = URIUtils::CreateArchivePath("zip", pathToUrl, ""); - if (!CDirectory::GetDirectory(zipDir, items) || items.Size() != 1 || !items[0]->m_bIsFolder) - { - CGUIDialogKaiToast::QueueNotification("", path, g_localizeStrings.Get(24045), TOAST_DISPLAY_TIME, false); - return false; - } - - // TODO: possibly add support for github generated zips here? - std::string archive = URIUtils::AddFileToFolder(items[0]->GetPath(), "addon.xml"); - - CXBMCTinyXML xml; - AddonPtr addon; - if (xml.LoadFile(archive) && CAddonMgr::Get().LoadAddonDescriptionFromMemory(xml.RootElement(), addon)) - { - // set the correct path - addon->Props().path = items[0]->GetPath(); - addon->Props().icon = URIUtils::AddFileToFolder(items[0]->GetPath(), "icon.png"); - - // install the addon - return DoInstall(addon); - } - - CGUIDialogKaiToast::QueueNotification("", path, g_localizeStrings.Get(24045), TOAST_DISPLAY_TIME, false); - return false; -} - -void CAddonInstaller::InstallFromXBMCRepo(const set &addonIDs) -{ - // first check we have the our repositories up to date (and wait until we do) - UpdateRepos(false, true); - - // now install the addons - for (set::const_iterator i = addonIDs.begin(); i != addonIDs.end(); ++i) - Install(*i); -} - -bool CAddonInstaller::CheckDependencies(const AddonPtr &addon, CAddonDatabase *database /* = NULL */) -{ - std::vector preDeps; - preDeps.push_back(addon->ID()); - CAddonDatabase localDB; - if (!database) - database = &localDB; - - return CheckDependencies(addon, preDeps, *database); -} - -bool CAddonInstaller::CheckDependencies(const AddonPtr &addon, - std::vector& preDeps, CAddonDatabase &database) -{ - if (addon == NULL) - return true; // a NULL addon has no dependencies - - if (!database.Open()) - return false; - - ADDONDEPS deps = addon->GetDeps(); - for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i) - { - const std::string &addonID = i->first; - const AddonVersion &version = i->second.first; - bool optional = i->second.second; - AddonPtr dep; - bool haveAddon = CAddonMgr::Get().GetAddon(addonID, dep); - if ((haveAddon && !dep->MeetsVersion(version)) || (!haveAddon && !optional)) - { - // we have it but our version isn't good enough, or we don't have it and we need it - if (!database.GetAddon(addonID, dep) || !dep->MeetsVersion(version)) - { - // we don't have it in a repo, or we have it but the version isn't good enough, so dep isn't satisfied. - CLog::Log(LOGDEBUG, "CAddonInstallJob[%s]: requires %s version %s which is not available", addon->ID().c_str(), addonID.c_str(), version.asString().c_str()); - database.Close(); - return false; - } - } - - // at this point we have our dep, or the dep is optional (and we don't have it) so check that it's OK as well - // TODO: should we assume that installed deps are OK? - if (dep && std::find(preDeps.begin(), preDeps.end(), dep->ID()) == preDeps.end()) - { - if (!CheckDependencies(dep, preDeps, database)) - { - database.Close(); - preDeps.push_back(dep->ID()); - return false; - } - } - } - database.Close(); - - return true; -} - -CDateTime CAddonInstaller::LastRepoUpdate() const -{ - CDateTime update; - CAddonDatabase database; - if (!database.Open()) - return update; - - VECADDONS addons; - CAddonMgr::Get().GetAddons(ADDON_REPOSITORY, addons); - for (unsigned int i = 0; i < addons.size(); i++) - { - CDateTime lastUpdate = database.GetRepoTimestamp(addons[i]->ID()); - if (lastUpdate.IsValid() && lastUpdate > update) - update = lastUpdate; - } - - return update; -} - -void CAddonInstaller::UpdateRepos(bool force, bool wait) -{ - CSingleLock lock(m_critSection); - if (m_repoUpdateJob) - { - if (wait) - { - // wait for our job to complete - lock.Leave(); - CLog::Log(LOGDEBUG, "%s - waiting for repository update job to finish...", __FUNCTION__); - m_repoUpdateDone.Wait(); - } - return; - } - - // don't run repo update jobs while on the login screen which runs under the master profile - if((g_windowManager.GetActiveWindow() & WINDOW_ID_MASK) == WINDOW_LOGIN_SCREEN) - return; - - if (!force && m_repoUpdateWatch.IsRunning() && m_repoUpdateWatch.GetElapsedSeconds() < 600) - return; - - CAddonDatabase database; - if (!database.Open()) - return; - - m_repoUpdateWatch.StartZero(); - - VECADDONS addons; - if (CAddonMgr::Get().GetAddons(ADDON_REPOSITORY, addons)) - { - for (const auto& repo : addons) - { - CDateTime lastUpdate = database.GetRepoTimestamp(repo->ID()); - if (force || !lastUpdate.IsValid() || lastUpdate + CDateTimeSpan(0, 24, 0, 0) < CDateTime::GetCurrentDateTime() - || repo->Version() != database.GetRepoVersion(repo->ID())) - { - CLog::Log(LOGDEBUG, "Checking repositories for updates (triggered by %s)", repo->Name().c_str()); - m_repoUpdateJob = CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(addons), this); - if (wait) - { - // wait for our job to complete - lock.Leave(); - CLog::Log(LOGDEBUG, "%s - waiting for this repository update job to finish...", __FUNCTION__); - m_repoUpdateDone.Wait(); - } - - return; - } - } - } -} - -bool CAddonInstaller::HasJob(const std::string& ID) const -{ - CSingleLock lock(m_critSection); - return m_downloadJobs.find(ID) != m_downloadJobs.end(); -} - -void CAddonInstaller::PrunePackageCache() -{ - std::map packs; - int64_t size = EnumeratePackageFolder(packs); - int64_t limit = (int64_t)g_advancedSettings.m_addonPackageFolderSize * 1024 * 1024; - if (size < limit) - return; - - // Prune packages - // 1. Remove the largest packages, leaving at least 2 for each add-on - CFileItemList items; - CAddonDatabase db; - db.Open(); - for (std::map::const_iterator it = packs.begin(); it != packs.end(); ++it) - { - it->second->Sort(SortByLabel, SortOrderDescending); - for (int j = 2; j < it->second->Size(); j++) - items.Add(CFileItemPtr(new CFileItem(*it->second->Get(j)))); - } - - items.Sort(SortBySize, SortOrderDescending); - int i = 0; - while (size > limit && i < items.Size()) - { - size -= items[i]->m_dwSize; - db.RemovePackage(items[i]->GetPath()); - CFileUtils::DeleteItem(items[i++], true); - } - - if (size > limit) - { - // 2. Remove the oldest packages (leaving least 1 for each add-on) - items.Clear(); - for (std::map::iterator it = packs.begin(); it != packs.end(); ++it) - { - if (it->second->Size() > 1) - items.Add(CFileItemPtr(new CFileItem(*it->second->Get(1)))); - } - - items.Sort(SortByDate, SortOrderAscending); - i = 0; - while (size > limit && i < items.Size()) - { - size -= items[i]->m_dwSize; - db.RemovePackage(items[i]->GetPath()); - CFileUtils::DeleteItem(items[i++],true); - } - } - - // clean up our mess - for (std::map::iterator it = packs.begin(); it != packs.end(); ++it) - delete it->second; -} - -int64_t CAddonInstaller::EnumeratePackageFolder(std::map& result) -{ - CFileItemList items; - CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS); - int64_t size = 0; - for (int i = 0; i < items.Size(); i++) - { - if (items[i]->m_bIsFolder) - continue; - - size += items[i]->m_dwSize; - std::string pack,dummy; - AddonVersion::SplitFileName(pack, dummy, items[i]->GetLabel()); - if (result.find(pack) == result.end()) - result[pack] = new CFileItemList; - result[pack]->Add(CFileItemPtr(new CFileItem(*items[i]))); - } - - return size; -} - -CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const std::string &hash /* = "" */, bool update /* = false */, const std::string &referer /* = "" */) - : m_addon(addon), - m_hash(hash), - m_update(update), - m_referer(referer) -{ } - -AddonPtr CAddonInstallJob::GetRepoForAddon(const AddonPtr& addon) -{ - AddonPtr repoPtr; - - CAddonDatabase database; - if (!database.Open()) - return repoPtr; - - std::string repo; - if (!database.GetRepoForAddon(addon->ID(), repo)) - return repoPtr; - - if (!CAddonMgr::Get().GetAddon(repo, repoPtr)) - return repoPtr; - - if (std::dynamic_pointer_cast(repoPtr) == NULL) - { - repoPtr.reset(); - return repoPtr; - } - - return repoPtr; -} - -bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, ADDON::AddonPtr& addon, std::string& hash) -{ - CAddonDatabase database; - if (!database.Open()) - return false; - - if (!database.GetAddon(addonID, addon)) - return false; - - AddonPtr ptr = GetRepoForAddon(addon); - if (ptr == NULL) - return false; - - RepositoryPtr repo = std::dynamic_pointer_cast(ptr); - if (repo == NULL) - return false; - - hash = repo->GetAddonHash(addon); - return true; -} - -bool CAddonInstallJob::DoWork() -{ - SetTitle(StringUtils::Format(g_localizeStrings.Get(24057).c_str(), m_addon->Name().c_str())); - SetProgress(0); - - // check whether all the dependencies are available or not - SetText(g_localizeStrings.Get(24058)); - if (!CAddonInstaller::Get().CheckDependencies(m_addon)) - { - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: dependency check failed", m_addon->ID().c_str()); - ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24044)); - return false; - } - - AddonPtr repoPtr = GetRepoForAddon(m_addon); - std::string installFrom; - if (!repoPtr || repoPtr->Props().libname.empty()) - { - // Addons are installed by downloading the .zip package on the server to the local - // packages folder, then extracting from the local .zip package into the addons folder - // Both these functions are achieved by "copying" using the vfs. - - std::string dest = "special://home/addons/packages/"; - std::string package = URIUtils::AddFileToFolder("special://home/addons/packages/", - URIUtils::GetFileName(m_addon->Path())); - if (URIUtils::HasSlashAtEnd(m_addon->Path())) - { // passed in a folder - all we need do is copy it across - installFrom = m_addon->Path(); - } - else - { - CAddonDatabase db; - if (!db.Open()) - { - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to open database", m_addon->ID().c_str()); - ReportInstallError(m_addon->ID(), m_addon->ID()); - return false; - } - - std::string md5; - // check that we don't already have a valid copy - if (!m_hash.empty() && CFile::Exists(package)) - { - if (db.GetPackageHash(m_addon->ID(), package, md5) && m_hash != md5) - { - db.RemovePackage(package); - CFile::Delete(package); - } - } - - // zip passed in - download + extract - if (!CFile::Exists(package)) - { - std::string path(m_addon->Path()); - if (!m_referer.empty() && URIUtils::IsInternetStream(path)) - { - CURL url(path); - url.SetProtocolOptions(m_referer); - path = url.Get(); - } - - if (!DownloadPackage(path, dest)) - { - CFile::Delete(package); - - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to download %s", m_addon->ID().c_str(), package.c_str()); - ReportInstallError(m_addon->ID(), URIUtils::GetFileName(package)); - return false; - } - } - - // at this point we have the package - check that it is valid - SetText(g_localizeStrings.Get(24077)); - if (!m_hash.empty()) - { - md5 = CUtil::GetFileMD5(package); - if (!StringUtils::EqualsNoCase(md5, m_hash)) - { - CFile::Delete(package); - - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: MD5 mismatch after download %s", m_addon->ID().c_str(), package.c_str()); - ReportInstallError(m_addon->ID(), URIUtils::GetFileName(package)); - return false; - } - - db.AddPackage(m_addon->ID(), package, md5); - } - - // check the archive as well - should have just a single folder in the root - CURL archive = URIUtils::CreateArchivePath("zip", CURL(package), ""); - - CFileItemList archivedFiles; - CDirectory::GetDirectory(archive, archivedFiles); - - if (archivedFiles.Size() != 1 || !archivedFiles[0]->m_bIsFolder) - { - // invalid package - db.RemovePackage(package); - CFile::Delete(package); - - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: invalid package %s", m_addon->ID().c_str(), package.c_str()); - ReportInstallError(m_addon->ID(), URIUtils::GetFileName(package)); - return false; - } - - installFrom = archivedFiles[0]->GetPath(); - } - repoPtr.reset(); - } - - // run any pre-install functions - bool reloadAddon = OnPreInstall(); - - // perform install - if (!Install(installFrom, repoPtr)) - return false; - - // run any post-install guff - OnPostInstall(reloadAddon); - - // and we're done! - MarkFinished(); - return true; -} - -bool CAddonInstallJob::DownloadPackage(const std::string &path, const std::string &dest) -{ - if (ShouldCancel(0, 1)) - return false; - - SetText(g_localizeStrings.Get(24078)); - - // need to download/copy the package first - CFileItemList list; - list.Add(CFileItemPtr(new CFileItem(path, false))); - list[0]->Select(true); - - return DoFileOperation(CFileOperationJob::ActionReplace, list, dest, true); -} - -bool CAddonInstallJob::DoFileOperation(FileAction action, CFileItemList &items, const std::string &file, bool useSameJob /* = true */) -{ - bool result = false; - if (useSameJob) - { - SetFileOperation(action, items, file); - - // temporarily disable auto-closing so not to close the current progress indicator - bool autoClose = GetAutoClose(); - if (autoClose) - SetAutoClose(false); - // temporarily disable updating title or text - bool updateInformation = GetUpdateInformation(); - if (updateInformation) - SetUpdateInformation(false); - - result = CFileOperationJob::DoWork(); - - SetUpdateInformation(updateInformation); - SetAutoClose(autoClose); - } - else - { - CFileOperationJob job(action, items, file); - - // pass our progress indicators to the temporary job and only allow it to - // show progress updates (no title or text changes) - job.SetProgressIndicators(GetProgressBar(), GetProgressDialog(), GetUpdateProgress(), false); - - result = job.DoWork(); - } - - return result; -} - -bool CAddonInstallJob::OnPreInstall() -{ - return m_addon->OnPreInstall(); -} - -bool CAddonInstallJob::DeleteAddon(const std::string &addonFolder) -{ - CFileItemList list; - list.Add(CFileItemPtr(new CFileItem(addonFolder, true))); - list[0]->Select(true); - - return DoFileOperation(CFileOperationJob::ActionDelete, list, "", false); -} - -bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& repo) -{ - SetText(g_localizeStrings.Get(24079)); - ADDONDEPS deps = m_addon->GetDeps(); - - unsigned int totalSteps = static_cast(deps.size()); - if (ShouldCancel(0, totalSteps)) - return false; - - // The first thing we do is install dependencies - std::string referer = StringUtils::Format("Referer=%s-%s.zip",m_addon->ID().c_str(),m_addon->Version().asString().c_str()); - for (ADDONDEPS::iterator it = deps.begin(); it != deps.end(); ++it) - { - if (it->first != "xbmc.metadata") - { - const std::string &addonID = it->first; - const AddonVersion &version = it->second.first; - bool optional = it->second.second; - AddonPtr dependency; - bool haveAddon = CAddonMgr::Get().GetAddon(addonID, dependency); - if ((haveAddon && !dependency->MeetsVersion(version)) || (!haveAddon && !optional)) - { - // we have it but our version isn't good enough, or we don't have it and we need it - bool force = dependency != NULL; - - // dependency is already queued up for install - ::Install will fail - // instead we wait until the Job has finished. note that we - // recall install on purpose in case prior installation failed - if (CAddonInstaller::Get().HasJob(addonID)) - { - while (CAddonInstaller::Get().HasJob(addonID)) - Sleep(50); - force = false; - - if (!CAddonMgr::Get().IsAddonInstalled(addonID)) - { - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to install dependency %s", m_addon->ID().c_str(), addonID.c_str()); - ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); - return false; - } - } - // don't have the addon or the addon isn't new enough - grab it (no new job for these) - else if (IsModal()) - { - AddonPtr addon; - std::string hash; - if (!CAddonInstallJob::GetAddonWithHash(addonID, addon, hash)) - { - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to find dependency %s", m_addon->ID().c_str(), addonID.c_str()); - ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); - return false; - } - - CAddonInstallJob dependencyJob(addon, hash, force, referer); - - // pass our progress indicators to the temporary job and don't allow it to - // show progress or information updates (no progress, title or text changes) - dependencyJob.SetProgressIndicators(GetProgressBar(), GetProgressDialog(), false, false); - - if (!dependencyJob.DoModal()) - { - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to install dependency %s", m_addon->ID().c_str(), addonID.c_str()); - ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); - return false; - } - } - else if (!CAddonInstaller::Get().Install(addonID, force, referer, false)) - { - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to install dependency %s", m_addon->ID().c_str(), addonID.c_str()); - ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); - return false; - } - } - } - - if (ShouldCancel(std::distance(deps.begin(), it), totalSteps)) - return false; - } - - SetText(g_localizeStrings.Get(24086)); - SetProgress(0); - - // now that we have all our dependencies, we can install our add-on - if (repo != NULL) - { - CFileItemList dummy; - std::string s = StringUtils::Format("plugin://%s/?action=install&package=%s&version=%s", repo->ID().c_str(), - m_addon->ID().c_str(), m_addon->Version().asString().c_str()); - if (!CDirectory::GetDirectory(s, dummy)) - { - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: installation of repository failed", m_addon->ID().c_str()); - ReportInstallError(m_addon->ID(), m_addon->ID()); - return false; - } - } - else - { - std::string addonFolder = installFrom; - URIUtils::RemoveSlashAtEnd(addonFolder); - addonFolder = URIUtils::AddFileToFolder("special://home/addons/", URIUtils::GetFileName(addonFolder)); - - CFileItemList install; - install.Add(CFileItemPtr(new CFileItem(installFrom, true))); - install[0]->Select(true); - - AddonPtr addon; - if (!DoFileOperation(CFileOperationJob::ActionReplace, install, "special://home/addons/", false) || - !CAddonMgr::Get().LoadAddonDescription(addonFolder, addon)) - { - // failed extraction or failed to load addon description - DeleteAddon(addonFolder); - - std::string addonID = URIUtils::GetFileName(addonFolder); - CLog::Log(LOGERROR, "CAddonInstallJob[%s]: could not read addon description of %s", addonID.c_str(), addonFolder.c_str()); - ReportInstallError(addonID, addonID); - return false; - } - - // Update the addon manager so that it has the newly installed add-on. - CAddonMgr::Get().FindAddons(); - } - SetProgress(100); - - return true; -} - -void CAddonInstallJob::OnPostInstall(bool reloadAddon) -{ - if (!IsModal() && CSettings::Get().GetBool("general.addonnotifications")) - CGUIDialogKaiToast::QueueNotification(m_addon->Icon(), m_addon->Name(), - g_localizeStrings.Get(m_update ? 24065 : 24064), - TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); - - m_addon->OnPostInstall(reloadAddon, m_update, IsModal()); -} - -void CAddonInstallJob::ReportInstallError(const std::string& addonID, const std::string& fileName, const std::string& message /* = "" */) -{ - AddonPtr addon; - CAddonDatabase database; - if (database.Open()) - { - database.GetAddon(addonID, addon); - database.Close(); - } - - MarkFinished(); - - std::string msg = message; - if (addon != NULL) - { - AddonPtr addon2; - CAddonMgr::Get().GetAddon(addonID, addon2); - if (msg.empty()) - msg = g_localizeStrings.Get(addon2 != NULL ? 113 : 114); - - if (IsModal()) - CGUIDialogOK::ShowAndGetInput(m_addon->Name(), msg); - else - CGUIDialogKaiToast::QueueNotification(addon->Icon(), addon->Name(), msg, TOAST_DISPLAY_TIME, false); - } - else - { - if (msg.empty()) - msg = g_localizeStrings.Get(114); - if (IsModal()) - CGUIDialogOK::ShowAndGetInput(fileName, msg); - else - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, fileName, msg, TOAST_DISPLAY_TIME, false); - } -} - -std::string CAddonInstallJob::AddonID() const -{ - return m_addon ? m_addon->ID() : ""; -} - -CAddonUnInstallJob::CAddonUnInstallJob(const AddonPtr &addon) - : m_addon(addon) -{ } - -bool CAddonUnInstallJob::DoWork() -{ - m_addon->OnPreUnInstall(); - - AddonPtr repoPtr = CAddonInstallJob::GetRepoForAddon(m_addon); - RepositoryPtr therepo = std::dynamic_pointer_cast(repoPtr); - if (therepo != NULL && !therepo->Props().libname.empty()) - { - CFileItemList dummy; - std::string s = StringUtils::Format("plugin://%s/?action=uninstall&package=%s", therepo->ID().c_str(), m_addon->ID().c_str()); - if (!CDirectory::GetDirectory(s, dummy)) - return false; - } - else if (!DeleteAddon(m_addon->Path())) - return false; - - OnPostUnInstall(); - - return true; -} - -bool CAddonUnInstallJob::DeleteAddon(const std::string &addonFolder) -{ - CFileItemList list; - list.Add(CFileItemPtr(new CFileItem(addonFolder, true))); - list[0]->Select(true); - - SetFileOperation(CFileOperationJob::ActionDelete, list, ""); - return CFileOperationJob::DoWork(); -} - -void CAddonUnInstallJob::OnPostUnInstall() -{ - bool bSave = false; - CFileItemList items; - XFILE::CFavouritesDirectory::Load(items); - for (int i = 0; i < items.Size(); i++) - { - if (items[i]->GetPath().find(m_addon->ID()) != std::string::npos) - { - items.Remove(items[i].get()); - bSave = true; - } - } - - if (bSave) - CFavouritesDirectory::Save(items); - - m_addon->OnPostUnInstall(); -} diff --git a/xbmc/addons/AddonInstaller.h b/xbmc/addons/AddonInstaller.h deleted file mode 100644 index aca93d8..0000000 --- a/xbmc/addons/AddonInstaller.h +++ /dev/null @@ -1,229 +0,0 @@ -#pragma once -/* - * Copyright (C) 2011-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 - * . - * - */ - -#include "utils/FileOperationJob.h" -#include "addons/Addon.h" -#include "utils/Stopwatch.h" -#include "threads/Event.h" - -class CAddonDatabase; - -enum { - AUTO_UPDATES_ON = 0, - AUTO_UPDATES_NOTIFY, - AUTO_UPDATES_NEVER, - AUTO_UPDATES_MAX -}; - -class CAddonInstaller : public IJobCallback -{ -public: - static CAddonInstaller &Get(); - - bool IsDownloading() const; - void GetInstallList(ADDON::VECADDONS &addons) const; - bool GetProgress(const std::string &addonID, unsigned int &percent) const; - bool Cancel(const std::string &addonID); - - /*! \brief Installs the addon while showing a modal progress dialog - \param addonID the addon ID of the item to install. - \param addon [out] the installed addon for later use. - \param promptForInstall Whether or not to prompt the user before installing the addon. - \return true on successful install, false otherwise. - \sa Install - */ - bool InstallModal(const std::string &addonID, ADDON::AddonPtr &addon, bool promptForInstall = true); - - /*! \brief Install an addon if it is available in a repository - \param addonID the addon ID of the item to install - \param force whether to force the install even if the addon is already installed (eg for updating). Defaults to false. - \param referer string to use for referer for http fetch. Set to previous version when updating, parent when fetching a dependency - \param background whether to install in the background or not. Defaults to true. - \param modal whether to show a modal dialog when not installing in background - \return true on successful install, false on failure. - \sa DoInstall - */ - bool Install(const std::string &addonID, bool force = false, const std::string &referer="", bool background = true, bool modal = false); - - /*! \brief Install an addon from the given zip path - \param path the zip file to install from - \return true if successful, false otherwise - \sa DoInstall - */ - bool InstallFromZip(const std::string &path); - - /*! \brief Install a set of addons from the official repository (if needed) - \param addonIDs a set of addon IDs to install - */ - void InstallFromXBMCRepo(const std::set &addonIDs); - - /*! \brief Check whether dependencies of an addon exist or are installable. - Iterates through the addon's dependencies, checking they're installed or installable. - Each dependency must also satisfies CheckDependencies in turn. - \param addon the addon to check - \param database the database instance to update. Defaults to NULL. - \return true if dependencies are available, false otherwise. - */ - bool CheckDependencies(const ADDON::AddonPtr &addon, CAddonDatabase *database = NULL); - - /*! \brief Update all repositories (if needed) - Runs through all available repositories and queues an update of them if they - need it (according to the set timeouts) or if forced. Optionally busy wait - until the repository updates are complete. - \param force whether we should run an update regardless of the normal update cycle. Defaults to false. - \param wait whether we should busy wait for the updates to be performed. Defaults to false. - */ - - /*! \brief Check if an installation job for a given add-on is already queued up - * \param ID The ID of the add-on - * \return true if a job exists, false otherwise - */ - bool HasJob(const std::string& ID) const; - - /*! \brief Fetch the last repository update time. - \return the last time a repository was updated. - */ - CDateTime LastRepoUpdate() const; - void UpdateRepos(bool force = false, bool wait = false); - - void OnJobComplete(unsigned int jobID, bool success, CJob* job); - void OnJobProgress(unsigned int jobID, unsigned int progress, unsigned int total, const CJob *job); - - class CDownloadJob - { - public: - CDownloadJob(unsigned int id) - { - jobID = id; - progress = 0; - } - unsigned int jobID; - unsigned int progress; - }; - - typedef std::map JobMap; - -private: - // private construction, and no assignements; use the provided singleton methods - CAddonInstaller(); - CAddonInstaller(const CAddonInstaller&); - CAddonInstaller const& operator=(CAddonInstaller const&); - virtual ~CAddonInstaller(); - - /*! \brief Install an addon from a repository or zip - \param addon the AddonPtr describing the addon - \param hash the hash to verify the install. Defaults to "". - \param update whether this is an update of an existing addon, or a new install. Defaults to false. - \param referer string to use for referer for http fetch. Defaults to "". - \param background whether to install in the background or not. Defaults to true. - \return true on successful install, false on failure. - */ - bool DoInstall(const ADDON::AddonPtr &addon, const std::string &hash = "", bool update = false, const std::string &referer = "", bool background = true, bool modal = false); - - /*! \brief Check whether dependencies of an addon exist or are installable. - Iterates through the addon's dependencies, checking they're installed or installable. - Each dependency must also satisfies CheckDependencies in turn. - \param addon the addon to check - \param preDeps previous dependencies encountered during recursion. aids in avoiding infinite recursion - \param database database instance to update - \return true if dependencies are available, false otherwise. - */ - bool CheckDependencies(const ADDON::AddonPtr &addon, std::vector& preDeps, CAddonDatabase &database); - - void PrunePackageCache(); - int64_t EnumeratePackageFolder(std::map& result); - - CCriticalSection m_critSection; - JobMap m_downloadJobs; - CStopWatch m_repoUpdateWatch; ///< repository updates are done based on this counter - unsigned int m_repoUpdateJob; ///< the job ID of the repository updates - CEvent m_repoUpdateDone; ///< event set when the repository updates are complete -}; - -class CAddonInstallJob : public CFileOperationJob -{ -public: - CAddonInstallJob(const ADDON::AddonPtr &addon, const std::string &hash = "", bool update = false, const std::string &referer = ""); - - virtual bool DoWork(); - - /*! \brief return the id of the addon being installed - \return id of the installing addon - */ - std::string AddonID() const; - - /*! \brief Find which repository hosts an add-on - * \param addon The add-on to find the repository for - * \return The hosting repository - */ - static ADDON::AddonPtr GetRepoForAddon(const ADDON::AddonPtr& addon); - - /*! \brief Find the add-on and itshash for the given add-on ID - * \param addonID ID of the add-on to find - * \param addon Add-on with the given add-on ID - * \param hash Hash of the add-on - * \return True if the add-on and its hash were found, false otherwise. - */ - static bool GetAddonWithHash(const std::string& addonID, ADDON::AddonPtr& addon, std::string& hash); - -private: - bool OnPreInstall(); - void OnPostInstall(bool reloadAddon); - bool Install(const std::string &installFrom, const ADDON::AddonPtr& repo = ADDON::AddonPtr()); - bool DownloadPackage(const std::string &path, const std::string &dest); - - /*! \brief Delete an addon following install failure - \param addonFolder - the folder to delete - */ - bool DeleteAddon(const std::string &addonFolder); - - bool DoFileOperation(FileAction action, CFileItemList &items, const std::string &file, bool useSameJob = true); - - /*! \brief Queue a notification for addon installation/update failure - \param addonID - addon id - \param fileName - filename which is shown in case the addon id is unknown - \param message - error message to be displayed - */ - void ReportInstallError(const std::string& addonID, const std::string& fileName, const std::string& message = ""); - - ADDON::AddonPtr m_addon; - std::string m_hash; - bool m_update; - std::string m_referer; -}; - -class CAddonUnInstallJob : public CFileOperationJob -{ -public: - CAddonUnInstallJob(const ADDON::AddonPtr &addon); - - virtual bool DoWork(); - -private: - /*! \brief Delete an addon following install failure - \param addonFolder - the folder to delete - */ - bool DeleteAddon(const std::string &addonFolder); - - void OnPostUnInstall(); - - ADDON::AddonPtr m_addon; -}; diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp deleted file mode 100644 index 9ab5c31..0000000 --- a/xbmc/addons/AddonManager.cpp +++ /dev/null @@ -1,1030 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "AddonManager.h" -#include "Addon.h" -#include "AudioEncoder.h" -#include "DllLibCPluff.h" -#include "utils/StringUtils.h" -#include "utils/JobManager.h" -#include "threads/SingleLock.h" -#include "FileItem.h" -#include "LangInfo.h" -#include "settings/AdvancedSettings.h" -#include "settings/Settings.h" -#include "utils/log.h" -#include "utils/XBMCTinyXML.h" -#ifdef HAS_VISUALISATION -#include "Visualisation.h" -#endif -#ifdef HAS_SCREENSAVER -#include "ScreenSaver.h" -#endif -#ifdef HAS_PVRCLIENTS -#include "DllPVRClient.h" -#include "pvr/addons/PVRClient.h" -#endif -//#ifdef HAS_SCRAPERS -#include "Scraper.h" -//#endif -#include "PluginSource.h" -#include "Repository.h" -#include "Skin.h" -#include "Service.h" -#include "ContextItemAddon.h" -#include "Util.h" -#include "addons/Webinterface.h" - -using namespace std; -using namespace XFILE; - -namespace ADDON -{ - -cp_log_severity_t clog_to_cp(int lvl); -void cp_fatalErrorHandler(const char *msg); -void cp_logger(cp_log_severity_t level, const char *msg, const char *apid, void *user_data); - -/********************************************************** - * CAddonMgr - * - */ - -map CAddonMgr::m_managers; - -AddonPtr CAddonMgr::Factory(const cp_extension_t *props) -{ - if (!PlatformSupportsAddon(props->plugin)) - return AddonPtr(); - - /* Check if user directories need to be created */ - const cp_cfg_element_t *settings = GetExtElement(props->configuration, "settings"); - if (settings) - CheckUserDirs(settings); - - const TYPE type = TranslateType(props->ext_point_id); - switch (type) - { - case ADDON_PLUGIN: - case ADDON_SCRIPT: - return AddonPtr(new CPluginSource(props)); - case ADDON_SCRIPT_LIBRARY: - case ADDON_SCRIPT_LYRICS: - case ADDON_SCRIPT_MODULE: - case ADDON_SUBTITLE_MODULE: - return AddonPtr(new CAddon(props)); - case ADDON_WEB_INTERFACE: - return AddonPtr(new CWebinterface(props)); - case ADDON_SCRIPT_WEATHER: - { - // Eden (API v2.0) broke old weather add-ons - AddonPtr result(new CAddon(props)); - AddonVersion ver1 = result->GetDependencyVersion("xbmc.python"); - AddonVersion ver2 = AddonVersion("2.0"); - if (ver1 < ver2) - { - CLog::Log(LOGINFO,"%s: Weather add-ons for api < 2.0 unsupported (%s)",__FUNCTION__,result->ID().c_str()); - return AddonPtr(); - } - return result; - } - case ADDON_SERVICE: - return AddonPtr(new CService(props)); - case ADDON_SCRAPER_ALBUMS: - case ADDON_SCRAPER_ARTISTS: - case ADDON_SCRAPER_MOVIES: - case ADDON_SCRAPER_MUSICVIDEOS: - case ADDON_SCRAPER_TVSHOWS: - case ADDON_SCRAPER_LIBRARY: - return AddonPtr(new CScraper(props)); - case ADDON_VIZ: - case ADDON_SCREENSAVER: - case ADDON_PVRDLL: - case ADDON_AUDIOENCODER: - { // begin temporary platform handling for Dlls - // ideally platforms issues will be handled by C-Pluff - // this is not an attempt at a solution - std::string value; - if (type == ADDON_SCREENSAVER && 0 == strnicmp(props->plugin->identifier, "screensaver.xbmc.builtin.", 25)) - { // built in screensaver - return AddonPtr(new CAddon(props)); - } - if (type == ADDON_SCREENSAVER) - { // Python screensaver - std::string library = CAddonMgr::Get().GetExtValue(props->configuration, "@library"); - if (URIUtils::HasExtension(library, ".py")) - return AddonPtr(new CScreenSaver(props)); - } - if (type == ADDON_AUDIOENCODER && 0 == strncmp(props->plugin->identifier, - "audioencoder.xbmc.builtin.", 26)) - { // built in audio encoder - return AddonPtr(new CAudioEncoder(props)); - } - std::string tograb; -#if defined(TARGET_ANDROID) - tograb = "@library_android"; -#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) - tograb = "@library_linux"; -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - tograb = "@library_windx"; -#elif defined(TARGET_DARWIN) - tograb = "@library_osx"; -#endif - value = GetExtValue(props->plugin->extensions->configuration, tograb.c_str()); - if (value.empty()) - break; - if (type == ADDON_VIZ) - { -#if defined(HAS_VISUALISATION) - return AddonPtr(new CVisualisation(props)); -#endif - } - else if (type == ADDON_PVRDLL) - { -#ifdef HAS_PVRCLIENTS - return AddonPtr(new PVR::CPVRClient(props)); -#endif - } - else if (type == ADDON_AUDIOENCODER) - return AddonPtr(new CAudioEncoder(props)); - else - return AddonPtr(new CScreenSaver(props)); - } - case ADDON_SKIN: - return AddonPtr(new CSkinInfo(props)); - case ADDON_VIZ_LIBRARY: - return AddonPtr(new CAddonLibrary(props)); - case ADDON_REPOSITORY: - return AddonPtr(new CRepository(props)); - case ADDON_CONTEXT_ITEM: - return AddonPtr(new CContextItemAddon(props)); - default: - break; - } - return AddonPtr(); -} - -bool CAddonMgr::CheckUserDirs(const cp_cfg_element_t *settings) -{ - if (!settings) - return false; - - const cp_cfg_element_t *userdirs = GetExtElement((cp_cfg_element_t *)settings, "userdirs"); - if (!userdirs) - return false; - - ELEMENTS elements; - if (!GetExtElements((cp_cfg_element_t *)userdirs, "userdir", elements)) - return false; - - ELEMENTS::iterator itr = elements.begin(); - while (itr != elements.end()) - { - std::string path = GetExtValue(*itr++, "@path"); - if (!CDirectory::Exists(path)) - { - if (!CUtil::CreateDirectoryEx(path)) - { - CLog::Log(LOGERROR, "CAddonMgr::CheckUserDirs: Unable to create directory %s.", path.c_str()); - return false; - } - } - } - - return true; -} - -CAddonMgr::CAddonMgr() -{ - m_cpluff = NULL; -} - -CAddonMgr::~CAddonMgr() -{ - DeInit(); -} - -CAddonMgr &CAddonMgr::Get() -{ - static CAddonMgr sAddonMgr; - return sAddonMgr; -} - -IAddonMgrCallback* CAddonMgr::GetCallbackForType(TYPE type) -{ - if (m_managers.find(type) == m_managers.end()) - return NULL; - else - return m_managers[type]; -} - -bool CAddonMgr::RegisterAddonMgrCallback(const TYPE type, IAddonMgrCallback* cb) -{ - if (cb == NULL) - return false; - - m_managers.erase(type); - m_managers[type] = cb; - - return true; -} - -void CAddonMgr::UnregisterAddonMgrCallback(TYPE type) -{ - m_managers.erase(type); -} - -bool CAddonMgr::Init() -{ - m_cpluff = new DllLibCPluff; - m_cpluff->Load(); - - m_database.Open(); - - if (!m_cpluff->IsLoaded()) - { - CLog::Log(LOGERROR, "ADDONS: Fatal Error, could not load libcpluff"); - return false; - } - - m_cpluff->set_fatal_error_handler(cp_fatalErrorHandler); - - cp_status_t status; - status = m_cpluff->init(); - if (status != CP_OK) - { - CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_init() returned status: %i", status); - return false; - } - - //TODO could separate addons into different contexts - // would allow partial unloading of addon framework - m_cp_context = m_cpluff->create_context(&status); - assert(m_cp_context); - status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://home/addons").c_str()); - if (status != CP_OK) - { - CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status); - return false; - } - - status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://xbmc/addons").c_str()); - if (status != CP_OK) - { - CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status); - return false; - } - - status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://xbmcbin/addons").c_str()); - if (status != CP_OK) - { - CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status); - return false; - } - - status = m_cpluff->register_logger(m_cp_context, cp_logger, - &CAddonMgr::Get(), clog_to_cp(g_advancedSettings.m_logLevel)); - if (status != CP_OK) - { - CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_logger() returned status: %i", status); - return false; - } - - FindAddons(); - - VECADDONS repos; - if (GetAddons(ADDON_REPOSITORY, repos)) - { - VECADDONS::iterator it = repos.begin(); - for (;it != repos.end(); ++it) - CLog::Log(LOGNOTICE, "ADDONS: Using repository %s", (*it)->ID().c_str()); - } - - return true; -} - -void CAddonMgr::DeInit() -{ - if (m_cpluff) - m_cpluff->destroy(); - delete m_cpluff; - m_cpluff = NULL; - m_database.Close(); - m_disabled.clear(); -} - -bool CAddonMgr::HasAddons(const TYPE &type, bool enabled /*= true*/) -{ - // TODO: This isn't particularly efficient as we create an addon type for each addon using the Factory, just so - // we can check addon dependencies in the addon constructor. - VECADDONS addons; - return GetAddons(type, addons, enabled); -} - -bool CAddonMgr::GetAllAddons(VECADDONS &addons, bool enabled /*= true*/, bool allowRepos /* = false */) -{ - for (int i = ADDON_UNKNOWN+1; i < ADDON_MAX; ++i) - { - if (!allowRepos && ADDON_REPOSITORY == (TYPE)i) - continue; - VECADDONS temp; - if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) - addons.insert(addons.end(), temp.begin(), temp.end()); - } - return !addons.empty(); -} - -void CAddonMgr::AddToUpdateableAddons(AddonPtr &pAddon) -{ - CSingleLock lock(m_critSection); - m_updateableAddons.push_back(pAddon); -} - -void CAddonMgr::RemoveFromUpdateableAddons(AddonPtr &pAddon) -{ - CSingleLock lock(m_critSection); - VECADDONS::iterator it = std::find(m_updateableAddons.begin(), m_updateableAddons.end(), pAddon); - - if(it != m_updateableAddons.end()) - { - m_updateableAddons.erase(it); - } -} - -struct AddonIdFinder -{ - AddonIdFinder(const std::string& id) - : m_id(id) - {} - - bool operator()(const AddonPtr& addon) - { - return m_id == addon->ID(); - } - private: - std::string m_id; -}; - -bool CAddonMgr::ReloadSettings(const std::string &id) -{ - CSingleLock lock(m_critSection); - VECADDONS::iterator it = std::find_if(m_updateableAddons.begin(), m_updateableAddons.end(), AddonIdFinder(id)); - - if( it != m_updateableAddons.end()) - { - return (*it)->ReloadSettings(); - } - return false; -} - -bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool getLocalVersion /*= false*/) -{ - CSingleLock lock(m_critSection); - for (int i = ADDON_UNKNOWN+1; i < ADDON_MAX; ++i) - { - VECADDONS temp; - if (CAddonMgr::Get().GetAddons((TYPE)i, temp, true)) - { - AddonPtr repoAddon; - for (unsigned int j = 0; j < temp.size(); j++) - { - // Ignore duplicates due to add-ons with multiple extension points - bool found = false; - for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); ++addonIt) - { - if ((*addonIt)->ID() == temp[j]->ID()) - found = true; - } - - if (found || !m_database.GetAddon(temp[j]->ID(), repoAddon)) - continue; - - if (temp[j]->Version() < repoAddon->Version() && - !m_database.IsAddonBlacklisted(temp[j]->ID(), - repoAddon->Version().asString().c_str())) - { - if (getLocalVersion) - repoAddon->Props().version = temp[j]->Version(); - addons.push_back(repoAddon); - } - } - } - } - return !addons.empty(); -} - -bool CAddonMgr::HasOutdatedAddons() -{ - VECADDONS dummy; - return GetAllOutdatedAddons(dummy); -} - -bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */) -{ - CSingleLock lock(m_critSection); - addons.clear(); - if (!m_cp_context) - return false; - cp_status_t status; - int num; - std::string ext_point(TranslateType(type)); - cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num); - for(int i=0; i plugin->identifier) != enabled) - { - AddonPtr addon(Factory(props)); - if (addon) - { - if (enabled) - { - // if the addon has a running instance, grab that - AddonPtr runningAddon = addon->GetRunningInstance(); - if (runningAddon) - addon = runningAddon; - } - addons.push_back(addon); - } - } - } - m_cpluff->release_info(m_cp_context, exts); - return addons.size() > 0; -} - -bool CAddonMgr::GetAddon(const std::string &str, AddonPtr &addon, const TYPE &type/*=ADDON_UNKNOWN*/, bool enabledOnly /*= true*/) -{ - CSingleLock lock(m_critSection); - - cp_status_t status; - cp_plugin_info_t *cpaddon = m_cpluff->get_plugin_info(m_cp_context, str.c_str(), &status); - if (status == CP_OK && cpaddon) - { - addon = GetAddonFromDescriptor(cpaddon, type==ADDON_UNKNOWN?"":TranslateType(type)); - m_cpluff->release_info(m_cp_context, cpaddon); - - if (addon) - { - if (enabledOnly && IsAddonDisabled(addon->ID())) - return false; - - // if the addon has a running instance, grab that - AddonPtr runningAddon = addon->GetRunningInstance(); - if (runningAddon) - addon = runningAddon; - } - return NULL != addon.get(); - } - if (cpaddon) - m_cpluff->release_info(m_cp_context, cpaddon); - - return false; -} - -//TODO handle all 'default' cases here, not just scrapers & vizs -bool CAddonMgr::GetDefault(const TYPE &type, AddonPtr &addon) -{ - std::string setting; - switch (type) - { - case ADDON_VIZ: - setting = CSettings::Get().GetString("musicplayer.visualisation"); - break; - case ADDON_SCREENSAVER: - setting = CSettings::Get().GetString("screensaver.mode"); - break; - case ADDON_SCRAPER_ALBUMS: - setting = CSettings::Get().GetString("musiclibrary.albumsscraper"); - break; - case ADDON_SCRAPER_ARTISTS: - setting = CSettings::Get().GetString("musiclibrary.artistsscraper"); - break; - case ADDON_SCRAPER_MOVIES: - setting = CSettings::Get().GetString("scrapers.moviesdefault"); - break; - case ADDON_SCRAPER_MUSICVIDEOS: - setting = CSettings::Get().GetString("scrapers.musicvideosdefault"); - break; - case ADDON_SCRAPER_TVSHOWS: - setting = CSettings::Get().GetString("scrapers.tvshowsdefault"); - break; - case ADDON_WEB_INTERFACE: - setting = CSettings::Get().GetString("services.webskin"); - break; - default: - return false; - } - return GetAddon(setting, addon, type); -} - -bool CAddonMgr::SetDefault(const TYPE &type, const std::string &addonID) -{ - switch (type) - { - case ADDON_VIZ: - CSettings::Get().SetString("musicplayer.visualisation",addonID); - break; - case ADDON_SCREENSAVER: - CSettings::Get().SetString("screensaver.mode",addonID); - break; - case ADDON_SCRAPER_ALBUMS: - CSettings::Get().SetString("musiclibrary.albumsscraper",addonID); - break; - case ADDON_SCRAPER_ARTISTS: - CSettings::Get().SetString("musiclibrary.artistsscraper",addonID); - break; - case ADDON_SCRAPER_MOVIES: - CSettings::Get().SetString("scrapers.moviesdefault",addonID); - break; - case ADDON_SCRAPER_MUSICVIDEOS: - CSettings::Get().SetString("scrapers.musicvideosdefault",addonID); - break; - case ADDON_SCRAPER_TVSHOWS: - CSettings::Get().SetString("scrapers.tvshowsdefault",addonID); - break; - default: - return false; - } - - return true; -} - -std::string CAddonMgr::GetString(const std::string &id, const int number) -{ - AddonPtr addon; - if (GetAddon(id, addon)) - return addon->GetString(number); - - return ""; -} - -void CAddonMgr::FindAddons() -{ - { - CSingleLock lock(m_critSection); - if (m_cpluff && m_cp_context) - { - m_cpluff->scan_plugins(m_cp_context, CP_SP_UPGRADE); - SetChanged(); - } - } - NotifyObservers(ObservableMessageAddons); -} - -void CAddonMgr::RemoveAddon(const std::string& ID) -{ - if (m_cpluff && m_cp_context) - { - m_cpluff->uninstall_plugin(m_cp_context,ID.c_str()); - SetChanged(); - NotifyObservers(ObservableMessageAddons); - } -} - -bool CAddonMgr::DisableAddon(const std::string& ID, bool disable) -{ - CSingleLock lock(m_critSection); - if (m_database.DisableAddon(ID, disable)) - { - m_disabled[ID] = disable; - return true; - } - - return false; -} - -bool CAddonMgr::IsAddonDisabled(const std::string& ID) -{ - CSingleLock lock(m_critSection); - std::map::const_iterator it = m_disabled.find(ID); - if (it != m_disabled.end()) - return it->second; - - bool ret = m_database.IsAddonDisabled(ID); - m_disabled.insert(pair(ID, ret)); - - return ret; -} - -bool CAddonMgr::CanAddonBeDisabled(const std::string& ID) -{ - if (ID.empty()) - return false; - - CSingleLock lock(m_critSection); - AddonPtr localAddon; - // can't disable an addon that isn't installed - if (!IsAddonInstalled(ID, localAddon)) - return false; - - // can't disable an addon that is in use - if (localAddon->IsInUse()) - return false; - - // installed PVR addons can always be disabled - if (localAddon->Type() == ADDON_PVRDLL) - return true; - - std::string systemAddonsPath = CSpecialProtocol::TranslatePath("special://xbmc/addons"); - // can't disable system addons - if (StringUtils::StartsWith(localAddon->Path(), systemAddonsPath)) - return false; - - return true; -} - -bool CAddonMgr::IsAddonInstalled(const std::string& ID) -{ - AddonPtr tmp; - return IsAddonInstalled(ID, tmp); -} - -bool CAddonMgr::IsAddonInstalled(const std::string& ID, AddonPtr& addon) -{ - return GetAddon(ID, addon, ADDON_UNKNOWN, false); -} - -bool CAddonMgr::CanAddonBeInstalled(const std::string& ID) -{ - if (ID.empty()) - return false; - - CSingleLock lock(m_critSection); - // can't install already installed addon - if (IsAddonInstalled(ID)) - return false; - - // can't install broken addons - if (!m_database.IsAddonBroken(ID).empty()) - return false; - - return true; -} - -bool CAddonMgr::CanAddonBeInstalled(const AddonPtr& addon) -{ - if (addon == NULL) - return false; - - CSingleLock lock(m_critSection); - // can't install already installed addon - if (IsAddonInstalled(addon->ID())) - return false; - - // can't install broken addons - if (!addon->Props().broken.empty()) - return false; - - return true; -} - -std::string CAddonMgr::GetTranslatedString(const cp_cfg_element_t *root, const char *tag) -{ - if (!root) - return ""; - - const cp_cfg_element_t *eng = NULL; - for (unsigned int i = 0; i < root->num_children; i++) - { - const cp_cfg_element_t &child = root->children[i]; - if (strcmp(tag, child.name) == 0) - { // see if we have a "lang" attribute - const char *lang = m_cpluff->lookup_cfg_value((cp_cfg_element_t*)&child, "@lang"); - if (lang && 0 == strcmp(lang,g_langInfo.GetLanguageLocale().c_str())) - return child.value ? child.value : ""; - if (!lang || 0 == strcmp(lang, "en")) - eng = &child; - } - } - return (eng && eng->value) ? eng->value : ""; -} - -AddonPtr CAddonMgr::AddonFromProps(AddonProps& addonProps) -{ - switch (addonProps.type) - { - case ADDON_PLUGIN: - case ADDON_SCRIPT: - return AddonPtr(new CPluginSource(addonProps)); - case ADDON_SCRIPT_LIBRARY: - case ADDON_SCRIPT_LYRICS: - case ADDON_SCRIPT_WEATHER: - case ADDON_SCRIPT_MODULE: - case ADDON_SUBTITLE_MODULE: - return AddonPtr(new CAddon(addonProps)); - case ADDON_WEB_INTERFACE: - return AddonPtr(new CWebinterface(addonProps)); - case ADDON_SERVICE: - return AddonPtr(new CService(addonProps)); - case ADDON_SCRAPER_ALBUMS: - case ADDON_SCRAPER_ARTISTS: - case ADDON_SCRAPER_MOVIES: - case ADDON_SCRAPER_MUSICVIDEOS: - case ADDON_SCRAPER_TVSHOWS: - case ADDON_SCRAPER_LIBRARY: - return AddonPtr(new CScraper(addonProps)); - case ADDON_SKIN: - return AddonPtr(new CSkinInfo(addonProps)); -#if defined(HAS_VISUALISATION) - case ADDON_VIZ: - return AddonPtr(new CVisualisation(addonProps)); -#endif - case ADDON_SCREENSAVER: - return AddonPtr(new CScreenSaver(addonProps)); - case ADDON_VIZ_LIBRARY: - return AddonPtr(new CAddonLibrary(addonProps)); - case ADDON_PVRDLL: - return AddonPtr(new PVR::CPVRClient(addonProps)); - case ADDON_AUDIOENCODER: - return AddonPtr(new CAudioEncoder(addonProps)); - case ADDON_REPOSITORY: - return AddonPtr(new CRepository(addonProps)); - case ADDON_CONTEXT_ITEM: - return AddonPtr(new CContextItemAddon(addonProps)); - default: - break; - } - return AddonPtr(); -} - -/* - * libcpluff interaction - */ - -bool CAddonMgr::PlatformSupportsAddon(const cp_plugin_info_t *plugin) const -{ - if (!plugin || !plugin->num_extensions) - return false; - const cp_extension_t *metadata = GetExtension(plugin, "xbmc.addon.metadata"); // platforms; - if (CAddonMgr::Get().GetExtList(metadata->configuration, "platform", platforms)) - { - for (vector::const_iterator platform = platforms.begin(); platform != platforms.end(); ++platform) - { - if (*platform == "all") - return true; -#if defined(TARGET_ANDROID) - if (*platform == "android") -#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) - if (*platform == "linux") -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - if (*platform == "windx") -#elif defined(TARGET_DARWIN_OSX) -// Remove this after Frodo and add an architecture filter -// in addition to platform. -#if defined(__x86_64__) - if (*platform == "osx64" || *platform == "osx") -#else - if (*platform == "osx32" || *platform == "osx") -#endif -#elif defined(TARGET_DARWIN_IOS) - if (*platform == "ios") -#endif - return true; - } - return false; // no works for us - } - return true; // assume no is equivalent to all -} - -const cp_cfg_element_t *CAddonMgr::GetExtElement(cp_cfg_element_t *base, const char *path) -{ - const cp_cfg_element_t *element = NULL; - if (base) - element = m_cpluff->lookup_cfg_element(base, path); - return element; -} - -bool CAddonMgr::GetExtElements(cp_cfg_element_t *base, const char *path, ELEMENTS &elements) -{ - if (!base || !path) - return false; - - for (unsigned int i = 0; i < base->num_children; i++) - { - std::string temp = base->children[i].name; - if (!temp.compare(path)) - elements.push_back(&base->children[i]); - } - - return !elements.empty(); -} - -const cp_extension_t *CAddonMgr::GetExtension(const cp_plugin_info_t *props, const char *extension) const -{ - if (!props) - return NULL; - for (unsigned int i = 0; i < props->num_extensions; ++i) - { - if (0 == strcmp(props->extensions[i].ext_point_id, extension)) - return &props->extensions[i]; - } - return NULL; -} - -std::string CAddonMgr::GetExtValue(cp_cfg_element_t *base, const char *path) -{ - const char *value = ""; - if (base && (value = m_cpluff->lookup_cfg_value(base, path))) - return value; - else - return ""; -} - -bool CAddonMgr::GetExtList(cp_cfg_element_t *base, const char *path, vector &result) const -{ - result.clear(); - if (!base || !path) - return false; - const char *all = m_cpluff->lookup_cfg_value(base, path); - if (!all || *all == 0) - return false; - StringUtils::Tokenize(all, result, ' '); - return true; -} - -AddonPtr CAddonMgr::GetAddonFromDescriptor(const cp_plugin_info_t *info, - const std::string& type) -{ - if (!info) - return AddonPtr(); - - if (!info->extensions && type.empty()) - { // no extensions, so we need only the dep information - return AddonPtr(new CAddon(info)); - } - - // grab a relevant extension point, ignoring our kodi.addon.metadata extension point - for (unsigned int i = 0; i < info->num_extensions; ++i) - { - if (0 != strcmp("xbmc.addon.metadata" , info->extensions[i].ext_point_id) && //extensions[i].ext_point_id) && - (type.empty() || 0 == strcmp(type.c_str(), info->extensions[i].ext_point_id))) - { // note that Factory takes care of whether or not we have platform support - return Factory(&info->extensions[i]); - } - } - return AddonPtr(); -} - -// FIXME: This function may not be required -bool CAddonMgr::LoadAddonDescription(const std::string &path, AddonPtr &addon) -{ - cp_status_t status; - cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor(m_cp_context, CSpecialProtocol::TranslatePath(path).c_str(), &status); - if (info) - { - addon = GetAddonFromDescriptor(info); - m_cpluff->release_info(m_cp_context, info); - return NULL != addon.get(); - } - return false; -} - -bool CAddonMgr::AddonsFromRepoXML(const TiXmlElement *root, VECADDONS &addons) -{ - // create a context for these addons - cp_status_t status; - cp_context_t *context = m_cpluff->create_context(&status); - if (!root || !context) - return false; - - // each addon XML should have a UTF-8 declaration - TiXmlDeclaration decl("1.0", "UTF-8", ""); - const TiXmlElement *element = root->FirstChildElement("addon"); - while (element) - { - // dump the XML back to text - std::string xml; - xml << decl; - xml << *element; - cp_status_t status; - cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor_from_memory(context, xml.c_str(), xml.size(), &status); - if (info) - { - AddonPtr addon = GetAddonFromDescriptor(info); - if (addon.get()) - addons.push_back(addon); - m_cpluff->release_info(context, info); - } - element = element->NextSiblingElement("addon"); - } - m_cpluff->destroy_context(context); - return true; -} - -bool CAddonMgr::LoadAddonDescriptionFromMemory(const TiXmlElement *root, AddonPtr &addon) -{ - // create a context for these addons - cp_status_t status; - cp_context_t *context = m_cpluff->create_context(&status); - if (!root || !context) - return false; - - // dump the XML back to text - std::string xml; - xml << TiXmlDeclaration("1.0", "UTF-8", ""); - xml << *root; - cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor_from_memory(context, xml.c_str(), xml.size(), &status); - if (info) - { - addon = GetAddonFromDescriptor(info); - m_cpluff->release_info(context, info); - } - m_cpluff->destroy_context(context); - return addon != NULL; -} - -bool CAddonMgr::StartServices(const bool beforelogin) -{ - CLog::Log(LOGDEBUG, "ADDON: Starting service addons."); - - VECADDONS services; - if (!GetAddons(ADDON_SERVICE, services)) - return false; - - bool ret = true; - for (IVECADDONS it = services.begin(); it != services.end(); ++it) - { - std::shared_ptr service = std::dynamic_pointer_cast(*it); - if (service) - { - if ( (beforelogin && service->GetStartOption() == CService::STARTUP) - || (!beforelogin && service->GetStartOption() == CService::LOGIN) ) - ret &= service->Start(); - } - } - - return ret; -} - -void CAddonMgr::StopServices(const bool onlylogin) -{ - CLog::Log(LOGDEBUG, "ADDON: Stopping service addons."); - - VECADDONS services; - if (!GetAddons(ADDON_SERVICE, services)) - return; - - for (IVECADDONS it = services.begin(); it != services.end(); ++it) - { - std::shared_ptr service = std::dynamic_pointer_cast(*it); - if (service) - { - if ( (onlylogin && service->GetStartOption() == CService::LOGIN) - || (!onlylogin) ) - service->Stop(); - } - } -} - -int cp_to_clog(cp_log_severity_t lvl) -{ - if (lvl >= CP_LOG_ERROR) - return LOGINFO; - return LOGDEBUG; -} - -cp_log_severity_t clog_to_cp(int lvl) -{ - if (lvl >= LOG_LEVEL_DEBUG) - return CP_LOG_INFO; - return CP_LOG_ERROR; -} - -void cp_fatalErrorHandler(const char *msg) -{ - CLog::Log(LOGERROR, "ADDONS: CPluffFatalError(%s)", msg); -} - -void cp_logger(cp_log_severity_t level, const char *msg, const char *apid, void *user_data) -{ - if(!apid) - CLog::Log(cp_to_clog(level), "ADDON: cpluff: '%s'", msg); - else - CLog::Log(cp_to_clog(level), "ADDON: cpluff: '%s' reports '%s'", apid, msg); -} - -} /* namespace ADDON */ - diff --git a/xbmc/addons/AddonManager.h b/xbmc/addons/AddonManager.h deleted file mode 100644 index 8bc058d..0000000 --- a/xbmc/addons/AddonManager.h +++ /dev/null @@ -1,253 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "Addon.h" -#include "threads/CriticalSection.h" -#include "utils/Observer.h" -#include -#include -#include -#include -#include "AddonDatabase.h" - -class DllLibCPluff; -extern "C" -{ -#include "lib/cpluff/libcpluff/cpluff.h" -} - -namespace ADDON -{ - typedef std::map MAPADDONS; - typedef std::map::iterator IMAPADDONS; - typedef std::vector ELEMENTS; - - const std::string ADDON_METAFILE = "description.xml"; - const std::string ADDON_VIS_EXT = "*.vis"; - const std::string ADDON_PYTHON_EXT = "*.py"; - const std::string ADDON_SCRAPER_EXT = "*.xml"; - const std::string ADDON_SCREENSAVER_EXT = "*.xbs"; - const std::string ADDON_PVRDLL_EXT = "*.pvr"; - const std::string ADDON_DSP_AUDIO_EXT = "*.adsp"; - const std::string ADDON_VERSION_RE = "(?\\d*)\\.?(?\\d*)?\\.?(?\\d*)?\\.?(?\\d*)?"; - - /** - * Class - IAddonMgrCallback - * This callback should be inherited by any class which manages - * specific addon types. Could be mostly used for Dll addon types to handle - * cleanup before restart/removal - */ - class IAddonMgrCallback - { - public: - virtual ~IAddonMgrCallback() {}; - virtual bool RequestRestart(AddonPtr addon, bool datachanged)=0; - virtual bool RequestRemoval(AddonPtr addon)=0; - }; - - /** - * Class - CAddonMgr - * Holds references to all addons, enabled or - * otherwise. Services the generic callbacks available - * to all addon variants. - */ - class CAddonMgr : public Observable - { - public: - static CAddonMgr &Get(); - bool ReInit() { DeInit(); return Init(); } - bool Init(); - void DeInit(); - - IAddonMgrCallback* GetCallbackForType(TYPE type); - bool RegisterAddonMgrCallback(TYPE type, IAddonMgrCallback* cb); - void UnregisterAddonMgrCallback(TYPE type); - - /* Addon access */ - bool GetDefault(const TYPE &type, AddonPtr &addon); - bool SetDefault(const TYPE &type, const std::string &addonID); - /*! \brief Retrieve a specific addon (of a specific type) - \param id the id of the addon to retrieve. - \param addon [out] the retrieved addon pointer - only use if the function returns true. - \param type type of addon to retrieve - defaults to any type. - \param enabledOnly whether we only want enabled addons - set to false to allow both enabled and disabled addons - defaults to true. - \return true if an addon matching the id of the given type is available and is enabled (if enabledOnly is true). - */ - bool GetAddon(const std::string &id, AddonPtr &addon, const TYPE &type = ADDON_UNKNOWN, bool enabledOnly = true); - bool HasAddons(const TYPE &type, bool enabled = true); - bool GetAddons(const TYPE &type, VECADDONS &addons, bool enabled = true); - bool GetAllAddons(VECADDONS &addons, bool enabled = true, bool allowRepos = false); - void AddToUpdateableAddons(AddonPtr &pAddon); - void RemoveFromUpdateableAddons(AddonPtr &pAddon); - bool ReloadSettings(const std::string &id); - /*! \brief Get all addons with available updates - \param addons List to fill with all outdated addons - \param getLocalVersion Whether to get the local addon version or the addon verion from the repository - \return True if there are outdated addons otherwise false - */ - bool GetAllOutdatedAddons(VECADDONS &addons, bool getLocalVersion = false); - /*! \brief Checks if there is any addon with available updates - \return True if there are outdated addons otherwise false - */ - bool HasOutdatedAddons(); - std::string GetString(const std::string &id, const int number); - - std::string GetTranslatedString(const cp_cfg_element_t *root, const char *tag); - static AddonPtr AddonFromProps(AddonProps& props); - void FindAddons(); - void RemoveAddon(const std::string& ID); - - /* \brief Disable an addon - Triggers the database routine and saves the current addon state to cache. - \param ID id of the addon - \param disable whether to enable or disable. Defaults to true (disable) - \sa IsAddonDisabled, - */ - bool DisableAddon(const std::string& ID, bool disable = true); - - /* \brief Check whether an addon has been disabled via DisableAddon. - In case the disabled cache does not know about the current state the database routine will be used. - \param ID id of the addon - \sa DisableAddon - */ - bool IsAddonDisabled(const std::string& ID); - - /* \brief Checks whether an addon can be disabled via DisableAddon. - \param ID id of the addon - \sa DisableAddon - */ - bool CanAddonBeDisabled(const std::string& ID); - - /* \brief Checks whether an addon is installed. - \param ID id of the addon - */ - bool IsAddonInstalled(const std::string& ID); - - /* \brief Checks whether an addon is installed. - \param ID id of the addon - \param addon Installed addon - */ - bool IsAddonInstalled(const std::string& ID, AddonPtr& addon); - - /* \brief Checks whether an addon can be installed. Broken addons can't be installed. - \param ID id of the addon - */ - bool CanAddonBeInstalled(const std::string& ID); - - /* \brief Checks whether an addon can be installed. Broken addons can't be installed. - \param addon addon to be checked - */ - bool CanAddonBeInstalled(const AddonPtr& addon); - - /* libcpluff */ - std::string GetExtValue(cp_cfg_element_t *base, const char *path); - - /*! \brief Retrieve a vector of repeated elements from a given configuration element - \param base the base configuration element. - \param path the path to the configuration element from the base element. - \param result [out] returned list of elements. - \return true if the configuration element is present and the list of elements is non-empty - */ - bool GetExtElements(cp_cfg_element_t *base, const char *path, ELEMENTS &result); - - /*! \brief Retrieve a list of strings from a given configuration element - Assumes the configuration element or attribute contains a whitespace separated list of values (eg xs:list schema). - \param base the base configuration element. - \param path the path to the configuration element or attribute from the base element. - \param result [out] returned list of strings. - \return true if the configuration element is present and the list of strings is non-empty - */ - bool GetExtList(cp_cfg_element_t *base, const char *path, std::vector &result) const; - - const cp_extension_t *GetExtension(const cp_plugin_info_t *props, const char *extension) const; - - /*! \brief Load the addon in the given path - This loads the addon using c-pluff which parses the addon descriptor file. - \param path folder that contains the addon. - \param addon [out] returned addon. - \return true if addon is set, false otherwise. - */ - bool LoadAddonDescription(const std::string &path, AddonPtr &addon); - - /*! \brief Load the addon in the given in-memory xml - This loads the addon using c-pluff which parses the addon descriptor file. - \param root Root element of an XML document. - \param addon [out] returned addon. - \return true if addon is set, false otherwise. - */ - bool LoadAddonDescriptionFromMemory(const TiXmlElement *root, AddonPtr &addon); - - /*! \brief Parse a repository XML file for addons and load their descriptors - A repository XML is essentially a concatenated list of addon descriptors. - \param root Root element of an XML document. - \param addons [out] returned list of addons. - \return true if the repository XML file is parsed, false otherwise. - */ - bool AddonsFromRepoXML(const TiXmlElement *root, VECADDONS &addons); - - /*! \brief Start all services addons. - \return True is all addons are started, false otherwise - */ - bool StartServices(const bool beforelogin); - /*! \brief Stop all services addons. - */ - void StopServices(const bool onlylogin); - - private: - void LoadAddons(const std::string &path, - std::map& unresolved); - - /* libcpluff */ - const cp_cfg_element_t *GetExtElement(cp_cfg_element_t *base, const char *path); - cp_context_t *m_cp_context; - DllLibCPluff *m_cpluff; - VECADDONS m_updateableAddons; - - /*! \brief Fetch a (single) addon from a plugin descriptor. - Assumes that there is a single (non-trivial) extension point per addon. - \param info the plugin descriptor - \param type the extension point we want - \return an AddonPtr based on the descriptor. May be NULL if no suitable extension point is found. - */ - AddonPtr GetAddonFromDescriptor(const cp_plugin_info_t *info, - const std::string& type=""); - - /*! \brief Check whether this addon is supported on the current platform - \param info the plugin descriptor - \return true if the addon is supported, false otherwise. - */ - bool PlatformSupportsAddon(const cp_plugin_info_t *info) const; - - AddonPtr Factory(const cp_extension_t *props); - bool CheckUserDirs(const cp_cfg_element_t *element); - - // private construction, and no assignements; use the provided singleton methods - CAddonMgr(); - CAddonMgr(const CAddonMgr&); - CAddonMgr const& operator=(CAddonMgr const&); - virtual ~CAddonMgr(); - - std::map m_disabled; - static std::map m_managers; - CCriticalSection m_critSection; - CAddonDatabase m_database; - }; - -}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonStatusHandler.cpp b/xbmc/addons/AddonStatusHandler.cpp deleted file mode 100644 index 7bb874a..0000000 --- a/xbmc/addons/AddonStatusHandler.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "AddonStatusHandler.h" -#include "AddonManager.h" -#include "threads/SingleLock.h" -#include "ApplicationMessenger.h" -#include "guilib/GUIWindowManager.h" -#include "GUIDialogAddonSettings.h" -#include "dialogs/GUIDialogYesNo.h" -#include "dialogs/GUIDialogOK.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "settings/Settings.h" -#include "utils/log.h" -#include "utils/StringUtils.h" - -namespace ADDON -{ - -/********************************************************** - * CAddonStatusHandler - AddOn Status Report Class - * - * Used to informate the user about occurred errors and - * changes inside Add-on's, and ask him what to do. - * - */ - -CCriticalSection CAddonStatusHandler::m_critSection; - -CAddonStatusHandler::CAddonStatusHandler(const std::string &addonID, ADDON_STATUS status, std::string message, bool sameThread) - : CThread(("AddonStatus " + addonID).c_str()) -{ - if (!CAddonMgr::Get().GetAddon(addonID, m_addon)) - return; - - CLog::Log(LOGINFO, "Called Add-on status handler for '%u' of clientName:%s, clientID:%s (same Thread=%s)", status, m_addon->Name().c_str(), m_addon->ID().c_str(), sameThread ? "yes" : "no"); - - m_status = status; - m_message = message; - - if (sameThread) - { - Process(); - } - else - { - Create(true, THREAD_MINSTACKSIZE); - } -} - -CAddonStatusHandler::~CAddonStatusHandler() -{ - StopThread(); -} - -void CAddonStatusHandler::OnStartup() -{ - SetPriority(GetMinPriority()); -} - -void CAddonStatusHandler::OnExit() -{ -} - -void CAddonStatusHandler::Process() -{ - CSingleLock lock(m_critSection); - - std::string heading = StringUtils::Format("%s: %s", TranslateType(m_addon->Type(), true).c_str(), m_addon->Name().c_str()); - - /* AddOn lost connection to his backend (for ones that use Network) */ - if (m_status == ADDON_STATUS_LOST_CONNECTION) - { - if (m_addon->Type() == ADDON_PVRDLL) - { - if (!CSettings::Get().GetBool("pvrmanager.hideconnectionlostwarning")) - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, m_addon->Name().c_str(), g_localizeStrings.Get(36030)); // connection lost - // TODO handle disconnects after the add-on's been initialised - } - else - { - CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); - if (!pDialog) return; - - pDialog->SetHeading(heading); - pDialog->SetLine(1, 24070); - pDialog->SetLine(2, 24073); - - //send message and wait for user input - ThreadMessage tMsg = {TMSG_DIALOG_DOMODAL, WINDOW_DIALOG_YES_NO, g_windowManager.GetActiveWindow()}; - CApplicationMessenger::Get().SendMessage(tMsg, true); - - if (pDialog->IsConfirmed()) - CAddonMgr::Get().GetCallbackForType(m_addon->Type())->RequestRestart(m_addon, false); - } - } - /* Request to restart the AddOn and data structures need updated */ - else if (m_status == ADDON_STATUS_NEED_RESTART) - { - CGUIDialogOK* pDialog = (CGUIDialogOK*)g_windowManager.GetWindow(WINDOW_DIALOG_OK); - if (!pDialog) return; - - pDialog->SetHeading(heading); - pDialog->SetLine(1, 24074); - - //send message and wait for user input - ThreadMessage tMsg = {TMSG_DIALOG_DOMODAL, WINDOW_DIALOG_OK, g_windowManager.GetActiveWindow()}; - CApplicationMessenger::Get().SendMessage(tMsg, true); - - CAddonMgr::Get().GetCallbackForType(m_addon->Type())->RequestRestart(m_addon, true); - } - /* Some required settings are missing/invalid */ - else if ((m_status == ADDON_STATUS_NEED_SETTINGS) || (m_status == ADDON_STATUS_NEED_SAVEDSETTINGS)) - { - CGUIDialogYesNo* pDialogYesNo = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); - if (!pDialogYesNo) return; - - pDialogYesNo->SetHeading(heading); - pDialogYesNo->SetLine(1, 24070); - pDialogYesNo->SetLine(2, 24072); - pDialogYesNo->SetLine(3, m_message); - - //send message and wait for user input - ThreadMessage tMsg = {TMSG_DIALOG_DOMODAL, WINDOW_DIALOG_YES_NO, g_windowManager.GetActiveWindow()}; - CApplicationMessenger::Get().SendMessage(tMsg, true); - - if (!pDialogYesNo->IsConfirmed()) return; - - if (!m_addon->HasSettings()) - return; - - if (CGUIDialogAddonSettings::ShowAndGetInput(m_addon)) - { - //todo doesn't dialogaddonsettings save these automatically? should do - m_addon->SaveSettings(); - CAddonMgr::Get().GetCallbackForType(m_addon->Type())->RequestRestart(m_addon, true); - } - } - /* A unknown event has occurred */ - else if (m_status == ADDON_STATUS_UNKNOWN) - { - //CAddonMgr::Get().DisableAddon(m_addon->ID()); - CGUIDialogOK* pDialog = (CGUIDialogOK*)g_windowManager.GetWindow(WINDOW_DIALOG_OK); - if (!pDialog) return; - - pDialog->SetHeading(heading); - pDialog->SetLine(1, 24070); - pDialog->SetLine(2, 24071); - pDialog->SetLine(3, m_message); - - //send message and wait for user input - ThreadMessage tMsg = {TMSG_DIALOG_DOMODAL, WINDOW_DIALOG_OK, g_windowManager.GetActiveWindow()}; - CApplicationMessenger::Get().SendMessage(tMsg, true); - } -} - - -} /*namespace ADDON*/ - diff --git a/xbmc/addons/AddonStatusHandler.h b/xbmc/addons/AddonStatusHandler.h deleted file mode 100644 index c9b65bd..0000000 --- a/xbmc/addons/AddonStatusHandler.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "threads/Thread.h" -#include "IAddon.h" -#include "include/xbmc_addon_types.h" -#include "threads/CriticalSection.h" -#include - -namespace ADDON -{ - /** - * Class - CAddonStatusHandler - * Used to informate the user about occurred errors and - * changes inside Add-on's, and ask him what to do. - * It can executed in the same thread as the calling - * function or in a seperate thread. - */ - class CAddonStatusHandler : private CThread - { - public: - CAddonStatusHandler(const std::string &addonID, ADDON_STATUS status, std::string message, bool sameThread = true); - ~CAddonStatusHandler(); - - /* Thread handling */ - virtual void Process(); - virtual void OnStartup(); - virtual void OnExit(); - - private: - static CCriticalSection m_critSection; - AddonPtr m_addon; - ADDON_STATUS m_status; - std::string m_message; - }; - - -} diff --git a/xbmc/addons/AddonVersion.cpp b/xbmc/addons/AddonVersion.cpp deleted file mode 100644 index 9d5a112..0000000 --- a/xbmc/addons/AddonVersion.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include -#include -#include -#include - -#include "AddonVersion.h" -#include "utils/StringUtils.h" - -namespace ADDON -{ - AddonVersion::AddonVersion(const std::string& version) - : mEpoch(0), mUpstream(version.empty() ? "0.0.0" : version) - { - size_t pos = mUpstream.find(':'); - if (pos != std::string::npos) - { - mEpoch = strtol(mUpstream.c_str(), NULL, 10); - mUpstream.erase(0, pos+1); - } - - pos = mUpstream.find('-'); - if (pos != std::string::npos) - { - mRevision = mUpstream.substr(pos+1); - mUpstream.erase(pos); - } - } - - /**Compare two components of a Debian-style version. Return -1, 0, or 1 - * if a is less than, equal to, or greater than b, respectively. - */ - int AddonVersion::CompareComponent(const char *a, const char *b) - { - while (*a && *b) - { - while (*a && *b && !isdigit(*a) && !isdigit(*b)) - { - if (*a != *b) - { - if (*a == '~') return -1; - if (*b == '~') return 1; - return *a < *b ? -1 : 1; - } - a++; - b++; - } - if (*a && *b && (!isdigit(*a) || !isdigit(*b))) - { - if (*a == '~') return -1; - if (*b == '~') return 1; - return isdigit(*a) ? -1 : 1; - } - - char *next_a, *next_b; - long int num_a = strtol(a, &next_a, 10); - long int num_b = strtol(b, &next_b, 10); - if (num_a != num_b) - return num_a < num_b ? -1 : 1; - - a = next_a; - b = next_b; - } - if (!*a && !*b) - return 0; - if (*a) - return *a == '~' ? -1 : 1; - else - return *b == '~' ? 1 : -1; - } - - bool AddonVersion::operator<(const AddonVersion& other) const - { - if (mEpoch != other.mEpoch) - return mEpoch < other.mEpoch; - - int result = CompareComponent(mUpstream.c_str(), other.mUpstream.c_str()); - if (result) - return (result < 0); - - return (CompareComponent(mRevision.c_str(), other.mRevision.c_str()) < 0); - } - - bool AddonVersion::operator==(const AddonVersion& other) const - { - return mEpoch == other.mEpoch - && CompareComponent(mUpstream.c_str(), other.mUpstream.c_str()) == 0 - && CompareComponent(mRevision.c_str(), other.mRevision.c_str()) == 0; - } - - bool AddonVersion::empty() const - { - return mEpoch == 0 && mUpstream == "0.0.0" && mRevision.empty(); - } - - std::string AddonVersion::asString() const - { - std::string out; - if (mEpoch) - out = StringUtils::Format("%i:", mEpoch); - out += mUpstream; - if (!mRevision.empty()) - out += "-" + mRevision; - return out; - } - - bool AddonVersion::SplitFileName(std::string& ID, std::string& version, - const std::string& filename) - { - size_t dpos = filename.rfind("-"); - if (dpos == std::string::npos) - return false; - ID = filename.substr(0, dpos); - version = filename.substr(dpos + 1); - version = version.substr(0, version.size() - 4); - - return true; - } -} diff --git a/xbmc/addons/AddonVersion.h b/xbmc/addons/AddonVersion.h deleted file mode 100644 index 3c23370..0000000 --- a/xbmc/addons/AddonVersion.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include -#include - -namespace ADDON -{ - /* \brief Addon versioning using the debian versioning scheme - - AddonVersion uses debian versioning, which means in the each section of the period - separated version string, numbers are compared numerically rather than lexicographically, - thus any preceding zeros are ignored. - - i.e. 1.00 is considered the same as 1.0, and 1.01 is considered the same as 1.1. - - Further, 1.0 < 1.0.0 - - See here for more info: http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version - */ - class AddonVersion : public boost::totally_ordered { - public: - AddonVersion(const AddonVersion& other) { *this = other; } - explicit AddonVersion(const std::string& version); - virtual ~AddonVersion() {}; - - int Epoch() const { return mEpoch; } - const std::string &Upstream() const { return mUpstream; } - const std::string &Revision() const { return mRevision; } - - AddonVersion& operator=(const AddonVersion& other); - bool operator<(const AddonVersion& other) const; - bool operator==(const AddonVersion& other) const; - std::string asString() const; - bool empty() const; - - static bool SplitFileName(std::string& ID, std::string& version, - const std::string& filename); - - protected: - int mEpoch; - std::string mUpstream; - std::string mRevision; - - static int CompareComponent(const char *a, const char *b); - }; - - inline AddonVersion& AddonVersion::operator=(const AddonVersion& other) - { - mEpoch = other.mEpoch; - mUpstream = other.mUpstream; - mRevision = other.mRevision; - return *this; - } -} diff --git a/xbmc/addons/AudioEncoder.cpp b/xbmc/addons/AudioEncoder.cpp deleted file mode 100644 index 2737bba..0000000 --- a/xbmc/addons/AudioEncoder.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2013 Arne Morten Kvarving - * - * 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 - * . - * - */ -#include "AudioEncoder.h" - -namespace ADDON -{ - -CAudioEncoder::CAudioEncoder(const cp_extension_t* ext) - : AudioEncoderDll(ext), - extension(CAddonMgr::Get().GetExtValue(ext->configuration, "@extension")), - m_context(NULL) -{ -} - -AddonPtr CAudioEncoder::Clone() const -{ - // Copy constructor is generated by compiler and calls parent copy constructor - return AddonPtr(new CAudioEncoder(*this)); -} - -bool CAudioEncoder::Init(audioenc_callbacks &callbacks) -{ - if (!Initialized()) - return false; - - // create encoder instance - m_context = m_pStruct->Create(&callbacks); - if (!m_context) - return false; - - return m_pStruct->Start(m_context, - m_iInChannels, - m_iInSampleRate, - m_iInBitsPerSample, - m_strTitle.c_str(), - m_strArtist.c_str(), - m_strAlbumArtist.c_str(), - m_strAlbum.c_str(), - m_strYear.c_str(), - m_strTrack.c_str(), - m_strGenre.c_str(), - m_strComment.c_str(), - m_iTrackLength); -} - -int CAudioEncoder::Encode(int nNumBytesRead, uint8_t* pbtStream) -{ - if (!Initialized() || !m_context) - return 0; - - return m_pStruct->Encode(m_context, nNumBytesRead, pbtStream); -} - -bool CAudioEncoder::Close() -{ - if (!Initialized() || !m_context) - return false; - - if (!m_pStruct->Finish(m_context)) - return false; - - m_pStruct->Free(m_context); - m_context = NULL; - - return true; -} - -void CAudioEncoder::Destroy() -{ - AudioEncoderDll::Destroy(); -} - -} /*namespace ADDON*/ - diff --git a/xbmc/addons/AudioEncoder.h b/xbmc/addons/AudioEncoder.h deleted file mode 100644 index 3900333..0000000 --- a/xbmc/addons/AudioEncoder.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2013 Arne Morten Kvarving - * - * 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 - * . - * - */ -#pragma once - -#include "AddonDll.h" -#include "include/xbmc_audioenc_types.h" -#include "cdrip/IEncoder.h" - -typedef DllAddon DllAudioEncoder; -namespace ADDON -{ - typedef CAddonDll AudioEncoderDll; - - class CAudioEncoder : public AudioEncoderDll, public IEncoder - { - public: - CAudioEncoder(const AddonProps &props) : AudioEncoderDll(props) {}; - CAudioEncoder(const cp_extension_t *ext); - virtual ~CAudioEncoder() {} - virtual AddonPtr Clone() const; - - // Things that MUST be supplied by the child classes - bool Init(audioenc_callbacks &callbacks); - int Encode(int nNumBytesRead, uint8_t* pbtStream); - bool Close(); - void Destroy(); - - const std::string extension; - - private: - void *m_context; ///< audio encoder context - }; - -} /*namespace ADDON*/ diff --git a/xbmc/addons/ContextItemAddon.cpp b/xbmc/addons/ContextItemAddon.cpp deleted file mode 100644 index 4222936..0000000 --- a/xbmc/addons/ContextItemAddon.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2013-2015 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 - * . - * - */ - -#include "ContextItemAddon.h" -#include "AddonManager.h" -#include "ContextMenuManager.h" -#include "dialogs/GUIDialogContextMenu.h" -#include "GUIInfoManager.h" -#include "interfaces/info/InfoBool.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "video/dialogs/GUIDialogVideoInfo.h" -#include - -using namespace std; - -namespace ADDON -{ - -CContextItemAddon::CContextItemAddon(const AddonProps &props) - : CAddon(props) -{ } - -CContextItemAddon::~CContextItemAddon() -{ } - -CContextItemAddon::CContextItemAddon(const cp_extension_t *ext) - : CAddon(ext) -{ - ELEMENTS items; - if (CAddonMgr::Get().GetExtElements(ext->configuration, "item", items)) - { - cp_cfg_element_t *item = items[0]; - - m_label = CAddonMgr::Get().GetExtValue(item, "label"); - if (StringUtils::IsNaturalNumber(m_label)) - { - m_label = GetString(boost::lexical_cast(m_label.c_str())); - ClearStrings(); - } - - m_parent = CAddonMgr::Get().GetExtValue(item, "parent"); - - string visible = CAddonMgr::Get().GetExtValue(item, "visible"); - if (visible.empty()) - visible = "false"; - - m_visCondition = g_infoManager.Register(visible, 0); - } -} - -bool CContextItemAddon::OnPreInstall() -{ - return CContextMenuManager::Get().Unregister(std::dynamic_pointer_cast(shared_from_this())); -} - -void CContextItemAddon::OnPostInstall(bool restart, bool update) -{ - if (restart) - { - // need to grab the local addon so we have the correct library path to run - AddonPtr localAddon; - if (CAddonMgr::Get().GetAddon(ID(), localAddon, ADDON_CONTEXT_ITEM)) - { - ContextItemAddonPtr contextItem = std::dynamic_pointer_cast(localAddon); - if (contextItem) - CContextMenuManager::Get().Register(contextItem); - } - } -} - -void CContextItemAddon::OnPreUnInstall() -{ - CContextMenuManager::Get().Unregister(std::dynamic_pointer_cast(shared_from_this())); -} - -void CContextItemAddon::OnDisabled() -{ - CContextMenuManager::Get().Unregister(std::dynamic_pointer_cast(shared_from_this())); -} -void CContextItemAddon::OnEnabled() -{ - CContextMenuManager::Get().Register(std::dynamic_pointer_cast(shared_from_this())); -} - -bool CContextItemAddon::IsVisible(const CFileItemPtr& item) const -{ - return item && m_visCondition->Get(item.get()); -} - -} diff --git a/xbmc/addons/ContextItemAddon.h b/xbmc/addons/ContextItemAddon.h deleted file mode 100644 index 628fdcd..0000000 --- a/xbmc/addons/ContextItemAddon.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -/* - * Copyright (C) 2013-2015 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 - * . - * - */ - -#include -#include -#include "Addon.h" - -class CFileItem; -typedef std::shared_ptr CFileItemPtr; - -namespace INFO -{ - class InfoBool; - typedef std::shared_ptr InfoPtr; -} - -namespace ADDON -{ - class CContextItemAddon : public CAddon - { - public: - CContextItemAddon(const cp_extension_t *ext); - CContextItemAddon(const AddonProps &props); - virtual ~CContextItemAddon(); - - const std::string& GetLabel() const { return m_label; } - - /*! - * \brief Get the parent category of this context item. - * - * \details Returns empty string if at root level or - * CONTEXT_MENU_GROUP_MANAGE when it should be in the 'manage' submenu. - */ - const std::string& GetParent() const { return m_parent; } - - /*! - * \brief Returns true if this contex menu should be visible for given item. - */ - bool IsVisible(const CFileItemPtr& item) const; - - virtual bool OnPreInstall(); - virtual void OnPostInstall(bool restart, bool update); - virtual void OnPreUnInstall(); - virtual void OnDisabled(); - virtual void OnEnabled(); - - private: - std::string m_label; - std::string m_parent; - INFO::InfoPtr m_visCondition; - }; - - typedef std::shared_ptr ContextItemAddonPtr; -} diff --git a/xbmc/addons/DllAddon.h b/xbmc/addons/DllAddon.h deleted file mode 100644 index 3ea4e8d..0000000 --- a/xbmc/addons/DllAddon.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -/* -* Copyright (C) 2005-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 -* . -* -*/ - -#include "DynamicDll.h" -#include "addons/include/xbmc_addon_cpp_dll.h" - -template -class DllAddonInterface -{ -public: - virtual ~DllAddonInterface() {} - virtual void GetAddon(TheStruct* pAddon) =0; - virtual ADDON_STATUS Create(void *cb, Props *info) =0; - virtual void Stop() =0; - virtual void Destroy() =0; - virtual ADDON_STATUS GetStatus() =0; - virtual bool HasSettings() =0; - virtual unsigned int GetSettings(ADDON_StructSetting*** sSet)=0; - virtual void FreeSettings()=0; - virtual ADDON_STATUS SetSetting(const char *settingName, const void *settingValue) =0; - virtual void Announce(const char *flag, const char *sender, const char *message, const void *data) =0; -}; - -template -class DllAddon : public DllDynamic, public DllAddonInterface -{ -public: - DECLARE_DLL_WRAPPER_TEMPLATE(DllAddon) - DEFINE_METHOD2(ADDON_STATUS, Create, (void* p1, Props* p2)) - DEFINE_METHOD0(void, Stop) - DEFINE_METHOD0(void, Destroy) - DEFINE_METHOD0(ADDON_STATUS, GetStatus) - DEFINE_METHOD0(bool, HasSettings) - DEFINE_METHOD1(unsigned int, GetSettings, (ADDON_StructSetting ***p1)) - DEFINE_METHOD0(void, FreeSettings) - DEFINE_METHOD2(ADDON_STATUS, SetSetting, (const char *p1, const void *p2)) - DEFINE_METHOD1(void, GetAddon, (TheStruct* p1)) - DEFINE_METHOD4(void, Announce, (const char *p1, const char *p2, const char *p3, const void *p4)) - BEGIN_METHOD_RESOLVE() - RESOLVE_METHOD_RENAME(get_addon,GetAddon) - RESOLVE_METHOD_RENAME(ADDON_Create, Create) - RESOLVE_METHOD_RENAME(ADDON_Stop, Stop) - RESOLVE_METHOD_RENAME(ADDON_Destroy, Destroy) - RESOLVE_METHOD_RENAME(ADDON_GetStatus, GetStatus) - RESOLVE_METHOD_RENAME(ADDON_HasSettings, HasSettings) - RESOLVE_METHOD_RENAME(ADDON_SetSetting, SetSetting) - RESOLVE_METHOD_RENAME(ADDON_GetSettings, GetSettings) - RESOLVE_METHOD_RENAME(ADDON_FreeSettings, FreeSettings) - RESOLVE_METHOD_RENAME(ADDON_Announce, Announce) - END_METHOD_RESOLVE() -}; - diff --git a/xbmc/addons/DllLibCPluff.h b/xbmc/addons/DllLibCPluff.h deleted file mode 100644 index 6e3f03c..0000000 --- a/xbmc/addons/DllLibCPluff.h +++ /dev/null @@ -1,116 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DynamicDll.h" - -extern "C" { -#include "lib/cpluff/libcpluff/cpluff.h" -} - -class DllLibCPluffInterface -{ -public: - virtual ~DllLibCPluffInterface() {} - virtual const char *get_version(void) =0; - virtual void set_fatal_error_handler(cp_fatal_error_func_t error_handler) =0; - virtual cp_status_t init(void) =0; - virtual void destroy(void) =0; - virtual cp_context_t * create_context(cp_status_t *status) =0; - virtual void destroy_context(cp_context_t *ctx) =0; - virtual cp_status_t register_pcollection(cp_context_t *ctx, const char *dir) =0; - virtual void unregister_pcollection(cp_context_t *ctx, const char *dir) =0; - virtual void unregister_pcollections(cp_context_t *ctx) =0; - virtual cp_status_t register_logger(cp_context_t *ctx, cp_logger_func_t logger, void *user_data, cp_log_severity_t min_severity) =0; - virtual void unregister_logger(cp_context_t *ctx, cp_logger_func_t logger) =0; - virtual cp_status_t scan_plugins(cp_context_t *ctx, int flags) =0; - virtual cp_plugin_info_t * get_plugin_info(cp_context_t *ctx, const char *id, cp_status_t *status) =0; - virtual cp_plugin_info_t ** get_plugins_info(cp_context_t *ctx, cp_status_t *status, int *num) =0; - virtual cp_extension_t ** get_extensions_info(cp_context_t *ctx, const char *extpt_id, cp_status_t *status, int *num) =0; - virtual void release_info(cp_context_t *ctx, void *info) =0; - virtual cp_cfg_element_t * lookup_cfg_element(cp_cfg_element_t *base, const char *path) =0; - virtual char * lookup_cfg_value(cp_cfg_element_t *base, const char *path) =0; - virtual cp_status_t define_symbol(cp_context_t *ctx, const char *name, void *ptr) =0; - virtual void *resolve_symbol(cp_context_t *ctx, const char *id, const char *name, cp_status_t *status) =0; - virtual void release_symbol(cp_context_t *ctx, const void *ptr) =0; - virtual cp_plugin_info_t *load_plugin_descriptor(cp_context_t *ctx, const char *path, cp_status_t *status) =0; - virtual cp_plugin_info_t *load_plugin_descriptor_from_memory(cp_context_t *ctx, const char *buffer, unsigned int buffer_len, cp_status_t *status) =0; - virtual cp_status_t uninstall_plugin(cp_context_t *ctx, const char *id)=0; -}; - -class DllLibCPluff : public DllDynamic, DllLibCPluffInterface -{ - DECLARE_DLL_WRAPPER(DllLibCPluff, DLL_PATH_CPLUFF) - DEFINE_METHOD0(const char*, get_version) - DEFINE_METHOD1(void, set_fatal_error_handler, (cp_fatal_error_func_t p1)) - DEFINE_METHOD0(cp_status_t, init) - DEFINE_METHOD0(void, destroy) - DEFINE_METHOD1(cp_context_t*, create_context, (cp_status_t *p1)) - DEFINE_METHOD1(void, destroy_context, (cp_context_t *p1)) - - DEFINE_METHOD2(cp_status_t, register_pcollection, (cp_context_t *p1, const char *p2)) - DEFINE_METHOD2(void, unregister_pcollection, (cp_context_t *p1, const char *p2)) - DEFINE_METHOD1(void, unregister_pcollections, (cp_context_t *p1)) - - DEFINE_METHOD4(cp_status_t, register_logger, (cp_context_t *p1, cp_logger_func_t p2, void *p3, cp_log_severity_t p4)) - DEFINE_METHOD2(void, unregister_logger, (cp_context_t *p1, cp_logger_func_t p2)) - DEFINE_METHOD2(cp_status_t, scan_plugins, (cp_context_t *p1, int p2)) - DEFINE_METHOD3(cp_plugin_info_t*, get_plugin_info, (cp_context_t *p1, const char *p2, cp_status_t *p3)) - DEFINE_METHOD3(cp_plugin_info_t**, get_plugins_info, (cp_context_t *p1, cp_status_t *p2, int *p3)) - DEFINE_METHOD4(cp_extension_t**, get_extensions_info, (cp_context_t *p1, const char *p2, cp_status_t *p3, int *p4)) - DEFINE_METHOD2(void, release_info, (cp_context_t *p1, void *p2)) - - DEFINE_METHOD2(cp_cfg_element_t*, lookup_cfg_element, (cp_cfg_element_t *p1, const char *p2)) - DEFINE_METHOD2(char*, lookup_cfg_value, (cp_cfg_element_t *p1, const char *p2)) - - DEFINE_METHOD3(cp_status_t, define_symbol, (cp_context_t *p1, const char *p2, void *p3)) - DEFINE_METHOD4(void*, resolve_symbol, (cp_context_t *p1, const char *p2, const char *p3, cp_status_t *p4)) - DEFINE_METHOD2(void, release_symbol, (cp_context_t *p1, const void *p2)) - DEFINE_METHOD3(cp_plugin_info_t*, load_plugin_descriptor, (cp_context_t *p1, const char *p2, cp_status_t *p3)) - DEFINE_METHOD4(cp_plugin_info_t*, load_plugin_descriptor_from_memory, (cp_context_t *p1, const char *p2, unsigned int p3, cp_status_t *p4)) - DEFINE_METHOD2(cp_status_t, uninstall_plugin, (cp_context_t *p1, const char *p2)) - - BEGIN_METHOD_RESOLVE() - RESOLVE_METHOD_RENAME(cp_get_version, get_version) - RESOLVE_METHOD_RENAME(cp_set_fatal_error_handler, set_fatal_error_handler) - RESOLVE_METHOD_RENAME(cp_init, init) - RESOLVE_METHOD_RENAME(cp_destroy, destroy) - RESOLVE_METHOD_RENAME(cp_create_context, create_context) - RESOLVE_METHOD_RENAME(cp_destroy_context, destroy_context) - RESOLVE_METHOD_RENAME(cp_register_pcollection, register_pcollection) - RESOLVE_METHOD_RENAME(cp_unregister_pcollection, unregister_pcollection) - RESOLVE_METHOD_RENAME(cp_unregister_pcollections, unregister_pcollections) - RESOLVE_METHOD_RENAME(cp_register_logger, register_logger) - RESOLVE_METHOD_RENAME(cp_unregister_logger, unregister_logger) - RESOLVE_METHOD_RENAME(cp_scan_plugins, scan_plugins) - RESOLVE_METHOD_RENAME(cp_get_plugin_info, get_plugin_info) - RESOLVE_METHOD_RENAME(cp_get_plugins_info, get_plugins_info) - RESOLVE_METHOD_RENAME(cp_get_extensions_info, get_extensions_info) - RESOLVE_METHOD_RENAME(cp_release_info, release_info) - RESOLVE_METHOD_RENAME(cp_lookup_cfg_element, lookup_cfg_element) - RESOLVE_METHOD_RENAME(cp_lookup_cfg_value, lookup_cfg_value) - RESOLVE_METHOD_RENAME(cp_define_symbol, define_symbol) - RESOLVE_METHOD_RENAME(cp_resolve_symbol, resolve_symbol) - RESOLVE_METHOD_RENAME(cp_release_symbol, release_symbol) - RESOLVE_METHOD_RENAME(cp_load_plugin_descriptor, load_plugin_descriptor) - RESOLVE_METHOD_RENAME(cp_load_plugin_descriptor_from_memory, load_plugin_descriptor_from_memory) - RESOLVE_METHOD_RENAME(cp_uninstall_plugin, uninstall_plugin) - END_METHOD_RESOLVE() -}; diff --git a/xbmc/addons/DllPVRClient.h b/xbmc/addons/DllPVRClient.h deleted file mode 100644 index 7948858..0000000 --- a/xbmc/addons/DllPVRClient.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "DllAddon.h" -#include "include/xbmc_pvr_types.h" - -class DllPVRClient : public DllAddon -{ - // this is populated via Macro calls in DllAddon.h -}; - diff --git a/xbmc/addons/GUIDialogAddonInfo.cpp b/xbmc/addons/GUIDialogAddonInfo.cpp deleted file mode 100644 index fe3484f..0000000 --- a/xbmc/addons/GUIDialogAddonInfo.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "GUIDialogAddonInfo.h" -#include "dialogs/GUIDialogYesNo.h" -#include "dialogs/GUIDialogOK.h" -#include "addons/AddonManager.h" -#include "AddonDatabase.h" -#include "FileItem.h" -#include "filesystem/Directory.h" -#include "filesystem/SpecialProtocol.h" -#include "GUIDialogAddonSettings.h" -#include "dialogs/GUIDialogContextMenu.h" -#include "dialogs/GUIDialogTextViewer.h" -#include "GUIUserMessages.h" -#include "guilib/GUIWindowManager.h" -#include "input/Key.h" -#include "utils/JobManager.h" -#include "utils/FileOperationJob.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" -#include "utils/log.h" -#include "addons/AddonInstaller.h" -#include "pvr/PVRManager.h" -#include "Util.h" -#include "interfaces/Builtins.h" - -#define CONTROL_BTN_INSTALL 6 -#define CONTROL_BTN_ENABLE 7 -#define CONTROL_BTN_UPDATE 8 -#define CONTROL_BTN_SETTINGS 9 -#define CONTROL_BTN_CHANGELOG 10 -#define CONTROL_BTN_ROLLBACK 11 -#define CONTROL_BTN_SELECT 12 - -using namespace std; -using namespace ADDON; -using namespace XFILE; - -CGUIDialogAddonInfo::CGUIDialogAddonInfo(void) - : CGUIDialog(WINDOW_DIALOG_ADDON_INFO, "DialogAddonInfo.xml"), m_jobid(0) -{ - m_item = CFileItemPtr(new CFileItem); - m_loadType = KEEP_IN_MEMORY; -} - -CGUIDialogAddonInfo::~CGUIDialogAddonInfo(void) -{ -} - -bool CGUIDialogAddonInfo::OnMessage(CGUIMessage& message) -{ - switch ( message.GetMessage() ) - { - case GUI_MSG_WINDOW_DEINIT: - { - if (m_jobid) - CJobManager::GetInstance().CancelJob(m_jobid); - } - break; - - case GUI_MSG_CLICKED: - { - int iControl = message.GetSenderId(); - if (iControl == CONTROL_BTN_UPDATE) - { - OnUpdate(); - return true; - } - if (iControl == CONTROL_BTN_INSTALL) - { - if (!m_localAddon) - { - OnInstall(); - return true; - } - else - { - OnUninstall(); - return true; - } - } - else if (iControl == CONTROL_BTN_SELECT) - { - OnLaunch(); - return true; - } - else if (iControl == CONTROL_BTN_ENABLE) - { - OnEnable(!m_item->GetProperty("Addon.Enabled").asBoolean()); - return true; - } - else if (iControl == CONTROL_BTN_SETTINGS) - { - OnSettings(); - return true; - } - else if (iControl == CONTROL_BTN_CHANGELOG) - { - OnChangeLog(); - return true; - } - else if (iControl == CONTROL_BTN_ROLLBACK) - { - OnRollback(); - return true; - } - } - break; -default: - break; - } - - return CGUIDialog::OnMessage(message); -} - -bool CGUIDialogAddonInfo::OnAction(const CAction &action) -{ - if (action.GetID() == ACTION_SHOW_INFO) - { - Close(); - return true; - } - return CGUIDialog::OnAction(action); -} - -void CGUIDialogAddonInfo::OnInitWindow() -{ - UpdateControls(); - CGUIDialog::OnInitWindow(); - m_changelog = false; -} - -void CGUIDialogAddonInfo::UpdateControls() -{ - bool isInstalled = NULL != m_localAddon.get(); - bool isEnabled = isInstalled && m_item->GetProperty("Addon.Enabled").asBoolean(); - bool isUpdatable = isInstalled && m_item->GetProperty("Addon.UpdateAvail").asBoolean(); - bool isExecutable = isInstalled && (m_localAddon->Type() == ADDON_PLUGIN || m_localAddon->Type() == ADDON_SCRIPT); - if (isInstalled) - GrabRollbackVersions(); - - bool canDisable = isInstalled && CAddonMgr::Get().CanAddonBeDisabled(m_localAddon->ID()); - bool canInstall = !isInstalled && m_item->GetProperty("Addon.Broken").empty(); - bool isRepo = (isInstalled && m_localAddon->Type() == ADDON_REPOSITORY) || (m_addon && m_addon->Type() == ADDON_REPOSITORY); - - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_INSTALL, canDisable || canInstall); - SET_CONTROL_LABEL(CONTROL_BTN_INSTALL, isInstalled ? 24037 : 24038); - - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_ENABLE, canDisable); - SET_CONTROL_LABEL(CONTROL_BTN_ENABLE, isEnabled ? 24021 : 24022); - - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_UPDATE, isUpdatable); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SETTINGS, isInstalled && m_localAddon->HasSettings()); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SELECT, isExecutable); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_CHANGELOG, !isRepo); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_ROLLBACK, m_rollbackVersions.size() > 1); -} - -void CGUIDialogAddonInfo::OnUpdate() -{ - std::string referer = StringUtils::Format("Referer=%s-%s.zip",m_localAddon->ID().c_str(),m_localAddon->Version().asString().c_str()); - CAddonInstaller::Get().Install(m_addon->ID(), true, referer); // force install - Close(); -} - -void CGUIDialogAddonInfo::OnInstall() -{ - CAddonInstaller::Get().Install(m_addon->ID()); - Close(); -} - -void CGUIDialogAddonInfo::OnLaunch() -{ - if (!m_localAddon) - return; - - CBuiltins::Execute("RunAddon(" + m_localAddon->ID() + ")"); - Close(); -} - -bool CGUIDialogAddonInfo::PromptIfDependency(int heading, int line2) -{ - if (!m_localAddon) - return false; - - VECADDONS addons; - vector deps; - CAddonMgr::Get().GetAllAddons(addons); - for (VECADDONS::const_iterator it = addons.begin(); - it != addons.end();++it) - { - ADDONDEPS::const_iterator i = (*it)->GetDeps().find(m_localAddon->ID()); - if (i != (*it)->GetDeps().end() && !i->second.second) // non-optional dependency - deps.push_back((*it)->Name()); - } - - if (!deps.empty()) - { - string line0 = StringUtils::Format(g_localizeStrings.Get(24046).c_str(), m_localAddon->Name().c_str()); - string line1 = StringUtils::Join(deps, ", "); - CGUIDialogOK::ShowAndGetInput(heading, line0, line1, line2); - return true; - } - return false; -} - -void CGUIDialogAddonInfo::OnUninstall() -{ - if (!m_localAddon.get()) - return; - - if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) - return; - - // ensure the addon is not a dependency of other installed addons - if (PromptIfDependency(24037, 24047)) - return; - - // prompt user to be sure - if (!CGUIDialogYesNo::ShowAndGetInput(24037, 750, 0, 0)) - return; - - // ensure the addon isn't disabled in our database - CAddonMgr::Get().DisableAddon(m_localAddon->ID(), false); - - CJobManager::GetInstance().AddJob(new CAddonUnInstallJob(m_localAddon), - &CAddonInstaller::Get()); - CAddonMgr::Get().RemoveAddon(m_localAddon->ID()); - Close(); -} - -void CGUIDialogAddonInfo::OnEnable(bool enable) -{ - if (!m_localAddon.get()) - return; - - if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) - return; - - if (!enable && PromptIfDependency(24075, 24091)) - return; - - CAddonMgr::Get().DisableAddon(m_localAddon->ID(), !enable); - SetItem(m_item); - UpdateControls(); - g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); -} - -void CGUIDialogAddonInfo::OnSettings() -{ - CGUIDialogAddonSettings::ShowAndGetInput(m_localAddon); -} - -void CGUIDialogAddonInfo::OnChangeLog() -{ - CGUIDialogTextViewer* pDlgInfo = (CGUIDialogTextViewer*)g_windowManager.GetWindow(WINDOW_DIALOG_TEXT_VIEWER); - std::string name; - if (m_addon) - name = m_addon->Name(); - else if (m_localAddon) - name = m_localAddon->Name(); - pDlgInfo->SetHeading(g_localizeStrings.Get(24054)+" - "+name); - if (m_item->GetProperty("Addon.Changelog").empty()) - { - pDlgInfo->SetText(g_localizeStrings.Get(13413)); - CFileItemList items; - if (m_localAddon && - !m_item->GetProperty("Addon.UpdateAvail").asBoolean()) - { - items.Add(CFileItemPtr(new CFileItem(m_localAddon->ChangeLog(),false))); - } - else - items.Add(CFileItemPtr(new CFileItem(m_addon->ChangeLog(),false))); - items[0]->Select(true); - m_jobid = CJobManager::GetInstance().AddJob( - new CFileOperationJob(CFileOperationJob::ActionCopy,items, - "special://temp/"),this); - } - else - pDlgInfo->SetText(m_item->GetProperty("Addon.Changelog").asString()); - - m_changelog = true; - pDlgInfo->DoModal(); - m_changelog = false; -} - -void CGUIDialogAddonInfo::OnRollback() -{ - if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) - return; - - CGUIDialogContextMenu* dlg = (CGUIDialogContextMenu*)g_windowManager.GetWindow(WINDOW_DIALOG_CONTEXT_MENU); - CAddonDatabase database; - database.Open(); - - CContextButtons buttons; - for (unsigned int i=0;iVersion().asString()) - label += " "+g_localizeStrings.Get(24094); - if (database.IsAddonBlacklisted(m_localAddon->ID(),label)) - label += " "+g_localizeStrings.Get(24095); - - buttons.Add(i,label); - } - int choice; - if ((choice=dlg->ShowAndGetChoice(buttons)) > -1) - { - // blacklist everything newer - for (unsigned int j=choice+1;jID(),m_rollbackVersions[j]); - std::string path = "special://home/addons/packages/"; - path += m_localAddon->ID()+"-"+m_rollbackVersions[choice]+".zip"; - // needed as cpluff won't downgrade - if (!m_localAddon->IsType(ADDON_SERVICE)) - //we will handle this for service addons in CAddonInstallJob::OnPostInstall - CAddonMgr::Get().RemoveAddon(m_localAddon->ID()); - CAddonInstaller::Get().InstallFromZip(path); - database.RemoveAddonFromBlacklist(m_localAddon->ID(),m_rollbackVersions[choice]); - Close(); - } -} - -bool CGUIDialogAddonInfo::ShowForItem(const CFileItemPtr& item) -{ - CGUIDialogAddonInfo* dialog = (CGUIDialogAddonInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_ADDON_INFO); - if (!dialog) - return false; - if (!dialog->SetItem(item)) - return false; - - dialog->DoModal(); - return true; -} - -bool CGUIDialogAddonInfo::SetItem(const CFileItemPtr& item) -{ - *m_item = *item; - m_rollbackVersions.clear(); - - // grab the local addon, if it's available - m_localAddon.reset(); - m_addon.reset(); - if (CAddonMgr::Get().GetAddon(item->GetProperty("Addon.ID").asString(), m_localAddon)) // sets m_localAddon if installed regardless of enabled state - m_item->SetProperty("Addon.Enabled", "true"); - else - m_item->SetProperty("Addon.Enabled", "false"); - m_item->SetProperty("Addon.Installed", m_localAddon ? "true" : "false"); - - CAddonDatabase database; - database.Open(); - database.GetAddon(item->GetProperty("Addon.ID").asString(),m_addon); - - if (TranslateType(item->GetProperty("Addon.intType").asString()) == ADDON_REPOSITORY) - { - CAddonDatabase database; - database.Open(); - VECADDONS addons; - if (m_addon) - database.GetRepository(m_addon->ID(), addons); - else if (m_localAddon) // sanity - database.GetRepository(m_localAddon->ID(), addons); - int tot=0; - for (int i = ADDON_UNKNOWN+1;iType() == (TYPE)i) - ++num; - } - m_item->SetProperty("Repo." + TranslateType((TYPE)i), num); - tot += num; - } - m_item->SetProperty("Repo.Addons", tot); - } - return true; -} - -void CGUIDialogAddonInfo::OnJobComplete(unsigned int jobID, bool success, - CJob* job) -{ - if (!m_changelog) - return; - - CGUIDialogTextViewer* pDlgInfo = (CGUIDialogTextViewer*)g_windowManager.GetWindow(WINDOW_DIALOG_TEXT_VIEWER); - - m_jobid = 0; - if (!success) - { - pDlgInfo->SetText(g_localizeStrings.Get(195)); - } - else - { - CFile file; - XFILE::auto_buffer buf; - if (file.LoadFile("special://temp/" + - URIUtils::GetFileName(((CFileOperationJob*)job)->GetItems()[0]->GetPath()), buf) > 0) - { - std::string str(buf.get(), buf.length()); - m_item->SetProperty("Addon.Changelog", str); - pDlgInfo->SetText(str); - } - } - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, WINDOW_DIALOG_TEXT_VIEWER, 0, GUI_MSG_UPDATE); - g_windowManager.SendThreadMessage(msg); -} - -void CGUIDialogAddonInfo::GrabRollbackVersions() -{ - CFileItemList items; - XFILE::CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS); - items.Sort(SortByLabel, SortOrderAscending); - CAddonDatabase db; - db.Open(); - for (int i=0;im_bIsFolder) - continue; - std::string ID, version; - AddonVersion::SplitFileName(ID,version,items[i]->GetLabel()); - if (ID == m_localAddon->ID()) - { - std::string hash, path(items[i]->GetPath()); - if (db.GetPackageHash(m_localAddon->ID(), path, hash)) - { - std::string md5 = CUtil::GetFileMD5(path); - if (md5 == hash) - m_rollbackVersions.push_back(version); - else /* The package has been corrupted */ - { - CLog::Log(LOGWARNING, "%s: Removing corrupt addon package %s.", __FUNCTION__, path.c_str()); - CFile::Delete(path); - db.RemovePackage(path); - } - } - } - } -} diff --git a/xbmc/addons/GUIDialogAddonInfo.h b/xbmc/addons/GUIDialogAddonInfo.h deleted file mode 100644 index 53b7a27..0000000 --- a/xbmc/addons/GUIDialogAddonInfo.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "guilib/GUIDialog.h" -#include "addons/IAddon.h" -#include "utils/Job.h" - -class CGUIDialogAddonInfo : - public CGUIDialog, - public IJobCallback -{ -public: - CGUIDialogAddonInfo(void); - virtual ~CGUIDialogAddonInfo(void); - virtual bool OnMessage(CGUIMessage& message); - virtual bool OnAction(const CAction &action); - - virtual CFileItemPtr GetCurrentListItem(int offset = 0) { return m_item; } - virtual bool HasListItems() const { return true; } - - static bool ShowForItem(const CFileItemPtr& item); - - // job callback - void OnJobComplete(unsigned int jobID, bool success, CJob* job); -protected: - void OnInitWindow(); - - /*! \brief Set the item to display addon info on. - \param item to display - \return true if we can display information, false otherwise - */ - bool SetItem(const CFileItemPtr &item); - void UpdateControls(); - - void OnUpdate(); - void OnInstall(); - void OnUninstall(); - void OnEnable(bool enable); - void OnSettings(); - void OnChangeLog(); - void OnRollback(); - void OnLaunch(); - - /*! \brief check if the add-on is a dependency of others, and if so prompt the user. - \param heading the label for the heading of the prompt dialog - \param line2 the action that could not be completed. - \return true if prompted, false otherwise. - */ - bool PromptIfDependency(int heading, int line2); - - CFileItemPtr m_item; - ADDON::AddonPtr m_addon; - ADDON::AddonPtr m_localAddon; - unsigned int m_jobid; - bool m_changelog; - - // rollback data - void GrabRollbackVersions(); - std::vector m_rollbackVersions; -}; - diff --git a/xbmc/addons/GUIDialogAddonSettings.cpp b/xbmc/addons/GUIDialogAddonSettings.cpp deleted file mode 100644 index ef1c3c2..0000000 --- a/xbmc/addons/GUIDialogAddonSettings.cpp +++ /dev/null @@ -1,1200 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "GUIDialogAddonSettings.h" -#include "filesystem/PluginDirectory.h" -#include "addons/IAddon.h" -#include "addons/AddonManager.h" -#include "dialogs/GUIDialogNumeric.h" -#include "dialogs/GUIDialogFileBrowser.h" -#include "dialogs/GUIDialogOK.h" -#include "guilib/GUIControlGroupList.h" -#include "guilib/GUISettingsSliderControl.h" -#include "utils/URIUtils.h" -#include "utils/StringUtils.h" -#include "storage/MediaManager.h" -#include "guilib/GUILabelControl.h" -#include "guilib/GUIRadioButtonControl.h" -#include "guilib/GUISpinControlEx.h" -#include "guilib/GUIImage.h" -#include "input/Key.h" -#include "filesystem/Directory.h" -#include "video/VideoInfoScanner.h" -#include "addons/Scraper.h" -#include "guilib/GUIWindowManager.h" -#include "ApplicationMessenger.h" -#include "guilib/GUIKeyboardFactory.h" -#include "FileItem.h" -#include "settings/AdvancedSettings.h" -#include "settings/MediaSourceSettings.h" -#include "GUIInfoManager.h" -#include "GUIUserMessages.h" -#include "dialogs/GUIDialogSelect.h" -#include "GUIWindowAddonBrowser.h" -#include "utils/log.h" -#include "Util.h" -#include "URL.h" -#include "utils/XMLUtils.h" - -using namespace std; -using namespace ADDON; -using XFILE::CDirectory; - -#define CONTROL_SETTINGS_AREA 2 -#define CONTROL_DEFAULT_BUTTON 3 -#define CONTROL_DEFAULT_RADIOBUTTON 4 -#define CONTROL_DEFAULT_SPIN 5 -#define CONTROL_DEFAULT_SEPARATOR 6 -#define CONTROL_DEFAULT_LABEL_SEPARATOR 7 -#define CONTROL_DEFAULT_SLIDER 8 -#define CONTROL_SECTION_AREA 9 -#define CONTROL_DEFAULT_SECTION_BUTTON 13 - -#define ID_BUTTON_OK 10 -#define ID_BUTTON_CANCEL 11 -#define ID_BUTTON_DEFAULT 12 -#define CONTROL_HEADING_LABEL 20 - -#define CONTROL_START_SECTION 100 -#define CONTROL_START_SETTING 200 - -CGUIDialogAddonSettings::CGUIDialogAddonSettings() - : CGUIDialogBoxBase(WINDOW_DIALOG_ADDON_SETTINGS, "DialogAddonSettings.xml") -{ - m_currentSection = 0; - m_totalSections = 1; - m_saveToDisk = false; -} - -CGUIDialogAddonSettings::~CGUIDialogAddonSettings(void) -{ -} - -bool CGUIDialogAddonSettings::OnMessage(CGUIMessage& message) -{ - switch (message.GetMessage()) - { - case GUI_MSG_WINDOW_DEINIT: - { - FreeSections(); - } - break; - case GUI_MSG_CLICKED: - { - int iControl = message.GetSenderId(); - bool bCloseDialog = false; - - if (iControl == ID_BUTTON_DEFAULT) - SetDefaultSettings(); - else if (iControl != ID_BUTTON_OK) - bCloseDialog = ShowVirtualKeyboard(iControl); - - if (iControl == ID_BUTTON_OK || iControl == ID_BUTTON_CANCEL || bCloseDialog) - { - if (iControl == ID_BUTTON_OK || bCloseDialog) - { - m_bConfirmed = true; - SaveSettings(); - } - Close(); - return true; - } - } - break; - case GUI_MSG_FOCUSED: - { - CGUIDialogBoxBase::OnMessage(message); - int focusedControl = GetFocusedControlID(); - if (focusedControl >= CONTROL_START_SECTION && focusedControl < (int)(CONTROL_START_SECTION + m_totalSections) && - focusedControl - CONTROL_START_SECTION != (int)m_currentSection) - { // changing section - UpdateFromControls(); - m_currentSection = focusedControl - CONTROL_START_SECTION; - CreateControls(); - } - return true; - } - case GUI_MSG_SETTING_UPDATED: - { - std::string id = message.GetStringParam(0); - std::string value = message.GetStringParam(1); - m_settings[id] = value; - if (GetFocusedControl()) - { - int iControl = GetFocusedControl()->GetID(); - CreateControls(); - CGUIMessage msg(GUI_MSG_SETFOCUS,GetID(),iControl); - OnMessage(msg); - } - return true; - } - } - return CGUIDialogBoxBase::OnMessage(message); -} - -bool CGUIDialogAddonSettings::OnAction(const CAction& action) -{ - if (action.GetID() == ACTION_DELETE_ITEM) - { - CGUIControl* pControl = GetFocusedControl(); - if (pControl) - { - int iControl = pControl->GetID(); - int controlId = CONTROL_START_SETTING; - const TiXmlElement* setting = GetFirstSetting(); - UpdateFromControls(); - while (setting) - { - if (controlId == iControl) - { - const char* id = setting->Attribute("id"); - const char* value = setting->Attribute("default"); - if (id && value) - m_settings[id] = value; - CreateControls(); - CGUIMessage msg(GUI_MSG_SETFOCUS,GetID(),iControl); - OnMessage(msg); - return true; - } - setting = setting->NextSiblingElement("setting"); - controlId++; - } - } - } - return CGUIDialogBoxBase::OnAction(action); -} - -void CGUIDialogAddonSettings::OnInitWindow() -{ - m_currentSection = 0; - m_totalSections = 1; - CreateSections(); - CreateControls(); - CGUIDialogBoxBase::OnInitWindow(); -} - -// \brief Show CGUIDialogOK dialog, then wait for user to dismiss it. -bool CGUIDialogAddonSettings::ShowAndGetInput(const AddonPtr &addon, bool saveToDisk /* = true */) -{ - if (!addon) - return false; - - if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) - return false; - - bool ret(false); - if (addon->HasSettings()) - { - // Create the dialog - CGUIDialogAddonSettings* pDialog = NULL; - pDialog = (CGUIDialogAddonSettings*) g_windowManager.GetWindow(WINDOW_DIALOG_ADDON_SETTINGS); - if (!pDialog) - return false; - - // Set the heading - std::string heading = StringUtils::Format("$LOCALIZE[10004] - %s", addon->Name().c_str()); // "Settings - AddonName" - pDialog->m_strHeading = heading; - - pDialog->m_addon = addon; - pDialog->m_saveToDisk = saveToDisk; - pDialog->DoModal(); - ret = true; - } - else - { // addon does not support settings, inform user - CGUIDialogOK::ShowAndGetInput(24000,0,24030,0); - } - - return ret; -} - -bool CGUIDialogAddonSettings::ShowVirtualKeyboard(int iControl) -{ - int controlId = CONTROL_START_SETTING; - bool bCloseDialog = false; - - const TiXmlElement *setting = GetFirstSetting(); - while (setting) - { - if (controlId == iControl) - { - const CGUIControl* control = GetControl(controlId); - const std::string id = XMLUtils::GetAttribute(setting, "id"); - const std::string type = XMLUtils::GetAttribute(setting, "type"); - - //Special handling for actions: does not require id attribute. TODO: refactor me. - if (control && control->GetControlType() == CGUIControl::GUICONTROL_BUTTON && type == "action") - { - const char *option = setting->Attribute("option"); - std::string action = XMLUtils::GetAttribute(setting, "action"); - if (!action.empty()) - { - // replace $CWD with the url of plugin/script - StringUtils::Replace(action, "$CWD", m_addon->Path()); - StringUtils::Replace(action, "$ID", m_addon->ID()); - if (option) - bCloseDialog = (strcmpi(option, "close") == 0); - CApplicationMessenger::Get().ExecBuiltIn(action); - } - break; - } - - if (control && control->GetControlType() == CGUIControl::GUICONTROL_BUTTON && - !id.empty() && !type.empty()) - { - const char *option = setting->Attribute("option"); - const char *source = setting->Attribute("source"); - std::string value = m_buttonValues[id]; - std::string label = GetString(setting->Attribute("label")); - - if (type == "text") - { - // get any options - bool bHidden = false; - bool bEncoded = false; - if (option) - { - bHidden = (strstr(option, "hidden") != NULL); - bEncoded = (strstr(option, "urlencoded") != NULL); - } - if (bEncoded) - value = CURL::Decode(value); - - if (CGUIKeyboardFactory::ShowAndGetInput(value, label, true, bHidden)) - { - // if hidden hide input - if (bHidden) - { - std::string hiddenText; - hiddenText.append(value.size(), L'*'); - ((CGUIButtonControl *)control)->SetLabel2(hiddenText); - } - else - ((CGUIButtonControl*) control)->SetLabel2(value); - if (bEncoded) - value = CURL::Encode(value); - } - } - else if (type == "number" && CGUIDialogNumeric::ShowAndGetNumber(value, label)) - { - ((CGUIButtonControl*) control)->SetLabel2(value); - } - else if (type == "ipaddress" && CGUIDialogNumeric::ShowAndGetIPAddress(value, label)) - { - ((CGUIButtonControl*) control)->SetLabel2(value); - } - else if (type == "select") - { - CGUIDialogSelect *pDlg = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); - if (pDlg) - { - pDlg->SetHeading(label.c_str()); - pDlg->Reset(); - - int selected = -1; - vector valuesVec; - if (setting->Attribute("values")) - StringUtils::Tokenize(setting->Attribute("values"), valuesVec, "|"); - else if (setting->Attribute("lvalues")) - { // localize - StringUtils::Tokenize(setting->Attribute("lvalues"), valuesVec, "|"); - for (unsigned int i = 0; i < valuesVec.size(); i++) - { - if (i == (unsigned int)atoi(value.c_str())) - selected = i; - std::string localized = m_addon->GetString(atoi(valuesVec[i].c_str())); - if (localized.empty()) - localized = g_localizeStrings.Get(atoi(valuesVec[i].c_str())); - valuesVec[i] = localized; - } - } - else if (source) - { - valuesVec = GetFileEnumValues(source, XMLUtils::GetAttribute(setting, "mask"), XMLUtils::GetAttribute(setting, "option")); - } - - for (unsigned int i = 0; i < valuesVec.size(); i++) - { - pDlg->Add(valuesVec[i]); - if (selected == (int)i || (selected < 0 && StringUtils::EqualsNoCase(valuesVec[i], value))) - pDlg->SetSelected(i); // FIXME: the SetSelected() does not select "i", it always defaults to the first position - } - pDlg->DoModal(); - int iSelected = pDlg->GetSelectedLabel(); - if (iSelected >= 0) - { - if (setting->Attribute("lvalues")) - value = StringUtils::Format("%i", iSelected); - else - value = valuesVec[iSelected]; - ((CGUIButtonControl*) control)->SetLabel2(valuesVec[iSelected]); - } - } - } - else if (type == "audio" || type == "video" - || type == "image" || type == "executable" - || type == "file" || type == "folder") - { - // setup the shares - VECSOURCES *shares = NULL; - if (source && strcmpi(source, "") != 0) - shares = CMediaSourceSettings::Get().GetSources(source); - - VECSOURCES localShares; - if (!shares) - { - g_mediaManager.GetLocalDrives(localShares); - if (!source || strcmpi(source, "local") != 0) - g_mediaManager.GetNetworkLocations(localShares); - } - else // always append local drives - { - localShares = *shares; - g_mediaManager.GetLocalDrives(localShares); - } - - if (type == "folder") - { - // get any options - bool bWriteOnly = false; - if (option) - bWriteOnly = (strcmpi(option, "writeable") == 0); - - if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, label, value, bWriteOnly)) - ((CGUIButtonControl*) control)->SetLabel2(value); - } - else if (type == "image") - { - if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, label, value)) - ((CGUIButtonControl*) control)->SetLabel2(value); - } - else - { - // set the proper mask - std::string strMask; - if (setting->Attribute("mask")) - { - strMask = setting->Attribute("mask"); - // convert mask qualifiers - StringUtils::Replace(strMask, "$AUDIO", g_advancedSettings.m_musicExtensions); - StringUtils::Replace(strMask, "$VIDEO", g_advancedSettings.m_videoExtensions); - StringUtils::Replace(strMask, "$IMAGE", g_advancedSettings.m_pictureExtensions); -#if defined(_WIN32_WINNT) - StringUtils::Replace(strMask, "$EXECUTABLE", ".exe|.bat|.cmd|.py"); -#else - StringUtils::Replace(strMask, "$EXECUTABLE", ""); -#endif - } - else - { - if (type == "video") - strMask = g_advancedSettings.m_videoExtensions; - else if (type == "audio") - strMask = g_advancedSettings.m_musicExtensions; - else if (type == "executable") -#if defined(_WIN32_WINNT) - strMask = ".exe|.bat|.cmd|.py"; -#else - strMask = ""; -#endif - } - - // get any options - bool bUseThumbs = false; - bool bUseFileDirectories = false; - if (option) - { - vector options = StringUtils::Split(option, '|'); - bUseThumbs = find(options.begin(), options.end(), "usethumbs") != options.end(); - bUseFileDirectories = find(options.begin(), options.end(), "treatasfolder") != options.end(); - } - - if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, label, value, bUseThumbs, bUseFileDirectories)) - ((CGUIButtonControl*) control)->SetLabel2(value); - } - } - else if (type == "date") - { - CDateTime date; - if (!value.empty()) - date.SetFromDBDate(value); - SYSTEMTIME timedate; - date.GetAsSystemTime(timedate); - if(CGUIDialogNumeric::ShowAndGetDate(timedate, label)) - { - date = timedate; - value = date.GetAsDBDate(); - ((CGUIButtonControl*) control)->SetLabel2(value); - } - } - else if (type == "time") - { - SYSTEMTIME timedate; - if (value.size() >= 5) - { - // assumes HH:MM - timedate.wHour = atoi(value.substr(0, 2).c_str()); - timedate.wMinute = atoi(value.substr(3, 2).c_str()); - } - if (CGUIDialogNumeric::ShowAndGetTime(timedate, label)) - { - value = StringUtils::Format("%02d:%02d", timedate.wHour, timedate.wMinute); - ((CGUIButtonControl*) control)->SetLabel2(value); - } - } - else if (type == "addon") - { - const char *strType = setting->Attribute("addontype"); - if (strType) - { - vector addonTypes = StringUtils::Split(strType, ','); - vector types; - for (vector::iterator i = addonTypes.begin(); i != addonTypes.end(); ++i) - { - StringUtils::Trim(*i); - ADDON::TYPE type = TranslateType(*i); - if (type != ADDON_UNKNOWN) - types.push_back(type); - } - if (types.size() > 0) - { - const char *strMultiselect = setting->Attribute("multiselect"); - bool multiSelect = strMultiselect && strcmpi(strMultiselect, "true") == 0; - if (multiSelect) - { - // construct vector of addon IDs (IDs are comma seperated in single string) - vector addonIDs = StringUtils::Split(value, ','); - if (CGUIWindowAddonBrowser::SelectAddonID(types, addonIDs, false) == 1) - { - value = StringUtils::Join(addonIDs, ","); - ((CGUIButtonControl*) control)->SetLabel2(GetAddonNames(value)); - } - } - else // no need of string splitting/joining if we select only 1 addon - if (CGUIWindowAddonBrowser::SelectAddonID(types, value, false) == 1) - ((CGUIButtonControl*) control)->SetLabel2(GetAddonNames(value)); - } - } - } - m_buttonValues[id] = value; - break; - } - } - setting = setting->NextSiblingElement("setting"); - controlId++; - } - EnableControls(); - return bCloseDialog; -} - -void CGUIDialogAddonSettings::UpdateFromControls() -{ - int controlID = CONTROL_START_SETTING; - const TiXmlElement *setting = GetFirstSetting(); - while (setting) - { - const std::string id = XMLUtils::GetAttribute(setting, "id"); - const std::string type = XMLUtils::GetAttribute(setting, "type"); - const CGUIControl* control = GetControl(controlID++); - - if (control) - { - std::string value; - switch (control->GetControlType()) - { - case CGUIControl::GUICONTROL_BUTTON: - value = m_buttonValues[id]; - break; - case CGUIControl::GUICONTROL_RADIO: - value = ((CGUIRadioButtonControl*) control)->IsSelected() ? "true" : "false"; - break; - case CGUIControl::GUICONTROL_SPINEX: - if (type == "fileenum" || type == "labelenum") - value = ((CGUISpinControlEx*) control)->GetLabel(); - else - value = StringUtils::Format("%i", ((CGUISpinControlEx*) control)->GetValue()); - break; - case CGUIControl::GUICONTROL_SETTINGS_SLIDER: - { - std::string option = XMLUtils::GetAttribute(setting, "option"); - if (option.size() == 0 || StringUtils::EqualsNoCase(option, "float")) - value = StringUtils::Format("%f", ((CGUISettingsSliderControl *)control)->GetFloatValue()); - else - value = StringUtils::Format("%i", ((CGUISettingsSliderControl *)control)->GetIntValue()); - } - break; - default: - break; - } - m_settings[id] = value; - } - - setting = setting->NextSiblingElement("setting"); - } -} - -void CGUIDialogAddonSettings::SaveSettings(void) -{ - UpdateFromControls(); - - for (map::iterator i = m_settings.begin(); i != m_settings.end(); ++i) - m_addon->UpdateSetting(i->first, i->second); - - if (m_saveToDisk) - { - m_addon->SaveSettings(); - } -} - -void CGUIDialogAddonSettings::FreeSections() -{ - CGUIControlGroupList *group = dynamic_cast(GetControl(CONTROL_SECTION_AREA)); - if (group) - { - group->FreeResources(); - group->ClearAll(); - } - m_settings.clear(); - m_buttonValues.clear(); - FreeControls(); -} - -void CGUIDialogAddonSettings::FreeControls() -{ - // clear the category group - CGUIControlGroupList *control = dynamic_cast(GetControl(CONTROL_SETTINGS_AREA)); - if (control) - { - control->FreeResources(); - control->ClearAll(); - } -} - -void CGUIDialogAddonSettings::CreateSections() -{ - CGUIControlGroupList *group = dynamic_cast(GetControl(CONTROL_SECTION_AREA)); - CGUIButtonControl *originalButton = dynamic_cast(GetControl(CONTROL_DEFAULT_SECTION_BUTTON)); - if (!m_addon) - return; - - if (originalButton) - originalButton->SetVisible(false); - - // clear the category group - FreeSections(); - - // grab our categories - const TiXmlElement *category = m_addon->GetSettingsXML()->FirstChildElement("category"); - if (!category) // add a default one... - category = m_addon->GetSettingsXML(); - - int buttonID = CONTROL_START_SECTION; - while (category) - { // add a category - CGUIButtonControl *button = originalButton ? originalButton->Clone() : NULL; - - std::string label = GetString(category->Attribute("label")); - if (label.empty()) - label = g_localizeStrings.Get(128); - - if (buttonID >= CONTROL_START_SETTING) - { - CLog::Log(LOGERROR, "%s - cannot have more than %d categories - simplify your addon!", __FUNCTION__, CONTROL_START_SETTING - CONTROL_START_SECTION); - break; - } - - // add the category button - if (button && group) - { - button->SetID(buttonID++); - button->SetLabel(label); - button->SetVisible(true); - group->AddControl(button); - } - - // grab a local copy of all the settings in this category - const TiXmlElement *setting = category->FirstChildElement("setting"); - while (setting) - { - const std::string id = XMLUtils::GetAttribute(setting, "id"); - if (!id.empty()) - m_settings[id] = m_addon->GetSetting(id); - setting = setting->NextSiblingElement("setting"); - } - category = category->NextSiblingElement("category"); - } - m_totalSections = buttonID - CONTROL_START_SECTION; -} - -void CGUIDialogAddonSettings::CreateControls() -{ - FreeControls(); - - CGUISpinControlEx *pOriginalSpin = dynamic_cast(GetControl(CONTROL_DEFAULT_SPIN)); - CGUIRadioButtonControl *pOriginalRadioButton = dynamic_cast(GetControl(CONTROL_DEFAULT_RADIOBUTTON)); - CGUIButtonControl *pOriginalButton = dynamic_cast(GetControl(CONTROL_DEFAULT_BUTTON)); - CGUIImage *pOriginalImage = dynamic_cast(GetControl(CONTROL_DEFAULT_SEPARATOR)); - CGUILabelControl *pOriginalLabel = dynamic_cast(GetControl(CONTROL_DEFAULT_LABEL_SEPARATOR)); - CGUISettingsSliderControl *pOriginalSlider = dynamic_cast(GetControl(CONTROL_DEFAULT_SLIDER)); - - if (!m_addon || !pOriginalSpin || !pOriginalRadioButton || !pOriginalButton || !pOriginalImage - || !pOriginalLabel || !pOriginalSlider) - return; - - pOriginalSpin->SetVisible(false); - pOriginalRadioButton->SetVisible(false); - pOriginalButton->SetVisible(false); - pOriginalImage->SetVisible(false); - pOriginalLabel->SetVisible(false); - pOriginalSlider->SetVisible(false); - - CGUIControlGroupList *group = dynamic_cast(GetControl(CONTROL_SETTINGS_AREA)); - if (!group) - return; - - // set our dialog heading - SET_CONTROL_LABEL(CONTROL_HEADING_LABEL, m_strHeading); - - CGUIControl* pControl = NULL; - int controlId = CONTROL_START_SETTING; - const TiXmlElement *setting = GetFirstSetting(); - while (setting) - { - const std::string type = XMLUtils::GetAttribute(setting, "type"); - const std::string id = XMLUtils::GetAttribute(setting, "id"); - const std::string values = XMLUtils::GetAttribute(setting, "values"); - const std::string lvalues = XMLUtils::GetAttribute(setting, "lvalues"); - const std::string entries = XMLUtils::GetAttribute(setting, "entries"); - const std::string defaultVal = XMLUtils::GetAttribute(setting, "default"); - const std::string subsetting = XMLUtils::GetAttribute(setting, "subsetting"); - const std::string label = GetString(setting->Attribute("label"), subsetting == "true"); - - bool bSort = XMLUtils::GetAttribute(setting, "sort") == "yes"; - if (!type.empty()) - { - bool isAddonSetting = false; - if (type == "text" || type == "ipaddress" - || type == "number" || type == "video" - || type == "audio" || type == "image" - || type == "folder" || type == "executable" - || type == "file" || type == "action" - || type == "date" || type == "time" - || type == "select" || (isAddonSetting = type == "addon")) - { - pControl = new CGUIButtonControl(*pOriginalButton); - if (!pControl) return; - ((CGUIButtonControl *)pControl)->SetLabel(label); - if (!id.empty()) - { - std::string value = m_settings[id]; - m_buttonValues[id] = value; - // get any option to test for hidden - const std::string option = XMLUtils::GetAttribute(setting, "option"); - if (option == "urlencoded") - value = CURL::Decode(value); - else if (option == "hidden") - { - std::string hiddenText; - hiddenText.append(value.size(), L'*'); - ((CGUIButtonControl *)pControl)->SetLabel2(hiddenText); - } - else - { - if (isAddonSetting) - ((CGUIButtonControl *)pControl)->SetLabel2(GetAddonNames(value)); - else if (type == "select" && !lvalues.empty()) - { - vector valuesVec = StringUtils::Split(lvalues, '|'); - int selected = atoi(value.c_str()); - if (selected >= 0 && selected < (int)valuesVec.size()) - { - std::string label = m_addon->GetString(atoi(valuesVec[selected].c_str())); - if (label.empty()) - label = g_localizeStrings.Get(atoi(valuesVec[selected].c_str())); - ((CGUIButtonControl *)pControl)->SetLabel2(label); - } - } - else - ((CGUIButtonControl *)pControl)->SetLabel2(value); - } - } - else - ((CGUIButtonControl *)pControl)->SetLabel2(defaultVal); - } - else if (type == "bool" && !id.empty()) - { - pControl = new CGUIRadioButtonControl(*pOriginalRadioButton); - if (!pControl) return; - ((CGUIRadioButtonControl *)pControl)->SetLabel(label); - ((CGUIRadioButtonControl *)pControl)->SetSelected(m_settings[id] == "true"); - } - else if ((type == "enum" || type == "labelenum") && !id.empty()) - { - vector valuesVec; - vector entryVec; - - pControl = new CGUISpinControlEx(*pOriginalSpin); - if (!pControl) return; - ((CGUISpinControlEx *)pControl)->SetText(label); - - if (!lvalues.empty()) - StringUtils::Tokenize(lvalues, valuesVec, "|"); - else if (values == "$HOURS") - { - for (unsigned int i = 0; i < 24; i++) - { - CDateTime time(2000, 1, 1, i, 0, 0); - valuesVec.push_back(g_infoManager.LocalizeTime(time, TIME_FORMAT_HH_MM_XX)); - } - } - else - StringUtils::Tokenize(values, valuesVec, "|"); - if (!entries.empty()) - StringUtils::Tokenize(entries, entryVec, "|"); - - if(bSort && type == "labelenum") - std::sort(valuesVec.begin(), valuesVec.end(), sortstringbyname()); - - for (unsigned int i = 0; i < valuesVec.size(); i++) - { - int iAdd = i; - if (entryVec.size() > i) - iAdd = atoi(entryVec[i].c_str()); - if (!lvalues.empty()) - { - std::string replace = m_addon->GetString(atoi(valuesVec[i].c_str())); - if (replace.empty()) - replace = g_localizeStrings.Get(atoi(valuesVec[i].c_str())); - ((CGUISpinControlEx *)pControl)->AddLabel(replace, iAdd); - } - else - ((CGUISpinControlEx *)pControl)->AddLabel(valuesVec[i], iAdd); - } - if (type == "labelenum") - { // need to run through all our settings and find the one that matches - ((CGUISpinControlEx*) pControl)->SetValueFromLabel(m_settings[id]); - } - else - ((CGUISpinControlEx*) pControl)->SetValue(atoi(m_settings[id].c_str())); - - } - else if (type == "fileenum" && !id.empty()) - { - pControl = new CGUISpinControlEx(*pOriginalSpin); - if (!pControl) return; - ((CGUISpinControlEx *)pControl)->SetText(label); - ((CGUISpinControlEx *)pControl)->SetFloatValue(1.0f); - - vector items = GetFileEnumValues(values, XMLUtils::GetAttribute(setting, "mask"), XMLUtils::GetAttribute(setting, "option")); - for (unsigned int i = 0; i < items.size(); ++i) - { - ((CGUISpinControlEx *)pControl)->AddLabel(items[i], i); - if (StringUtils::EqualsNoCase(items[i], m_settings[id])) - ((CGUISpinControlEx *)pControl)->SetValue(i); - } - } - // Sample: - // in strings.xml: %2.0f mp - // creates 11 piece, text formated number labels from 0 to 100 - else if (type == "rangeofnum" && !id.empty()) - { - pControl = new CGUISpinControlEx(*pOriginalSpin); - if (!pControl) - return; - ((CGUISpinControlEx *)pControl)->SetText(label); - ((CGUISpinControlEx *)pControl)->SetFloatValue(1.0f); - - double rangestart = 0, rangeend = 1; - setting->Attribute("rangestart", &rangestart); - setting->Attribute("rangeend", &rangeend); - - int elements = 2; - setting->Attribute("elements", &elements); - - std::string valueformat; - if (setting->Attribute("valueformat")) - valueformat = m_addon->GetString(atoi(setting->Attribute("valueformat"))); - for (int i = 0; i < elements; i++) - { - std::string valuestring; - if (elements < 2) - valuestring = StringUtils::Format(valueformat.c_str(), rangestart); - else - valuestring = StringUtils::Format(valueformat.c_str(), rangestart+(rangeend-rangestart)/(elements-1)*i); - ((CGUISpinControlEx *)pControl)->AddLabel(valuestring, i); - } - ((CGUISpinControlEx *)pControl)->SetValue(atoi(m_settings[id].c_str())); - } - // Sample: - // to make ints from 5-60 with 5 steps - else if (type == "slider" && !id.empty()) - { - pControl = new CGUISettingsSliderControl(*pOriginalSlider); - if (!pControl) return; - ((CGUISettingsSliderControl *)pControl)->SetText(label); - - float fMin = 0.0f; - float fMax = 100.0f; - float fInc = 1.0f; - vector range = StringUtils::Split(XMLUtils::GetAttribute(setting, "range"), ','); - if (range.size() > 1) - { - fMin = (float)atof(range[0].c_str()); - if (range.size() > 2) - { - fMax = (float)atof(range[2].c_str()); - fInc = (float)atof(range[1].c_str()); - } - else - fMax = (float)atof(range[1].c_str()); - } - - std::string option = XMLUtils::GetAttribute(setting, "option"); - int iType=0; - - if (option.empty() || StringUtils::EqualsNoCase(option, "float")) - iType = SLIDER_CONTROL_TYPE_FLOAT; - else if (StringUtils::EqualsNoCase(option, "int")) - iType = SLIDER_CONTROL_TYPE_INT; - else if (StringUtils::EqualsNoCase(option, "percent")) - iType = SLIDER_CONTROL_TYPE_PERCENTAGE; - - ((CGUISettingsSliderControl *)pControl)->SetType(iType); - ((CGUISettingsSliderControl *)pControl)->SetFloatRange(fMin, fMax); - ((CGUISettingsSliderControl *)pControl)->SetFloatInterval(fInc); - ((CGUISettingsSliderControl *)pControl)->SetFloatValue((float)atof(m_settings[id].c_str())); - } - else if (type == "lsep") - { - pControl = new CGUILabelControl(*pOriginalLabel); - if (pControl) - ((CGUILabelControl *)pControl)->SetLabel(label); - } - else if (type == "sep") - pControl = new CGUIImage(*pOriginalImage); - } - - if (pControl) - { - pControl->SetWidth(group->GetWidth()); - pControl->SetVisible(true); - pControl->SetID(controlId); - pControl->AllocResources(); - group->AddControl(pControl); - pControl = NULL; - } - - setting = setting->NextSiblingElement("setting"); - controlId++; - } - EnableControls(); -} - -std::string CGUIDialogAddonSettings::GetAddonNames(const std::string& addonIDslist) const -{ - std::string retVal; - vector addons = StringUtils::Split(addonIDslist, ','); - for (vector::const_iterator it = addons.begin(); it != addons.end() ; ++it) - { - if (!retVal.empty()) - retVal += ", "; - AddonPtr addon; - if (CAddonMgr::Get().GetAddon(*it ,addon)) - retVal += addon->Name(); - else - retVal += *it; - } - return retVal; -} - -vector CGUIDialogAddonSettings::GetFileEnumValues(const std::string &path, const std::string &mask, const std::string &options) const -{ - // Create our base path, used for type "fileenum" settings - // replace $PROFILE with the profile path of the plugin/script - std::string fullPath = path; - if (fullPath.find("$PROFILE") != std::string::npos) - StringUtils::Replace(fullPath, "$PROFILE", m_addon->Profile()); - else - fullPath = URIUtils::AddFileToFolder(m_addon->Path(), path); - - bool hideExtensions = StringUtils::EqualsNoCase(options, "hideext"); - // fetch directory - CFileItemList items; - if (!mask.empty()) - CDirectory::GetDirectory(fullPath, items, mask, XFILE::DIR_FLAG_NO_FILE_DIRS); - else - CDirectory::GetDirectory(fullPath, items, "", XFILE::DIR_FLAG_NO_FILE_DIRS); - - vector values; - for (int i = 0; i < items.Size(); ++i) - { - CFileItemPtr pItem = items[i]; - if ((mask == "/" && pItem->m_bIsFolder) || !pItem->m_bIsFolder) - { - if (hideExtensions) - pItem->RemoveExtension(); - values.push_back(pItem->GetLabel()); - } - } - return values; -} - -// Go over all the settings and set their enabled condition according to the values of the enabled attribute -void CGUIDialogAddonSettings::EnableControls() -{ - int controlId = CONTROL_START_SETTING; - const TiXmlElement *setting = GetFirstSetting(); - while (setting) - { - const CGUIControl* control = GetControl(controlId); - if (control) - { - // set enable status - const char *enable = setting->Attribute("enable"); - if (enable) - ((CGUIControl*) control)->SetEnabled(GetCondition(enable, controlId)); - else - ((CGUIControl*) control)->SetEnabled(true); - // set visible status - const char *visible = setting->Attribute("visible"); - if (visible) - ((CGUIControl*) control)->SetVisible(GetCondition(visible, controlId)); - else - ((CGUIControl*) control)->SetVisible(true); - } - setting = setting->NextSiblingElement("setting"); - controlId++; - } -} - -bool CGUIDialogAddonSettings::GetCondition(const std::string &condition, const int controlId) -{ - if (condition.empty()) return true; - - bool bCondition = true; - bool bCompare = true; - bool bControlDependend = false;//flag if the condition depends on another control - vector conditionVec; - - if (condition.find("+") != std::string::npos) - StringUtils::Tokenize(condition, conditionVec, "+"); - else - { - bCondition = false; - bCompare = false; - StringUtils::Tokenize(condition, conditionVec, "|"); - } - - for (unsigned int i = 0; i < conditionVec.size(); i++) - { - vector condVec; - if (!TranslateSingleString(conditionVec[i], condVec)) continue; - - const CGUIControl* control2 = GetControl(controlId + atoi(condVec[1].c_str())); - if (!control2) - continue; - - bControlDependend = true; //once we are here - this condition depends on another control - - std::string value; - switch (control2->GetControlType()) - { - case CGUIControl::GUICONTROL_BUTTON: - value = ((CGUIButtonControl*) control2)->GetLabel2(); - break; - case CGUIControl::GUICONTROL_RADIO: - value = ((CGUIRadioButtonControl*) control2)->IsSelected() ? "true" : "false"; - break; - case CGUIControl::GUICONTROL_SPINEX: - if (((CGUISpinControlEx*) control2)->GetFloatValue() > 0.0f) - value = ((CGUISpinControlEx*) control2)->GetLabel(); - else - value = StringUtils::Format("%i", ((CGUISpinControlEx*) control2)->GetValue()); - break; - default: - break; - } - - if (condVec[0] == "eq") - { - if (bCompare) - bCondition &= StringUtils::EqualsNoCase(value, condVec[2]); - else - bCondition |= StringUtils::EqualsNoCase(value, condVec[2]); - } - else if (condVec[0] == "!eq") - { - if (bCompare) - bCondition &= !StringUtils::EqualsNoCase(value, condVec[2]); - else - bCondition |= !StringUtils::EqualsNoCase(value, condVec[2]); - } - else if (condVec[0] == "gt") - { - if (bCompare) - bCondition &= (atoi(value.c_str()) > atoi(condVec[2].c_str())); - else - bCondition |= (atoi(value.c_str()) > atoi(condVec[2].c_str())); - } - else if (condVec[0] == "lt") - { - if (bCompare) - bCondition &= (atoi(value.c_str()) < atoi(condVec[2].c_str())); - else - bCondition |= (atoi(value.c_str()) < atoi(condVec[2].c_str())); - } - } - - if (!bControlDependend)//if condition doesn't depend on another control - try if its an infobool expression - { - bCondition = g_infoManager.EvaluateBool(condition); - } - - return bCondition; -} - -bool CGUIDialogAddonSettings::TranslateSingleString(const std::string &strCondition, vector &condVec) -{ - std::string strTest = strCondition; - StringUtils::ToLower(strTest); - StringUtils::Trim(strTest); - - size_t pos1 = strTest.find("("); - size_t pos2 = strTest.find(",", pos1); - size_t pos3 = strTest.find(")", pos2); - if (pos1 != std::string::npos && - pos2 != std::string::npos && - pos3 != std::string::npos) - { - condVec.push_back(strTest.substr(0, pos1)); - condVec.push_back(strTest.substr(pos1 + 1, pos2 - pos1 - 1)); - condVec.push_back(strTest.substr(pos2 + 1, pos3 - pos2 - 1)); - return true; - } - return false; -} - -std::string CGUIDialogAddonSettings::GetString(const char *value, bool subSetting) const -{ - if (!value) - return ""; - std::string prefix(subSetting ? "- " : ""); - if (StringUtils::IsNaturalNumber(value)) - return prefix + m_addon->GetString(atoi(value)); - return prefix + value; -} - -// Go over all the settings and set their default values -void CGUIDialogAddonSettings::SetDefaultSettings() -{ - if(!m_addon) - return; - - const TiXmlElement *category = m_addon->GetSettingsXML()->FirstChildElement("category"); - if (!category) // add a default one... - category = m_addon->GetSettingsXML(); - - while (category) - { - const TiXmlElement *setting = category->FirstChildElement("setting"); - while (setting) - { - const std::string id = XMLUtils::GetAttribute(setting, "id"); - const std::string type = XMLUtils::GetAttribute(setting, "type"); - const char *value = setting->Attribute("default"); - if (!id.empty()) - { - if (value) - m_settings[id] = value; - else if (type == "bool") - m_settings[id] = "false"; - else if (type == "slider" || type == "enum") - m_settings[id] = "0"; - else - m_settings[id] = ""; - } - setting = setting->NextSiblingElement("setting"); - } - category = category->NextSiblingElement("category"); - } - CreateControls(); -} - -const TiXmlElement *CGUIDialogAddonSettings::GetFirstSetting() const -{ - const TiXmlElement *category = m_addon->GetSettingsXML()->FirstChildElement("category"); - if (!category) - category = m_addon->GetSettingsXML(); - for (unsigned int i = 0; i < m_currentSection && category; i++) - category = category->NextSiblingElement("category"); - if (category) - return category->FirstChildElement("setting"); - return NULL; -} - -void CGUIDialogAddonSettings::DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions) -{ - // update status of current section button - bool alphaFaded = false; - CGUIControl *control = GetFirstFocusableControl(CONTROL_START_SECTION + m_currentSection); - if (control && !control->HasFocus()) - { - if (control->GetControlType() == CGUIControl::GUICONTROL_BUTTON) - { - control->SetFocus(true); - ((CGUIButtonControl *)control)->SetAlpha(0x80); - alphaFaded = true; - } - else if (control->GetControlType() == CGUIControl::GUICONTROL_TOGGLEBUTTON) - { - control->SetFocus(true); - ((CGUIButtonControl *)control)->SetSelected(true); - alphaFaded = true; - } - } - CGUIDialogBoxBase::DoProcess(currentTime, dirtyregions); - if (alphaFaded && m_active) // dialog may close - { - control->SetFocus(false); - if (control->GetControlType() == CGUIControl::GUICONTROL_BUTTON) - ((CGUIButtonControl *)control)->SetAlpha(0xFF); - else - ((CGUIButtonControl *)control)->SetSelected(false); - } -} - -std::string CGUIDialogAddonSettings::GetCurrentID() const -{ - if (m_addon) - return m_addon->ID(); - return ""; -} - -int CGUIDialogAddonSettings::GetDefaultLabelID(int controlId) const -{ - if (controlId == ID_BUTTON_OK) - return 186; - else if (controlId == ID_BUTTON_CANCEL) - return 222; - else if (controlId == ID_BUTTON_DEFAULT) - return 409; - - return CGUIDialogBoxBase::GetDefaultLabelID(controlId); -} diff --git a/xbmc/addons/GUIDialogAddonSettings.h b/xbmc/addons/GUIDialogAddonSettings.h deleted file mode 100644 index 9c9c156..0000000 --- a/xbmc/addons/GUIDialogAddonSettings.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "dialogs/GUIDialogBoxBase.h" -#include "addons/Addon.h" - -class CGUIDialogAddonSettings : public CGUIDialogBoxBase -{ -public: - CGUIDialogAddonSettings(void); - virtual ~CGUIDialogAddonSettings(void); - virtual bool OnMessage(CGUIMessage& message); - virtual bool OnAction(const CAction& action); - /*! \brief Show the addon settings dialog, allowing the user to configure an addon - \param addon the addon to configure - \param saveToDisk whether the changes should be saved to disk or just made local to the addon. Defaults to true - \return true if settings were changed and the dialog confirmed, false otherwise. - */ - static bool ShowAndGetInput(const ADDON::AddonPtr &addon, bool saveToDisk = true); - virtual void DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions); - - std::string GetCurrentID() const; -protected: - virtual void OnInitWindow(); - virtual int GetDefaultLabelID(int controlId) const; - -private: - /*! \brief return a (localized) addon string. - \param value either a character string (which is used directly) or a number to lookup in the addons strings.xml - \param subsetting whether the character string should be prefixed by "- ", defaults to false - \return the localized addon string - */ - std::string GetString(const char *value, bool subSetting = false) const; - - /*! \brief return a the values for a fileenum setting - \param path the path to use for files - \param mask the mask to use - \param options any options, such as "hideext" to hide extensions - \return the filenames in the path that match the mask - */ - std::vector GetFileEnumValues(const std::string &path, const std::string &mask, const std::string &options) const; - - /*! \brief Translate list of addon IDs to list of addon names - \param addonIDslist comma seperated list of addon IDs - \return comma seperated list of addon names - */ - std::string GetAddonNames(const std::string& addonIDslist) const; - - void CreateSections(); - void FreeSections(); - void CreateControls(); - void FreeControls(); - void UpdateFromControls(); - void EnableControls(); - void SetDefaultSettings(); - bool GetCondition(const std::string &condition, const int controlId); - - void SaveSettings(void); - bool ShowVirtualKeyboard(int iControl); - bool TranslateSingleString(const std::string &strCondition, std::vector &enableVec); - - const TiXmlElement *GetFirstSetting() const; - - ADDON::AddonPtr m_addon; - std::map m_buttonValues; - bool m_saveToDisk; // whether the addon settings should be saved to disk or just stored locally in the addon - - unsigned int m_currentSection; - unsigned int m_totalSections; - - std::map m_settings; // local storage of values -}; - diff --git a/xbmc/addons/GUIViewStateAddonBrowser.cpp b/xbmc/addons/GUIViewStateAddonBrowser.cpp deleted file mode 100644 index 4f42b2e..0000000 --- a/xbmc/addons/GUIViewStateAddonBrowser.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "GUIViewStateAddonBrowser.h" -#include "FileItem.h" -#include "filesystem/File.h" -#include "guilib/GraphicContext.h" -#include "guilib/WindowIDs.h" -#include "view/ViewState.h" -#include "addons/Addon.h" -#include "addons/AddonManager.h" -#include "addons/AddonInstaller.h" -#include "AddonDatabase.h" -#include "utils/StringUtils.h" - -using namespace XFILE; -using namespace ADDON; - -CGUIViewStateAddonBrowser::CGUIViewStateAddonBrowser(const CFileItemList& items) : CGUIViewState(items) -{ - if (items.IsVirtualDirectoryRoot()) - { - AddSortMethod(SortByNone, 551, LABEL_MASKS("%F", "", "%L", "")); - SetSortMethod(SortByNone); - } - else - { - AddSortMethod(SortByLabel, SortAttributeIgnoreFolders, 551, LABEL_MASKS("%L", "%I", "%L", "")); // Filename, Size | Foldername, empty - AddSortMethod(SortByDate, 552, LABEL_MASKS("%L", "%J", "%L", "%J")); // Filename, Date | Foldername, Date - SetSortMethod(SortByLabel); - } - SetViewAsControl(DEFAULT_VIEW_AUTO); - - SetSortOrder(SortOrderAscending); - LoadViewState(items.GetPath(), WINDOW_ADDON_BROWSER); -} - -void CGUIViewStateAddonBrowser::SaveViewState() -{ - SaveViewToDb(m_items.GetPath(), WINDOW_ADDON_BROWSER); -} - -std::string CGUIViewStateAddonBrowser::GetExtensions() -{ - return ""; -} - -VECSOURCES& CGUIViewStateAddonBrowser::GetSources() -{ - m_sources.clear(); - - { // check for updates - CMediaSource share; - share.strPath = "addons://check/"; - share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOTE; // hack for sorting - share.strName = g_localizeStrings.Get(24055); // "Check for updates" - CDateTime lastChecked = CAddonInstaller::Get().LastRepoUpdate(); - if (lastChecked.IsValid()) - share.strStatus = StringUtils::Format(g_localizeStrings.Get(24056).c_str(), - lastChecked.GetAsLocalizedDateTime(false, false).c_str()); - m_sources.push_back(share); - } - if (CAddonMgr::Get().HasOutdatedAddons()) - { - CMediaSource share; - share.strPath = "addons://outdated/"; - share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; - share.strName = g_localizeStrings.Get(24043); // "Available updates" - m_sources.push_back(share); - } - CAddonDatabase db; - if (db.Open() && db.HasDisabledAddons()) - { - CMediaSource share; - share.strPath = "addons://disabled/"; - share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; - share.strName = g_localizeStrings.Get(24039); - m_sources.push_back(share); - } - // we always have some enabled addons - { - CMediaSource share; - share.strPath = "addons://enabled/"; - share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; - share.strName = g_localizeStrings.Get(24062); - m_sources.push_back(share); - } - if (CAddonMgr::Get().HasAddons(ADDON_REPOSITORY,true)) - { - CMediaSource share; - share.strPath = "addons://repos/"; - share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; - share.strName = g_localizeStrings.Get(24033); - m_sources.push_back(share); - } - // add "install from zip" - { - CMediaSource share; - share.strPath = "addons://install/"; - share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; - share.strName = g_localizeStrings.Get(24041); - m_sources.push_back(share); - } - // add "search" - { - CMediaSource share; - share.strPath = "addons://search/"; - share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; - share.strName = g_localizeStrings.Get(137); - m_sources.push_back(share); - } - - return CGUIViewState::GetSources(); -} - diff --git a/xbmc/addons/GUIViewStateAddonBrowser.h b/xbmc/addons/GUIViewStateAddonBrowser.h deleted file mode 100644 index 565cdc8..0000000 --- a/xbmc/addons/GUIViewStateAddonBrowser.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "view/GUIViewState.h" - -class CGUIViewStateAddonBrowser : public CGUIViewState -{ -public: - CGUIViewStateAddonBrowser(const CFileItemList& items); - -protected: - virtual void SaveViewState(); - virtual std::string GetExtensions(); - virtual VECSOURCES& GetSources(); -}; - diff --git a/xbmc/addons/GUIWindowAddonBrowser.cpp b/xbmc/addons/GUIWindowAddonBrowser.cpp deleted file mode 100644 index f4560dd..0000000 --- a/xbmc/addons/GUIWindowAddonBrowser.cpp +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "GUIWindowAddonBrowser.h" -#include "addons/AddonManager.h" -#include "addons/Repository.h" -#include "GUIDialogAddonInfo.h" -#include "GUIDialogAddonSettings.h" -#include "dialogs/GUIDialogBusy.h" -#include "dialogs/GUIDialogOK.h" -#include "dialogs/GUIDialogYesNo.h" -#include "dialogs/GUIDialogSelect.h" -#include "dialogs/GUIDialogFileBrowser.h" -#include "GUIUserMessages.h" -#include "guilib/GUIWindowManager.h" -#include "utils/URIUtils.h" -#include "URL.h" -#include "FileItem.h" -#include "filesystem/File.h" -#include "filesystem/Directory.h" -#include "filesystem/AddonsDirectory.h" -#include "addons/AddonInstaller.h" -#include "utils/JobManager.h" -#include "utils/log.h" -#include "threads/SingleLock.h" -#include "settings/Settings.h" -#include "settings/MediaSourceSettings.h" -#include "utils/StringUtils.h" -#include "AddonDatabase.h" -#include "settings/AdvancedSettings.h" -#include "storage/MediaManager.h" -#include "LangInfo.h" -#include "input/Key.h" -#include "ContextMenuManager.h" - -#define CONTROL_AUTOUPDATE 5 -#define CONTROL_SHUTUP 6 -#define CONTROL_FOREIGNFILTER 7 -#define CONTROL_BROKENFILTER 8 - -using namespace ADDON; -using namespace XFILE; -using namespace std; - -CGUIWindowAddonBrowser::CGUIWindowAddonBrowser(void) -: CGUIMediaWindow(WINDOW_ADDON_BROWSER, "AddonBrowser.xml") -{ -} - -CGUIWindowAddonBrowser::~CGUIWindowAddonBrowser() -{ -} - -bool CGUIWindowAddonBrowser::OnMessage(CGUIMessage& message) -{ - switch ( message.GetMessage() ) - { - case GUI_MSG_WINDOW_DEINIT: - { - if (m_thumbLoader.IsLoading()) - m_thumbLoader.StopThread(); - } - break; - case GUI_MSG_WINDOW_INIT: - { - m_rootDir.AllowNonLocalSources(false); - - // is this the first time the window is opened? - if (m_vecItems->GetPath() == "?" && message.GetStringParam().empty()) - m_vecItems->SetPath(""); - } - break; - case GUI_MSG_CLICKED: - { - int iControl = message.GetSenderId(); - if (iControl == CONTROL_AUTOUPDATE) - { - const CGUIControl *control = GetControl(CONTROL_AUTOUPDATE); - if (control && control->GetControlType() == CGUIControl::GUICONTROL_BUTTON) - CSettings::Get().SetInt("general.addonupdates", (CSettings::Get().GetInt("general.addonupdates")+1) % AUTO_UPDATES_MAX); - else - CSettings::Get().SetInt("general.addonupdates", (CSettings::Get().GetInt("general.addonupdates") == 0) ? 1 : 0); - UpdateButtons(); - return true; - } - else if (iControl == CONTROL_SHUTUP) - { - CSettings::Get().ToggleBool("general.addonnotifications"); - CSettings::Get().Save(); - return true; - } - else if (iControl == CONTROL_FOREIGNFILTER) - { - CSettings::Get().ToggleBool("general.addonforeignfilter"); - CSettings::Get().Save(); - Refresh(); - return true; - } - else if (iControl == CONTROL_BROKENFILTER) - { - CSettings::Get().ToggleBool("general.addonbrokenfilter"); - CSettings::Get().Save(); - Refresh(); - return true; - } - else if (m_viewControl.HasControl(iControl)) // list/thumb control - { - // get selected item - int iItem = m_viewControl.GetSelectedItem(); - int iAction = message.GetParam1(); - - // iItem is checked for validity inside these routines - if (iAction == ACTION_SHOW_INFO) - { - if (!m_vecItems->Get(iItem)->GetProperty("Addon.ID").empty()) - return CGUIDialogAddonInfo::ShowForItem((*m_vecItems)[iItem]); - return false; - } - } - } - break; - case GUI_MSG_NOTIFY_ALL: - { - if (message.GetParam1() == GUI_MSG_UPDATE_ITEM && IsActive() && message.GetNumStringParams() == 1) - { // update this item - for (int i = 0; i < m_vecItems->Size(); ++i) - { - CFileItemPtr item = m_vecItems->Get(i); - if (item->GetProperty("Addon.ID") == message.GetStringParam()) - { - SetItemLabel2(item); - return true; - } - } - } - } - break; - default: - break; - } - return CGUIMediaWindow::OnMessage(message); -} - -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); - - AddonPtr addon; - if (!CAddonMgr::Get().GetAddon(pItem->GetProperty("Addon.ID").asString(), addon, ADDON_UNKNOWN, false)) // allow disabled addons - return; - - if (addon->Type() == ADDON_REPOSITORY && pItem->m_bIsFolder) - { - buttons.Add(CONTEXT_BUTTON_SCAN,24034); - buttons.Add(CONTEXT_BUTTON_REFRESH,24035); - } - - buttons.Add(CONTEXT_BUTTON_INFO,24003); - - if (addon->HasSettings()) - buttons.Add(CONTEXT_BUTTON_SETTINGS,24020); - - CContextMenuManager::Get().AddVisibleItems(pItem, buttons); -} - -bool CGUIWindowAddonBrowser::OnContextButton(int itemNumber, - CONTEXT_BUTTON button) -{ - CFileItemPtr pItem = m_vecItems->Get(itemNumber); - if (pItem->IsPath("addons://enabled/")) - { - if (button == CONTEXT_BUTTON_SCAN) - { - CAddonMgr::Get().FindAddons(); - return true; - } - } - - AddonPtr addon; - if (CAddonMgr::Get().GetAddon(pItem->GetProperty("Addon.ID").asString(), addon, ADDON_UNKNOWN, false)) - { - if (button == CONTEXT_BUTTON_SETTINGS) - return CGUIDialogAddonSettings::ShowAndGetInput(addon); - - if (button == CONTEXT_BUTTON_REFRESH) - { - CAddonDatabase database; - database.Open(); - database.DeleteRepository(addon->ID()); - button = CONTEXT_BUTTON_SCAN; - } - - if (button == CONTEXT_BUTTON_SCAN) - { - CAddonInstaller::Get().UpdateRepos(true); - return true; - } - - if (button == CONTEXT_BUTTON_INFO) - { - CGUIDialogAddonInfo::ShowForItem(pItem); - return true; - } - } - - return CGUIMediaWindow::OnContextButton(itemNumber, button); -} - -class UpdateAddons : public IRunnable -{ - virtual void Run() - { - VECADDONS addons; - CAddonMgr::Get().GetAllOutdatedAddons(addons, true); // get local - for (VECADDONS::iterator i = addons.begin(); i != addons.end(); ++i) - { - std::string referer = StringUtils::Format("Referer=%s-%s.zip",(*i)->ID().c_str(),(*i)->Version().asString().c_str()); - CAddonInstaller::Get().Install((*i)->ID(), true, referer); // force install - } - } -}; - -class UpdateRepos : public IRunnable -{ - virtual void Run() - { - CAddonInstaller::Get().UpdateRepos(true, true); - } -}; - -bool CGUIWindowAddonBrowser::OnClick(int iItem) -{ - CFileItemPtr item = m_vecItems->Get(iItem); - if (item->GetPath() == "addons://install/") - { - // pop up filebrowser to grab an installed folder - VECSOURCES shares = *CMediaSourceSettings::Get().GetSources("files"); - g_mediaManager.GetLocalDrives(shares); - g_mediaManager.GetNetworkLocations(shares); - std::string path; - if (CGUIDialogFileBrowser::ShowAndGetFile(shares, "*.zip", g_localizeStrings.Get(24041), path)) - CAddonInstaller::Get().InstallFromZip(path); - return true; - } - else if (item->GetPath() == "addons://check/") - { - // perform the check for updates - UpdateRepos updater; - if (CGUIDialogBusy::Wait(&updater)) - Refresh(); - return true; - } - if (item->GetPath() == "addons://update_all/") - { - // fire off a threaded update of all addons - UpdateAddons updater; - if (CGUIDialogBusy::Wait(&updater)) - return Update("addons://downloading/"); - return true; - } - if (!item->m_bIsFolder) - { - // cancel a downloading job - if (item->HasProperty("Addon.Downloading")) - { - if (CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(24000), - item->GetProperty("Addon.Name").asString(), - g_localizeStrings.Get(24066),"")) - { - if (CAddonInstaller::Get().Cancel(item->GetProperty("Addon.ID").asString())) - Refresh(); - } - return true; - } - - CGUIDialogAddonInfo::ShowForItem(item); - return true; - } - if (item->IsPath("addons://search/")) - return Update(item->GetPath()); - - return CGUIMediaWindow::OnClick(iItem); -} - -void CGUIWindowAddonBrowser::UpdateButtons() -{ - const CGUIControl *control = GetControl(CONTROL_AUTOUPDATE); - if (control && control->GetControlType() == CGUIControl::GUICONTROL_BUTTON) - { // set label - CSettingInt *setting = (CSettingInt *)CSettings::Get().GetSetting("general.addonupdates"); - if (setting) - { - const StaticIntegerSettingOptions& options = setting->GetOptions(); - for (StaticIntegerSettingOptions::const_iterator it = options.begin(); it != options.end(); ++it) - { - if (it->second == setting->GetValue()) - { - SET_CONTROL_LABEL(CONTROL_AUTOUPDATE, it->first); - break; - } - } - } - } - else - { // old skin with toggle button - set on if auto updates are on - SET_CONTROL_SELECTED(GetID(),CONTROL_AUTOUPDATE, CSettings::Get().GetInt("general.addonupdates") == AUTO_UPDATES_ON); - } - SET_CONTROL_SELECTED(GetID(),CONTROL_SHUTUP, CSettings::Get().GetBool("general.addonnotifications")); - SET_CONTROL_SELECTED(GetID(),CONTROL_FOREIGNFILTER, CSettings::Get().GetBool("general.addonforeignfilter")); - SET_CONTROL_SELECTED(GetID(),CONTROL_BROKENFILTER, CSettings::Get().GetBool("general.addonbrokenfilter")); - CGUIMediaWindow::UpdateButtons(); -} - -static bool FilterVar(bool valid, const CVariant& variant, - const std::string& check) -{ - if (!valid) - return false; - - if (variant.isNull() || variant.asString().empty()) - return false; - - std::string regions = variant.asString(); - return regions.find(check) == std::string::npos; -} - -bool CGUIWindowAddonBrowser::GetDirectory(const std::string& strDirectory, - CFileItemList& items) -{ - bool result; - if (URIUtils::PathEquals(strDirectory, "addons://downloading/")) - { - VECADDONS addons; - CAddonInstaller::Get().GetInstallList(addons); - - CURL url(strDirectory); - CAddonsDirectory::GenerateListing(url,addons,items); - result = true; - items.SetProperty("reponame",g_localizeStrings.Get(24067)); - items.SetPath(strDirectory); - - if (m_guiState.get() && !m_guiState->HideParentDirItems()) - { - CFileItemPtr pItem(new CFileItem("..")); - pItem->SetPath(m_history.GetParentPath()); - pItem->m_bIsFolder = true; - pItem->m_bIsShareOrDrive = false; - items.AddFront(pItem, 0); - } - - } - else - { - result = CGUIMediaWindow::GetDirectory(strDirectory,items); - if (CSettings::Get().GetBool("general.addonforeignfilter")) - { - int i=0; - while (i < items.Size()) - { - if (!FilterVar(true, items[i]->GetProperty("Addon.Language"), "en") || - !FilterVar(true, items[i]->GetProperty("Addon.Language"), g_langInfo.GetLanguageLocale())) - { - i++; - } - else - items.Remove(i); - } - } - if (CSettings::Get().GetBool("general.addonbrokenfilter")) - { - for (int i = items.Size() - 1; i >= 0; i--) - { - if (!items[i]->GetProperty("Addon.Broken").empty()) - { //check if it's installed - AddonPtr addon; - if (!CAddonMgr::Get().GetAddon(items[i]->GetProperty("Addon.ID").asString(), addon)) - items.Remove(i); - } - } - } - } - - if (strDirectory.empty() && CAddonInstaller::Get().IsDownloading()) - { - CFileItemPtr item(new CFileItem("addons://downloading/",true)); - item->SetLabel(g_localizeStrings.Get(24067)); - item->SetLabelPreformated(true); - item->SetIconImage("DefaultNetwork.png"); - items.Add(item); - } - - items.SetContent("addons"); - - for (int i=0;im_bIsFolder) return; - unsigned int percent; - if (CAddonInstaller::Get().GetProgress(item->GetProperty("Addon.ID").asString(), percent)) - { - std::string progress = StringUtils::Format(g_localizeStrings.Get(24042).c_str(), percent); - item->SetProperty("Addon.Status", progress); - item->SetProperty("Addon.Downloading", true); - } - else - item->ClearProperty("Addon.Downloading"); - item->SetLabel2(item->GetProperty("Addon.Status").asString()); - // to avoid the view state overriding label 2 - item->SetLabelPreformated(true); -} - -bool CGUIWindowAddonBrowser::Update(const std::string &strDirectory, bool updateFilterPath /* = true */) -{ - if (m_thumbLoader.IsLoading()) - m_thumbLoader.StopThread(); - - if (!CGUIMediaWindow::Update(strDirectory, updateFilterPath)) - return false; - - m_thumbLoader.Load(*m_vecItems); - - return true; -} - -int CGUIWindowAddonBrowser::SelectAddonID(TYPE type, std::string &addonID, bool showNone /* = false */, bool showDetails /* = true */, bool showInstalled /* = true */, bool showInstallable /*= false */, bool showMore /* = true */) -{ - vector types; - types.push_back(type); - return SelectAddonID(types, addonID, showNone, showDetails, showInstalled, showInstallable, showMore); -} - -int CGUIWindowAddonBrowser::SelectAddonID(ADDON::TYPE type, vector &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */) -{ - vector types; - types.push_back(type); - return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, showInstalled, showInstallable, showMore); -} - -int CGUIWindowAddonBrowser::SelectAddonID(const vector &types, std::string &addonID, bool showNone /* = false */, bool showDetails /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */) -{ - vector addonIDs; - if (!addonID.empty()) - addonIDs.push_back(addonID); - int retval = SelectAddonID(types, addonIDs, showNone, showDetails, false, showInstalled, showInstallable, showMore); - if (addonIDs.size() > 0) - addonID = addonIDs.at(0); - else - addonID = ""; - return retval; -} - -int CGUIWindowAddonBrowser::SelectAddonID(const vector &types, vector &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */) -{ - // if we shouldn't show neither installed nor installable addons the list will be empty - if (!showInstalled && !showInstallable) - return 0; - - // can't show the "Get More" button if we already show installable addons - if (showInstallable) - showMore = false; - - CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); - if (!dialog) - return 0; - - // get rid of any invalid addon types - vector validTypes(types.size()); - std::copy_if(types.begin(), types.end(), validTypes.begin(), [](ADDON::TYPE type) { return type != ADDON_UNKNOWN; }); - - if (validTypes.empty()) - return 0; - - // get all addons to show - VECADDONS addons; - if (showInstalled) - { - for (vector::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) - { - VECADDONS typeAddons; - if (*type == ADDON_AUDIO) - CAddonsDirectory::GetScriptsAndPlugins("audio", typeAddons); - else if (*type == ADDON_EXECUTABLE) - CAddonsDirectory::GetScriptsAndPlugins("executable", typeAddons); - else if (*type == ADDON_IMAGE) - CAddonsDirectory::GetScriptsAndPlugins("image", typeAddons); - else if (*type == ADDON_VIDEO) - CAddonsDirectory::GetScriptsAndPlugins("video", typeAddons); - else - CAddonMgr::Get().GetAddons(*type, typeAddons); - - addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); - } - } - - if (showInstallable || showMore) - { - VECADDONS installableAddons; - CAddonDatabase database; - if (database.Open() && database.GetAddons(installableAddons)) - { - for (ADDON::IVECADDONS addon = installableAddons.begin(); addon != installableAddons.end();) - { - AddonPtr pAddon = *addon; - - // check if the addon matches one of the provided addon types - bool matchesType = false; - for (vector::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) - { - if (pAddon->IsType(*type)) - { - matchesType = true; - break; - } - } - - // only show addons that match one of the provided addon types and that aren't disabled - if (matchesType && !CAddonMgr::Get().IsAddonDisabled(pAddon->ID())) - { - // check if the addon is installed - bool isInstalled = CAddonMgr::Get().IsAddonInstalled(pAddon->ID()); - - // check if the addon is installed or can be installed - if ((showInstallable || showMore) && !isInstalled && CAddonMgr::Get().CanAddonBeInstalled(pAddon)) - { - ++addon; - continue; - } - } - - addon = installableAddons.erase(addon); - } - - if (showInstallable) - addons.insert(addons.end(), installableAddons.begin(), installableAddons.end()); - else if (showMore) - showMore = !installableAddons.empty(); - } - } - - if (addons.empty() && !showNone) - return 0; - - // turn the addons into items - std::map addonMap; - CFileItemList items; - for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon) - { - CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addon, "")); - if (!items.Contains(item->GetPath())) - { - items.Add(item); - addonMap.insert(std::make_pair(item->GetPath(), *addon)); - } - } - - if (items.IsEmpty() && !showNone) - return 0; - - std::string heading; - for (vector::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) - { - if (!heading.empty()) - heading += ", "; - heading += TranslateType(*type, true); - } - - dialog->SetHeading(heading); - dialog->Reset(); - dialog->SetUseDetails(showDetails); - - if (multipleSelection) - { - showNone = false; - showMore = false; - dialog->EnableButton(true, 186); - } - else if (showMore) - dialog->EnableButton(true, 21452); - - if (showNone) - { - CFileItemPtr item(new CFileItem("", false)); - item->SetLabel(g_localizeStrings.Get(231)); - item->SetLabel2(g_localizeStrings.Get(24040)); - item->SetIconImage("DefaultAddonNone.png"); - item->SetSpecialSort(SortSpecialOnTop); - items.Add(item); - } - items.Sort(SortByLabel, SortOrderAscending); - - if (addonIDs.size() > 0) - { - for (vector::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; ++it) - { - CFileItemPtr item = items.Get(*it); - if (item) - item->Select(true); - } - } - dialog->SetItems(&items); - dialog->SetMultiSelection(multipleSelection); - dialog->DoModal(); - - // if the "Get More" button has been pressed and we haven't shown the - // installable addons so far show a list of installable addons - if (showMore&& dialog->IsButtonPressed()) - return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, false, true, false); - - if (!dialog->IsConfirmed()) - return 0; - - addonIDs.clear(); - const CFileItemList& list = dialog->GetSelectedItems(); - for (int i = 0 ; i < list.Size() ; i++) - { - const CFileItemPtr& item = list.Get(i); - - // check if one of the selected addons needs to be installed - if (showInstallable) - { - std::map::const_iterator itAddon = addonMap.find(item->GetPath()); - if (itAddon != addonMap.end()) - { - const AddonPtr& addon = itAddon->second; - - // if the addon isn't installed we need to install it - if (!CAddonMgr::Get().IsAddonInstalled(addon->ID())) - { - AddonPtr installedAddon; - if (!CAddonInstaller::Get().InstallModal(addon->ID(), installedAddon, false)) - continue; - } - - // if the addon is disabled we need to enable it - if (CAddonMgr::Get().IsAddonDisabled(addon->ID())) - CAddonMgr::Get().DisableAddon(addon->ID(), false); - } - } - - addonIDs.push_back(item->GetPath()); - } - return 1; -} - -std::string CGUIWindowAddonBrowser::GetStartFolder(const std::string &dir) -{ - if (URIUtils::PathStarts(dir, "addons://")) - return dir; - return CGUIMediaWindow::GetStartFolder(dir); -} diff --git a/xbmc/addons/GUIWindowAddonBrowser.h b/xbmc/addons/GUIWindowAddonBrowser.h deleted file mode 100644 index d7c0ee0..0000000 --- a/xbmc/addons/GUIWindowAddonBrowser.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "addons/Addon.h" -#include "windows/GUIMediaWindow.h" -#include "ThumbLoader.h" - -class CFileItem; -class CFileItemList; - -class CGUIWindowAddonBrowser : public CGUIMediaWindow -{ -public: - CGUIWindowAddonBrowser(void); - virtual ~CGUIWindowAddonBrowser(void); - virtual bool OnMessage(CGUIMessage& message); - - /*! \brief Popup a selection dialog with a list of addons of the given type - \param type the type of addon wanted - \param addonID [out] the addon ID of the selected item - \param showNone whether there should be a "None" item in the list (defaults to false) - \param showDetails whether to show details of the addons or not - \param showInstalled whether installed addons should be in the list - \param showInstallable whether installable addons should be in the list - \param showMore whether to show the "Get More" button (only makes sense if showInstalled is true and showInstallable is false) - \return 1 if an addon was selected, 2 if "Get More" was chosen, or 0 if an error occurred or if the selection process was cancelled - */ - static int SelectAddonID(ADDON::TYPE type, std::string &addonID, bool showNone = false, bool showDetails = true, bool showInstalled = true, bool showInstallable = false, bool showMore = true); - static int SelectAddonID(const std::vector &types, std::string &addonID, bool showNone = false, bool showDetails = true, bool showInstalled = true, bool showInstallable = false, bool showMore = true); - /*! \brief Popup a selection dialog with a list of addons of the given type - \param type the type of addon wanted - \param addonIDs [out] array of selected addon IDs - \param showNone whether there should be a "None" item in the list (defaults to false) - \param showDetails whether to show details of the addons or not - \param multipleSelection allow selection of multiple addons, if set to true showNone will automaticly switch to false - \param showInstalled whether installed addons should be in the list - \param showInstallable whether installable addons should be in the list - \param showMore whether to show the "Get More" button (only makes sense if showInstalled is true and showInstallable is false) - \return 1 if an addon was selected or multiple selection was specified, 2 if "Get More" was chosen, or 0 if an error occurred or if the selection process was cancelled - */ - static int SelectAddonID(ADDON::TYPE type, std::vector &addonIDs, bool showNone = false, bool showDetails = true, bool multipleSelection = true, bool showInstalled = true, bool showInstallable = false, bool showMore = true); - static int SelectAddonID(const std::vector &types, std::vector &addonIDs, bool showNone = false, bool showDetails = true, bool multipleSelection = true, bool showInstalled = true, bool showInstallable = false, bool showMore = true); - -protected: - /* \brief set label2 of an item based on the Addon.Status property - \param item the item to update - */ - void SetItemLabel2(CFileItemPtr item); - - virtual void GetContextButtons(int itemNumber, CContextButtons &buttons); - virtual bool OnContextButton(int itemNumber, CONTEXT_BUTTON button); - virtual bool OnClick(int iItem); - virtual void UpdateButtons(); - virtual bool GetDirectory(const std::string &strDirectory, CFileItemList &items); - virtual bool Update(const std::string &strDirectory, bool updateFilterPath = true); - virtual std::string GetStartFolder(const std::string &dir); -private: - CProgramThumbLoader m_thumbLoader; -}; - diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h deleted file mode 100644 index 76f22fa..0000000 --- a/xbmc/addons/IAddon.h +++ /dev/null @@ -1,138 +0,0 @@ -#pragma once -/* -* Copyright (C) 2005-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 -* . -* -*/ -#include - -#include -#include -#include -#include - -class TiXmlElement; - -namespace ADDON -{ - typedef enum - { - ADDON_UNKNOWN, - ADDON_VIZ, - ADDON_SKIN, - ADDON_PVRDLL, - ADDON_SCRIPT, - ADDON_SCRIPT_WEATHER, - ADDON_SUBTITLE_MODULE, - ADDON_SCRIPT_LYRICS, - ADDON_SCRAPER_ALBUMS, - ADDON_SCRAPER_ARTISTS, - ADDON_SCRAPER_MOVIES, - ADDON_SCRAPER_MUSICVIDEOS, - ADDON_SCRAPER_TVSHOWS, - ADDON_SCREENSAVER, - ADDON_PLUGIN, - ADDON_REPOSITORY, - ADDON_WEB_INTERFACE, - ADDON_SERVICE, - ADDON_AUDIOENCODER, - ADDON_CONTEXT_ITEM, - ADDON_VIDEO, // virtual addon types - ADDON_AUDIO, - ADDON_IMAGE, - ADDON_EXECUTABLE, - ADDON_VIZ_LIBRARY, - ADDON_SCRAPER_LIBRARY, - ADDON_SCRIPT_LIBRARY, - ADDON_SCRIPT_MODULE, - ADDON_MAX - } TYPE; - - class IAddon; - typedef std::shared_ptr AddonPtr; - class CVisualisation; - typedef std::shared_ptr VizPtr; - class CSkinInfo; - typedef std::shared_ptr SkinPtr; - class CPluginSource; - typedef std::shared_ptr PluginPtr; - - class CAddonMgr; - class AddonVersion; - typedef std::map > ADDONDEPS; - typedef std::map InfoMap; - class AddonProps; - - class IAddon : public std::enable_shared_from_this - { - public: - virtual ~IAddon() {}; - virtual AddonPtr Clone() const =0; - virtual TYPE Type() const =0; - virtual bool IsType(TYPE type) const =0; - virtual AddonProps Props() const =0; - virtual AddonProps& Props() =0; - virtual const std::string ID() const =0; - virtual const std::string Name() const =0; - virtual bool Enabled() const =0; - virtual bool IsInUse() const =0; - virtual const AddonVersion Version() const =0; - virtual const AddonVersion MinVersion() const =0; - virtual const std::string Summary() const =0; - virtual const std::string Description() const =0; - virtual const std::string Path() const =0; - virtual const std::string Profile() const =0; - virtual const std::string LibPath() const =0; - virtual const std::string ChangeLog() const =0; - virtual const std::string FanArt() const =0; - virtual const std::string Author() const =0; - virtual const std::string Icon() const =0; - virtual int Stars() const =0; - virtual const std::string Disclaimer() const =0; - virtual const InfoMap &ExtraInfo() const =0; - virtual bool HasSettings() =0; - virtual void SaveSettings() =0; - virtual void UpdateSetting(const std::string& key, const std::string& value) =0; - virtual std::string GetSetting(const std::string& key) =0; - virtual TiXmlElement* GetSettingsXML() =0; - virtual std::string GetString(uint32_t id) =0; - virtual const ADDONDEPS &GetDeps() const =0; - virtual AddonVersion GetDependencyVersion(const std::string &dependencyID) const =0; - virtual bool MeetsVersion(const AddonVersion &version) const =0; - virtual bool ReloadSettings() =0; - virtual void OnDisabled() =0; - virtual void OnEnabled() =0; - virtual AddonPtr GetRunningInstance() const=0; - virtual bool OnPreInstall() =0; - virtual void OnPostInstall(bool restart, bool update, bool modal) =0; - virtual void OnPreUnInstall() =0; - virtual void OnPostUnInstall() =0; - virtual bool CanInstall(const std::string& referer) =0; - - protected: - virtual bool LoadSettings(bool bForce = false) =0; - - private: - friend class CAddonMgr; - virtual bool IsAddonLibrary() =0; - virtual void Enable() =0; - virtual void Disable() =0; - virtual bool LoadStrings() =0; - virtual void ClearStrings() =0; - }; -}; - diff --git a/xbmc/addons/Makefile b/xbmc/addons/Makefile deleted file mode 100644 index 4cf5b17..0000000 --- a/xbmc/addons/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -SRCS=Addon.cpp \ - AddonCallbacks.cpp \ - AddonCallbacksAddon.cpp \ - AddonCallbacksCodec.cpp \ - AddonCallbacksGUI.cpp \ - AddonCallbacksPVR.cpp \ - AddonDatabase.cpp \ - AddonInstaller.cpp \ - AddonManager.cpp \ - AddonStatusHandler.cpp \ - AddonVersion.cpp \ - AudioEncoder.cpp \ - ContextItemAddon.cpp \ - GUIDialogAddonInfo.cpp \ - GUIDialogAddonSettings.cpp \ - GUIViewStateAddonBrowser.cpp \ - GUIWindowAddonBrowser.cpp \ - PluginSource.cpp \ - Repository.cpp \ - Scraper.cpp \ - ScreenSaver.cpp \ - Service.cpp \ - Skin.cpp \ - Visualisation.cpp \ - Webinterface.cpp \ - -LIB=addons.a - -include ../../Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) - diff --git a/xbmc/addons/PluginSource.cpp b/xbmc/addons/PluginSource.cpp deleted file mode 100644 index a5729cf..0000000 --- a/xbmc/addons/PluginSource.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "PluginSource.h" -#include "AddonManager.h" -#include "utils/StringUtils.h" - -using namespace std; - -namespace ADDON -{ - -CPluginSource::CPluginSource(const AddonProps &props) - : CAddon(props) -{ - std::string provides; - InfoMap::const_iterator i = Props().extrainfo.find("provides"); - if (i != Props().extrainfo.end()) - provides = i->second; - SetProvides(provides); -} - -CPluginSource::CPluginSource(const cp_extension_t *ext) - : CAddon(ext) -{ - std::string provides; - if (ext) - { - provides = CAddonMgr::Get().GetExtValue(ext->configuration, "provides"); - if (!provides.empty()) - Props().extrainfo.insert(make_pair("provides", provides)); - } - SetProvides(provides); -} - -AddonPtr CPluginSource::Clone() const -{ - return AddonPtr(new CPluginSource(*this)); -} - -void CPluginSource::SetProvides(const std::string &content) -{ - if (!content.empty()) - { - vector provides = StringUtils::Split(content, ' '); - for (vector::const_iterator i = provides.begin(); i != provides.end(); ++i) - { - Content content = Translate(*i); - if (content != UNKNOWN) - m_providedContent.insert(content); - } - } - if (Type() == ADDON_SCRIPT && m_providedContent.empty()) - m_providedContent.insert(EXECUTABLE); -} - -CPluginSource::Content CPluginSource::Translate(const std::string &content) -{ - if (content == "audio") - return CPluginSource::AUDIO; - else if (content == "image") - return CPluginSource::IMAGE; - else if (content == "executable") - return CPluginSource::EXECUTABLE; - else if (content == "video") - return CPluginSource::VIDEO; - else - return CPluginSource::UNKNOWN; -} - -bool CPluginSource::IsType(TYPE type) const -{ - return ((type == ADDON_VIDEO && Provides(VIDEO)) - || (type == ADDON_AUDIO && Provides(AUDIO)) - || (type == ADDON_IMAGE && Provides(IMAGE)) - || (type == ADDON_EXECUTABLE && Provides(EXECUTABLE))); -} - -} /*namespace ADDON*/ - diff --git a/xbmc/addons/PluginSource.h b/xbmc/addons/PluginSource.h deleted file mode 100644 index 87e1f34..0000000 --- a/xbmc/addons/PluginSource.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#pragma once - -#include "Addon.h" - -namespace ADDON -{ - -class CPluginSource : public CAddon -{ -public: - - enum Content { UNKNOWN, AUDIO, IMAGE, EXECUTABLE, VIDEO }; - - CPluginSource(const cp_extension_t *ext); - CPluginSource(const AddonProps &props); - virtual ~CPluginSource() {} - virtual AddonPtr Clone() const; - virtual bool IsType(TYPE type) const; - bool Provides(const Content& content) const - { - return content == UNKNOWN ? false : m_providedContent.count(content) > 0; - } - - bool ProvidesSeveral() const - { - return m_providedContent.size() > 1; - } - - static Content Translate(const std::string &content); -private: - /*! \brief Set the provided content for this plugin - If no valid content types are passed in, we set the EXECUTABLE type - \param content a space-separated list of content types - */ - void SetProvides(const std::string &content); - std::set m_providedContent; -}; - -} /*namespace ADDON*/ diff --git a/xbmc/addons/Repository.cpp b/xbmc/addons/Repository.cpp deleted file mode 100644 index e65a195..0000000 --- a/xbmc/addons/Repository.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "Repository.h" -#include "addons/AddonDatabase.h" -#include "addons/AddonInstaller.h" -#include "addons/AddonManager.h" -#include "dialogs/GUIDialogYesNo.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "filesystem/File.h" -#include "filesystem/PluginDirectory.h" -#include "settings/Settings.h" -#include "utils/log.h" -#include "utils/JobManager.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" -#include "utils/XBMCTinyXML.h" -#include "FileItem.h" -#include "TextureDatabase.h" -#include "URL.h" - -using namespace std; -using namespace XFILE; -using namespace ADDON; - -AddonPtr CRepository::Clone() const -{ - return AddonPtr(new CRepository(*this)); -} - -CRepository::CRepository(const AddonProps& props) : - CAddon(props) -{ -} - -CRepository::CRepository(const cp_extension_t *ext) - : CAddon(ext) -{ - // read in the other props that we need - if (ext) - { - AddonVersion version("0.0.0"); - AddonPtr addonver; - if (CAddonMgr::Get().GetAddon("xbmc.addon", addonver)) - version = addonver->Version(); - for (size_t i = 0; i < ext->configuration->num_children; ++i) - { - if(ext->configuration->children[i].name && - strcmp(ext->configuration->children[i].name, "dir") == 0) - { - AddonVersion min_version(CAddonMgr::Get().GetExtValue(&ext->configuration->children[i], "@minversion")); - if (min_version <= version) - { - DirInfo dir; - dir.version = min_version; - dir.checksum = CAddonMgr::Get().GetExtValue(&ext->configuration->children[i], "checksum"); - dir.compressed = CAddonMgr::Get().GetExtValue(&ext->configuration->children[i], "info@compressed") == "true"; - dir.info = CAddonMgr::Get().GetExtValue(&ext->configuration->children[i], "info"); - dir.datadir = CAddonMgr::Get().GetExtValue(&ext->configuration->children[i], "datadir"); - dir.zipped = CAddonMgr::Get().GetExtValue(&ext->configuration->children[i], "datadir@zip") == "true"; - dir.hashes = CAddonMgr::Get().GetExtValue(&ext->configuration->children[i], "hashes") == "true"; - m_dirs.push_back(dir); - } - } - } - // backward compatibility - if (!CAddonMgr::Get().GetExtValue(ext->configuration, "info").empty()) - { - DirInfo info; - info.checksum = CAddonMgr::Get().GetExtValue(ext->configuration, "checksum"); - info.compressed = CAddonMgr::Get().GetExtValue(ext->configuration, "info@compressed") == "true"; - info.info = CAddonMgr::Get().GetExtValue(ext->configuration, "info"); - info.datadir = CAddonMgr::Get().GetExtValue(ext->configuration, "datadir"); - info.zipped = CAddonMgr::Get().GetExtValue(ext->configuration, "datadir@zip") == "true"; - info.hashes = CAddonMgr::Get().GetExtValue(ext->configuration, "hashes") == "true"; - m_dirs.push_back(info); - } - } -} - -CRepository::CRepository(const CRepository &rhs) - : CAddon(rhs), m_dirs(rhs.m_dirs) -{ -} - -CRepository::~CRepository() -{ -} - -string CRepository::FetchChecksum(const string& url) -{ - CFile file; - try - { - if (file.Open(url)) - { - // we intentionally avoid using file.GetLength() for - // Transfer-Encoding: chunked servers. - std::stringstream str; - char temp[1024]; - int read; - while ((read=file.Read(temp, sizeof(temp))) > 0) - str.write(temp, read); - return str.str(); - } - return ""; - } - catch (...) - { - return ""; - } -} - -string CRepository::GetAddonHash(const AddonPtr& addon) const -{ - string checksum; - DirList::const_iterator it; - for (it = m_dirs.begin();it != m_dirs.end(); ++it) - if (URIUtils::IsInPath(addon->Path(), it->datadir)) - break; - if (it != m_dirs.end() && it->hashes) - { - checksum = FetchChecksum(addon->Path()+".md5"); - size_t pos = checksum.find_first_of(" \n"); - if (pos != string::npos) - return checksum.substr(0, pos); - } - return checksum; -} - -#define SET_IF_NOT_EMPTY(x,y) \ - { \ - if (!x.empty()) \ - x = y; \ - } - -bool CRepository::Parse(const DirInfo& dir, VECADDONS &result) -{ - string file = dir.info; - if (dir.compressed) - { - CURL url(dir.info); - string opts = url.GetProtocolOptions(); - if (!opts.empty()) - opts += "&"; - url.SetProtocolOptions(opts+"Encoding=gzip"); - file = url.Get(); - } - - CXBMCTinyXML doc; - if (doc.LoadFile(file) && doc.RootElement() && - CAddonMgr::Get().AddonsFromRepoXML(doc.RootElement(), result)) - { - for (IVECADDONS i = result.begin(); i != result.end(); ++i) - { - AddonPtr addon = *i; - if (dir.zipped) - { - string file = StringUtils::Format("%s/%s-%s.zip", addon->ID().c_str(), addon->ID().c_str(), addon->Version().asString().c_str()); - addon->Props().path = URIUtils::AddFileToFolder(dir.datadir,file); - SET_IF_NOT_EMPTY(addon->Props().icon,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/icon.png")) - file = StringUtils::Format("%s/changelog-%s.txt", addon->ID().c_str(), addon->Version().asString().c_str()); - SET_IF_NOT_EMPTY(addon->Props().changelog,URIUtils::AddFileToFolder(dir.datadir,file)) - SET_IF_NOT_EMPTY(addon->Props().fanart,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/fanart.jpg")) - } - else - { - addon->Props().path = URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/"); - SET_IF_NOT_EMPTY(addon->Props().icon,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/icon.png")) - SET_IF_NOT_EMPTY(addon->Props().changelog,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/changelog.txt")) - SET_IF_NOT_EMPTY(addon->Props().fanart,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/fanart.jpg")) - } - } - return true; - } - return false; -} - -void CRepository::OnPostInstall(bool restart, bool update, bool modal) -{ - VECADDONS addons; - AddonPtr repo(new CRepository(*this)); - addons.push_back(repo); - CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(addons), &CAddonInstaller::Get()); -} - -void CRepository::OnPostUnInstall() -{ - CAddonDatabase database; - database.Open(); - database.DeleteRepository(ID()); -} - -CRepositoryUpdateJob::CRepositoryUpdateJob(const VECADDONS &repos) - : m_repos(repos) -{ -} - -void MergeAddons(map &addons, const VECADDONS &new_addons) -{ - for (VECADDONS::const_iterator it = new_addons.begin(); it != new_addons.end(); ++it) - { - map::iterator existing = addons.find((*it)->ID()); - if (existing != addons.end()) - { // already got it - replace if we have a newer version - if (existing->second->Version() < (*it)->Version()) - existing->second = *it; - } - else - addons.insert(make_pair((*it)->ID(), *it)); - } -} - -bool CRepositoryUpdateJob::DoWork() -{ - map addons; - for (VECADDONS::const_iterator i = m_repos.begin(); i != m_repos.end(); ++i) - { - if (ShouldCancel(0, 0)) - return false; - const RepositoryPtr repo = std::dynamic_pointer_cast(*i); - VECADDONS newAddons; - if (GrabAddons(repo, newAddons)) - MergeAddons(addons, newAddons); - } - if (addons.empty()) - return true; //Nothing to do - - // check for updates - CAddonDatabase database; - database.Open(); - database.BeginMultipleExecute(); - - CTextureDatabase textureDB; - textureDB.Open(); - textureDB.BeginMultipleExecute(); - VECADDONS notifications; - for (map::const_iterator i = addons.begin(); i != addons.end(); ++i) - { - // manager told us to feck off - if (ShouldCancel(0,0)) - break; - - AddonPtr newAddon = i->second; - bool deps_met = CAddonInstaller::Get().CheckDependencies(newAddon, &database); - if (!deps_met && newAddon->Props().broken.empty()) - newAddon->Props().broken = "DEPSNOTMET"; - - // invalidate the art associated with this item - if (!newAddon->Props().fanart.empty()) - textureDB.InvalidateCachedTexture(newAddon->Props().fanart); - if (!newAddon->Props().icon.empty()) - textureDB.InvalidateCachedTexture(newAddon->Props().icon); - - AddonPtr addon; - CAddonMgr::Get().GetAddon(newAddon->ID(),addon); - if (addon && newAddon->Version() > addon->Version() && - !database.IsAddonBlacklisted(newAddon->ID(),newAddon->Version().asString()) && - deps_met) - { - if (CSettings::Get().GetInt("general.addonupdates") == AUTO_UPDATES_ON) - { - string referer; - if (URIUtils::IsInternetStream(newAddon->Path())) - referer = StringUtils::Format("Referer=%s-%s.zip",addon->ID().c_str(),addon->Version().asString().c_str()); - - if (newAddon->CanInstall(referer)) - CAddonInstaller::Get().Install(addon->ID(), true, referer); - } - else - notifications.push_back(addon); - } - - // Check if we should mark the add-on as broken. We may have a newer version - // of this add-on in the database or installed - if so, we keep it unbroken. - bool haveNewer = (addon && addon->Version() > newAddon->Version()) || - database.GetAddonVersion(newAddon->ID()) > newAddon->Version(); - if (!haveNewer) - { - if (!newAddon->Props().broken.empty()) - { - if (database.IsAddonBroken(newAddon->ID()).empty()) - { - std::string line = g_localizeStrings.Get(24096); - if (newAddon->Props().broken == "DEPSNOTMET") - line = g_localizeStrings.Get(24104); - if (addon && CGUIDialogYesNo::ShowAndGetInput(newAddon->Name(), - line, - g_localizeStrings.Get(24097), - "")) - CAddonMgr::Get().DisableAddon(newAddon->ID()); - } - } - database.BreakAddon(newAddon->ID(), newAddon->Props().broken); - } - } - database.CommitMultipleExecute(); - textureDB.CommitMultipleExecute(); - if (!notifications.empty() && CSettings::Get().GetBool("general.addonnotifications")) - { - if (notifications.size() == 1) - CGUIDialogKaiToast::QueueNotification(notifications[0]->Icon(), - g_localizeStrings.Get(24061), - notifications[0]->Name(),TOAST_DISPLAY_TIME,false,TOAST_DISPLAY_TIME); - else - CGUIDialogKaiToast::QueueNotification("", - g_localizeStrings.Get(24001), - g_localizeStrings.Get(24061),TOAST_DISPLAY_TIME,false,TOAST_DISPLAY_TIME); - } - - return true; -} - -bool CRepositoryUpdateJob::GrabAddons(const RepositoryPtr& repo, VECADDONS& addons) -{ - CAddonDatabase database; - database.Open(); - string oldReposum; - if (!database.GetRepoChecksum(repo->ID(), oldReposum)) - oldReposum = ""; - - string reposum; - for (CRepository::DirList::const_iterator it = repo->m_dirs.begin(); it != repo->m_dirs.end(); ++it) - { - if (ShouldCancel(0, 0)) - return false; - if (!it->checksum.empty()) - { - const string dirsum = CRepository::FetchChecksum(it->checksum); - if (dirsum.empty()) - { - CLog::Log(LOGERROR, "Failed to fetch checksum for directory listing %s for repository %s. ", (*it).info.c_str(), repo->ID().c_str()); - return false; - } - reposum += dirsum; - } - } - - if (oldReposum != reposum || oldReposum.empty()) - { - map uniqueAddons; - for (CRepository::DirList::const_iterator it = repo->m_dirs.begin(); it != repo->m_dirs.end(); ++it) - { - if (ShouldCancel(0, 0)) - return false; - VECADDONS addons; - if (!CRepository::Parse(*it, addons)) - { //TODO: Hash is invalid and should not be saved, but should we fail? - //We can still report a partial addon listing. - CLog::Log(LOGERROR, "Failed to read directory listing %s for repository %s. ", (*it).info.c_str(), repo->ID().c_str()); - return false; - } - MergeAddons(uniqueAddons, addons); - } - - bool add = true; - if (!repo->Props().libname.empty()) - { - CFileItemList dummy; - string s = StringUtils::Format("plugin://%s/?action=update", repo->ID().c_str()); - add = CDirectory::GetDirectory(s, dummy); - } - if (add) - { - for (map::const_iterator i = uniqueAddons.begin(); i != uniqueAddons.end(); ++i) - addons.push_back(i->second); - database.AddRepository(repo->ID(), addons, reposum, repo->Version()); - } - } - else - { - CLog::Log(LOGDEBUG, "Checksum for repository %s not changed.", repo->ID().c_str()); - database.GetRepository(repo->ID(), addons); - database.SetRepoTimestamp(repo->ID(), CDateTime::GetCurrentDateTime().GetAsDBDateTime(), repo->Version()); - } - return true; -} - diff --git a/xbmc/addons/Repository.h b/xbmc/addons/Repository.h deleted file mode 100644 index 5120c38..0000000 --- a/xbmc/addons/Repository.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "Addon.h" -#include "utils/Job.h" - -namespace ADDON -{ - class CRepository; - typedef std::shared_ptr RepositoryPtr; - class CRepository : public CAddon - { - public: - virtual AddonPtr Clone() const; - CRepository(const AddonProps& props); - CRepository(const cp_extension_t *props); - virtual ~CRepository(); - - /*! \brief Get the md5 hash for an addon. - \param the addon in question. - \return the md5 hash for the given addon, empty if non exists. - */ - std::string GetAddonHash(const AddonPtr& addon) const; - - struct DirInfo - { - DirInfo() : version("0.0.0"), compressed(false), zipped(false), hashes(false) {} - AddonVersion version; - std::string info; - std::string checksum; - std::string datadir; - bool compressed; - bool zipped; - bool hashes; - }; - - typedef std::vector DirList; - DirList m_dirs; - - static bool Parse(const DirInfo& dir, VECADDONS& addons); - static std::string FetchChecksum(const std::string& url); - - virtual void OnPostInstall(bool restart, bool update, bool modal); - virtual void OnPostUnInstall(); - - private: - CRepository(const CRepository &rhs); - }; - - class CRepositoryUpdateJob : public CJob - { - public: - CRepositoryUpdateJob(const VECADDONS& repos); - virtual ~CRepositoryUpdateJob() {} - - virtual const char *GetType() const { return "repoupdate"; }; - virtual bool DoWork(); - private: - bool GrabAddons(const RepositoryPtr& repo, VECADDONS& addons); - - VECADDONS m_repos; - }; -} - diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp deleted file mode 100644 index 06f34f2..0000000 --- a/xbmc/addons/Scraper.cpp +++ /dev/null @@ -1,1033 +0,0 @@ -/* -* Copyright (C) 2005-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 -* . -* -*/ -#include "Scraper.h" -#include "filesystem/File.h" -#include "filesystem/Directory.h" -#include "filesystem/CurlFile.h" -#include "AddonManager.h" -#include "utils/ScraperParser.h" -#include "utils/ScraperUrl.h" -#include "utils/CharsetConverter.h" -#include "utils/log.h" -#include "music/infoscanner/MusicAlbumInfo.h" -#include "music/infoscanner/MusicArtistInfo.h" -#include "utils/fstrcmp.h" -#include "settings/AdvancedSettings.h" -#include "FileItem.h" -#include "utils/URIUtils.h" -#include "utils/XMLUtils.h" -#include "utils/StringUtils.h" -#include "music/MusicDatabase.h" -#include "video/VideoDatabase.h" -#include "music/Album.h" -#include "music/Artist.h" -#include "Util.h" -#include "URL.h" - -#include -#include - -using namespace std; -using namespace XFILE; -using namespace MUSIC_GRABBER; -using namespace VIDEO; - -namespace ADDON -{ - -typedef struct -{ - const char* name; - CONTENT_TYPE type; - int pretty; -} ContentMapping; - -static const ContentMapping content[] = - {{"unknown", CONTENT_NONE, 231 }, - {"albums", CONTENT_ALBUMS, 132 }, - {"music", CONTENT_ALBUMS, 132 }, - {"artists", CONTENT_ARTISTS, 133 }, - {"movies", CONTENT_MOVIES, 20342 }, - {"tvshows", CONTENT_TVSHOWS, 20343 }, - {"musicvideos", CONTENT_MUSICVIDEOS, 20389 }}; - -std::string TranslateContent(const CONTENT_TYPE &type, bool pretty/*=false*/) -{ - for (unsigned int index=0; index < ARRAY_SIZE(content); ++index) - { - const ContentMapping &map = content[index]; - if (type == map.type) - { - if (pretty && map.pretty) - return g_localizeStrings.Get(map.pretty); - else - return map.name; - } - } - return ""; -} - -CONTENT_TYPE TranslateContent(const std::string &string) -{ - for (unsigned int index=0; index < ARRAY_SIZE(content); ++index) - { - const ContentMapping &map = content[index]; - if (string == map.name) - return map.type; - } - return CONTENT_NONE; -} - -TYPE ScraperTypeFromContent(const CONTENT_TYPE &content) -{ - switch (content) - { - case CONTENT_ALBUMS: - return ADDON_SCRAPER_ALBUMS; - case CONTENT_ARTISTS: - return ADDON_SCRAPER_ARTISTS; - case CONTENT_MOVIES: - return ADDON_SCRAPER_MOVIES; - case CONTENT_MUSICVIDEOS: - return ADDON_SCRAPER_MUSICVIDEOS; - case CONTENT_TVSHOWS: - return ADDON_SCRAPER_TVSHOWS; - default: - return ADDON_UNKNOWN; - } -} - -// if the XML root is , throw CScraperError with enclosed /<message> values -static void CheckScraperError(const TiXmlElement *pxeRoot) -{ - if (!pxeRoot || stricmp(pxeRoot->Value(), "error")) - return; - std::string sTitle; - std::string sMessage; - XMLUtils::GetString(pxeRoot, "title", sTitle); - XMLUtils::GetString(pxeRoot, "message", sMessage); - throw CScraperError(sTitle, sMessage); -} - -CScraper::CScraper(const cp_extension_t *ext) : CAddon(ext), m_fLoaded(false) -{ - if (ext) - { - m_language = CAddonMgr::Get().GetExtValue(ext->configuration, "@language"); - m_requiressettings = CAddonMgr::Get().GetExtValue(ext->configuration,"@requiressettings") == "true"; - std::string persistence = CAddonMgr::Get().GetExtValue(ext->configuration, "@cachepersistence"); - if (!persistence.empty()) - m_persistence.SetFromTimeString(persistence); - } - switch (Type()) - { - case ADDON_SCRAPER_ALBUMS: - m_pathContent = CONTENT_ALBUMS; - break; - case ADDON_SCRAPER_ARTISTS: - m_pathContent = CONTENT_ARTISTS; - break; - case ADDON_SCRAPER_MOVIES: - m_pathContent = CONTENT_MOVIES; - break; - case ADDON_SCRAPER_MUSICVIDEOS: - m_pathContent = CONTENT_MUSICVIDEOS; - break; - case ADDON_SCRAPER_TVSHOWS: - m_pathContent = CONTENT_TVSHOWS; - break; - default: - m_pathContent = CONTENT_NONE; - break; - } -} - -AddonPtr CScraper::Clone() const -{ - return AddonPtr(new CScraper(*this)); -} - -CScraper::CScraper(const CScraper &rhs) - : CAddon(rhs), m_fLoaded(false), - m_language(rhs.m_language), - m_requiressettings(rhs.m_requiressettings), - m_persistence(rhs.m_persistence), - m_pathContent(rhs.m_pathContent) -{ -} - -bool CScraper::Supports(const CONTENT_TYPE &content) const -{ - return Type() == ScraperTypeFromContent(content); -} - -bool CScraper::SetPathSettings(CONTENT_TYPE content, const std::string& xml) -{ - m_pathContent = content; - if (!LoadSettings()) - return false; - - if (xml.empty()) - return true; - - CXBMCTinyXML doc; - doc.Parse(xml); - m_userSettingsLoaded = SettingsFromXML(doc); - - return m_userSettingsLoaded; -} - -std::string CScraper::GetPathSettings() -{ - if (!LoadSettings()) - return ""; - - stringstream stream; - CXBMCTinyXML doc; - SettingsToXML(doc); - if (doc.RootElement()) - stream << *doc.RootElement(); - - return stream.str(); -} - -void CScraper::ClearCache() -{ - std::string strCachePath = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, "scrapers"); - - // create scraper cache dir if needed - if (!CDirectory::Exists(strCachePath)) - CDirectory::Create(strCachePath); - - strCachePath = URIUtils::AddFileToFolder(strCachePath, ID()); - URIUtils::AddSlashAtEnd(strCachePath); - - if (CDirectory::Exists(strCachePath)) - { - CFileItemList items; - CDirectory::GetDirectory(strCachePath,items); - for (int i=0;i<items.Size();++i) - { - // wipe cache - if (items[i]->m_dateTime + m_persistence <= CDateTime::GetCurrentDateTime()) - CFile::Delete(items[i]->GetPath()); - } - } - else - CDirectory::Create(strCachePath); -} - -// returns a vector of strings: the first is the XML output by the function; the rest -// is XML output by chained functions, possibly recursively -// the CCurlFile object is passed in so that URL fetches can be canceled from other threads -// throws CScraperError abort on internal failures (e.g., parse errors) -vector<string> CScraper::Run(const std::string& function, - const CScraperUrl& scrURL, - CCurlFile& http, - const vector<string>* extras) -{ - if (!Load()) - throw CScraperError(); - - std::string strXML = InternalRun(function,scrURL,http,extras); - if (strXML.empty()) - { - if (function != "NfoUrl" && function != "ResolveIDToUrl") - CLog::Log(LOGERROR, "%s: Unable to parse web site",__FUNCTION__); - throw CScraperError(); - } - - CLog::Log(LOGDEBUG,"scraper: %s returned %s",function.c_str(),strXML.c_str()); - - CXBMCTinyXML doc; - /* all data was converted to UTF-8 before being processed by scraper */ - doc.Parse(strXML, TIXML_ENCODING_UTF8); - if (!doc.RootElement()) - { - CLog::Log(LOGERROR, "%s: Unable to parse XML",__FUNCTION__); - throw CScraperError(); - } - - vector<string> result; - result.push_back(strXML); - TiXmlElement* xchain = doc.RootElement()->FirstChildElement(); - // skip children of the root element until <url> or <chain> - while (xchain && strcmp(xchain->Value(),"url") && strcmp(xchain->Value(),"chain")) - xchain = xchain->NextSiblingElement(); - while (xchain) - { - // <chain|url function="...">param</> - const char* szFunction = xchain->Attribute("function"); - if (szFunction) - { - CScraperUrl scrURL2; - vector<string> extras; - // for <chain>, pass the contained text as a parameter; for <url>, as URL content - if (strcmp(xchain->Value(),"chain")==0) - { - if (xchain->FirstChild()) - extras.push_back(xchain->FirstChild()->Value()); - } - else - scrURL2.ParseElement(xchain); - // Fix for empty chains. $$1 would still contain the - // previous value as there is no child of the xml node. - // since $$1 will always either contain the data from an - // url or the parameters to a chain, we can safely clear it here - // to fix this issue - m_parser.m_param[0].clear(); - vector<string> result2 = RunNoThrow(szFunction,scrURL2,http,&extras); - result.insert(result.end(),result2.begin(),result2.end()); - } - xchain = xchain->NextSiblingElement(); - // continue to skip past non-<url> or <chain> elements - while (xchain && strcmp(xchain->Value(),"url") && strcmp(xchain->Value(),"chain")) - xchain = xchain->NextSiblingElement(); - } - - return result; -} - -// just like Run, but returns an empty list instead of throwing in case of error -// don't use in new code; errors should be handled appropriately -vector<string> CScraper::RunNoThrow(const std::string& function, - const CScraperUrl& url, - XFILE::CCurlFile& http, - const vector<string>* extras) -{ - vector<string> vcs; - try - { - vcs = Run(function, url, http, extras); - } - catch (const CScraperError &sce) - { - assert(sce.FAborted()); // the only kind we should get - } - return vcs; -} - -std::string CScraper::InternalRun(const std::string& function, - const CScraperUrl& scrURL, - CCurlFile& http, - const vector<string>* extras) -{ - // walk the list of input URLs and fetch each into parser parameters - unsigned int i; - for (i=0;i<scrURL.m_url.size();++i) - { - if (!CScraperUrl::Get(scrURL.m_url[i],m_parser.m_param[i],http,ID()) || m_parser.m_param[i].size() == 0) - return ""; - } - // put the 'extra' parameterts into the parser parameter list too - if (extras) - { - for (unsigned int j=0;j<extras->size();++j) - m_parser.m_param[j+i] = (*extras)[j]; - } - - return m_parser.Parse(function,this); -} - -bool CScraper::Load() -{ - if (m_fLoaded) - return true; - - bool result=m_parser.Load(LibPath()); - if (result) - { - // TODO: this routine assumes that deps are a single level, and assumes the dep is installed. - // 1. Does it make sense to have recursive dependencies? - // 2. Should we be checking the dep versions or do we assume it is ok? - ADDONDEPS deps = GetDeps(); - ADDONDEPS::iterator itr = deps.begin(); - while (itr != deps.end()) - { - if (itr->first == "xbmc.metadata") - { - ++itr; - continue; - } - AddonPtr dep; - - bool bOptional = itr->second.second; - - if (CAddonMgr::Get().GetAddon((*itr).first, dep)) - { - CXBMCTinyXML doc; - if (dep->Type() == ADDON_SCRAPER_LIBRARY && doc.LoadFile(dep->LibPath())) - m_parser.AddDocument(&doc); - } - else - { - if (!bOptional) - { - result = false; - break; - } - } - ++itr; - } - } - - if (!result) - CLog::Log(LOGWARNING, "failed to load scraper XML from %s", LibPath().c_str()); - return m_fLoaded = result; -} - -bool CScraper::IsInUse() const -{ - if (Supports(CONTENT_ALBUMS) || Supports(CONTENT_ARTISTS)) - { // music scraper - CMusicDatabase db; - if (db.Open() && db.ScraperInUse(ID())) - return true; - } - else - { // video scraper - CVideoDatabase db; - if (db.Open() && db.ScraperInUse(ID())) - return true; - } - return false; -} - -bool CScraper::IsNoop() -{ - if (!Load()) - throw CScraperError(); - - return m_parser.IsNoop(); -} - -// pass in contents of .nfo file; returns URL (possibly empty if none found) -// and may populate strId, or throws CScraperError on error -CScraperUrl CScraper::NfoUrl(const std::string &sNfoContent) -{ - CScraperUrl scurlRet; - - if (IsNoop()) - return scurlRet; - - // scraper function takes contents of .nfo file, returns XML (see below) - vector<string> vcsIn; - vcsIn.push_back(sNfoContent); - CScraperUrl scurl; - CCurlFile fcurl; - vector<string> vcsOut = Run("NfoUrl", scurl, fcurl, &vcsIn); - if (vcsOut.empty() || vcsOut[0].empty()) - return scurlRet; - if (vcsOut.size() > 1) - CLog::Log(LOGWARNING, "%s: scraper returned multiple results; using first", __FUNCTION__); - - // parse returned XML: either <error> element on error, blank on failure, - // or <url>...</url> or <url>...</url><id>...</id> on success - for (unsigned int i=0; i < vcsOut.size(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(vcsOut[i], TIXML_ENCODING_UTF8); - CheckScraperError(doc.RootElement()); - - if (doc.RootElement()) - { - /* - NOTE: Scrapers might return invalid xml with some loose - elements (eg. '<url>http://some.url</url><id>123</id>'). - Since XMLUtils::GetString() is assuming well formed xml - with start and end-tags we're not able to use it. - Check for the desired Elements instead. - */ - TiXmlElement* pxeUrl=NULL; - TiXmlElement* pId=NULL; - if (!strcmp(doc.RootElement()->Value(),"details")) - { - pxeUrl = doc.RootElement()->FirstChildElement("url"); - pId = doc.RootElement()->FirstChildElement("id"); - } - else - { - pId = doc.FirstChildElement("id"); - pxeUrl = doc.FirstChildElement("url"); - } - if (pId && pId->FirstChild()) - scurlRet.strId = pId->FirstChild()->Value(); - - if (pxeUrl && pxeUrl->Attribute("function")) - continue; - - if (pxeUrl) - scurlRet.ParseElement(pxeUrl); - else if (!strcmp(doc.RootElement()->Value(), "url")) - scurlRet.ParseElement(doc.RootElement()); - else - continue; - break; - } - } - return scurlRet; -} - -CScraperUrl CScraper::ResolveIDToUrl(const std::string& externalID) -{ - CScraperUrl scurlRet; - - // scraper function takes an external ID, returns XML (see below) - vector<string> vcsIn; - vcsIn.push_back(externalID); - CScraperUrl scurl; - CCurlFile fcurl; - vector<string> vcsOut = Run("ResolveIDToUrl", scurl, fcurl, &vcsIn); - if (vcsOut.empty() || vcsOut[0].empty()) - return scurlRet; - if (vcsOut.size() > 1) - CLog::Log(LOGWARNING, "%s: scraper returned multiple results; using first", __FUNCTION__); - - // parse returned XML: either <error> element on error, blank on failure, - // or <url>...</url> or <url>...</url><id>...</id> on success - for (unsigned int i=0; i < vcsOut.size(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(vcsOut[i], TIXML_ENCODING_UTF8); - CheckScraperError(doc.RootElement()); - - if (doc.RootElement()) - { - /* - NOTE: Scrapers might return invalid xml with some loose - elements (eg. '<url>http://some.url</url><id>123</id>'). - Since XMLUtils::GetString() is assuming well formed xml - with start and end-tags we're not able to use it. - Check for the desired Elements instead. - */ - TiXmlElement* pxeUrl=NULL; - TiXmlElement* pId=NULL; - if (!strcmp(doc.RootElement()->Value(),"details")) - { - pxeUrl = doc.RootElement()->FirstChildElement("url"); - pId = doc.RootElement()->FirstChildElement("id"); - } - else - { - pId = doc.FirstChildElement("id"); - pxeUrl = doc.FirstChildElement("url"); - } - if (pId && pId->FirstChild()) - scurlRet.strId = pId->FirstChild()->Value(); - - if (pxeUrl && pxeUrl->Attribute("function")) - continue; - - if (pxeUrl) - scurlRet.ParseElement(pxeUrl); - else if (!strcmp(doc.RootElement()->Value(), "url")) - scurlRet.ParseElement(doc.RootElement()); - else - continue; - break; - } - } - return scurlRet; -} - -static bool RelevanceSortFunction(const CScraperUrl &left, const CScraperUrl &right) -{ - return left.relevance > right.relevance; -} - -// fetch list of matching movies sorted by relevance (may be empty); -// throws CScraperError on error; first called with fFirst set, then unset if first try fails -std::vector<CScraperUrl> CScraper::FindMovie(XFILE::CCurlFile &fcurl, const std::string &sMovie, - bool fFirst) -{ - // prepare parameters for URL creation - std::string sTitle, sTitleYear, sYear; - CUtil::CleanString(sMovie, sTitle, sTitleYear, sYear, true/*fRemoveExt*/, fFirst); - - CLog::Log(LOGDEBUG, "%s: Searching for '%s' using %s scraper " - "(path: '%s', content: '%s', version: '%s')", __FUNCTION__, sTitle.c_str(), - Name().c_str(), Path().c_str(), - ADDON::TranslateContent(Content()).c_str(), Version().asString().c_str()); - - std::vector<CScraperUrl> vcscurl; - if (IsNoop()) - return vcscurl; - - if (!fFirst) - StringUtils::Replace(sTitle, '-',' '); - - vector<string> vcsIn(1); - g_charsetConverter.utf8To(SearchStringEncoding(), sTitle, vcsIn[0]); - vcsIn[0] = CURL::Encode(vcsIn[0]); - if (fFirst && !sYear.empty()) - vcsIn.push_back(sYear); - - // request a search URL from the title/filename/etc. - CScraperUrl scurl; - vector<string> vcsOut = Run("CreateSearchUrl", scurl, fcurl, &vcsIn); - if (vcsOut.empty()) - { - CLog::Log(LOGDEBUG, "%s: CreateSearchUrl failed", __FUNCTION__); - throw CScraperError(); - } - scurl.ParseString(vcsOut[0]); - - // do the search, and parse the result into a list - vcsIn.clear(); - vcsIn.push_back(scurl.m_url[0].m_url); - vcsOut = Run("GetSearchResults", scurl, fcurl, &vcsIn); - - bool fSort(true); - std::set<std::string> stsDupeCheck; - bool fResults(false); - for (vector<string>::const_iterator i = vcsOut.begin(); i != vcsOut.end(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(*i, TIXML_ENCODING_UTF8); - if (!doc.RootElement()) - { - CLog::Log(LOGERROR, "%s: Unable to parse XML", __FUNCTION__); - continue; // might have more valid results later - } - - CheckScraperError(doc.RootElement()); - - TiXmlHandle xhDoc(&doc); - TiXmlHandle xhResults = xhDoc.FirstChild("results"); - if (!xhResults.Element()) - continue; - fResults = true; // even if empty - - // we need to sort if returned results don't specify 'sorted="yes"' - if (fSort) - { - const char *sorted = xhResults.Element()->Attribute("sorted"); - if (sorted != NULL) - fSort = !StringUtils::EqualsNoCase(sorted, "yes"); - } - - for (TiXmlElement *pxeMovie = xhResults.FirstChild("entity").Element(); - pxeMovie; pxeMovie = pxeMovie->NextSiblingElement()) - { - CScraperUrl scurlMovie; - TiXmlNode *pxnTitle = pxeMovie->FirstChild("title"); - TiXmlElement *pxeLink = pxeMovie->FirstChildElement("url"); - if (pxnTitle && pxnTitle->FirstChild() && pxeLink && pxeLink->FirstChild()) - { - scurlMovie.strTitle = pxnTitle->FirstChild()->Value(); - XMLUtils::GetString(pxeMovie, "id", scurlMovie.strId); - - for ( ; pxeLink && pxeLink->FirstChild(); pxeLink = pxeLink->NextSiblingElement("url")) - scurlMovie.ParseElement(pxeLink); - - // calculate the relavance of this hit - std::string sCompareTitle = scurlMovie.strTitle; - StringUtils::ToLower(sCompareTitle); - std::string sMatchTitle = sTitle; - StringUtils::ToLower(sMatchTitle); - - /* - * Identify the best match by performing a fuzzy string compare on the search term and - * the result. Additionally, use the year (if available) to further refine the best match. - * An exact match scores 1, a match off by a year scores 0.5 (release dates can vary between - * countries), otherwise it scores 0. - */ - std::string sCompareYear; - XMLUtils::GetString(pxeMovie, "year", sCompareYear); - - double yearScore = 0; - if (!sYear.empty() && !sCompareYear.empty()) - yearScore = std::max(0.0, 1-0.5*abs(atoi(sYear.c_str())-atoi(sCompareYear.c_str()))); - - scurlMovie.relevance = fstrcmp(sMatchTitle.c_str(), sCompareTitle.c_str(), 0.0) + yearScore; - - // reconstruct a title for the user - if (!sCompareYear.empty()) - scurlMovie.strTitle += StringUtils::Format(" (%s)", sCompareYear.c_str()); - - std::string sLanguage; - if (XMLUtils::GetString(pxeMovie, "language", sLanguage) && !sLanguage.empty()) - scurlMovie.strTitle += StringUtils::Format(" (%s)", sLanguage.c_str()); - - // filter for dupes from naughty scrapers - if (stsDupeCheck.insert(scurlMovie.m_url[0].m_url + " " + scurlMovie.strTitle).second) - vcscurl.push_back(scurlMovie); - } - } - } - - if (!fResults) - throw CScraperError(); // scraper aborted - - if (fSort) - std::stable_sort(vcscurl.begin(), vcscurl.end(), RelevanceSortFunction); - - return vcscurl; -} - -// find album by artist, using fcurl for web fetches -// returns a list of albums (empty if no match or failure) -std::vector<CMusicAlbumInfo> CScraper::FindAlbum(CCurlFile &fcurl, const std::string &sAlbum, - const std::string &sArtist) -{ - CLog::Log(LOGDEBUG, "%s: Searching for '%s - %s' using %s scraper " - "(path: '%s', content: '%s', version: '%s')", __FUNCTION__, sArtist.c_str(), - sAlbum.c_str(), Name().c_str(), Path().c_str(), - ADDON::TranslateContent(Content()).c_str(), Version().asString().c_str()); - - std::vector<CMusicAlbumInfo> vcali; - if (IsNoop()) - return vcali; - - // scraper function is given the album and artist as parameters and - // returns an XML <url> element parseable by CScraperUrl - std::vector<string> extras(2); - g_charsetConverter.utf8To(SearchStringEncoding(), sAlbum, extras[0]); - g_charsetConverter.utf8To(SearchStringEncoding(), sArtist, extras[1]); - extras[0] = CURL::Encode(extras[0]); - extras[1] = CURL::Encode(extras[1]); - CScraperUrl scurl; - vector<string> vcsOut = RunNoThrow("CreateAlbumSearchUrl", scurl, fcurl, &extras); - if (vcsOut.size() > 1) - CLog::Log(LOGWARNING, "%s: scraper returned multiple results; using first", __FUNCTION__); - - if (vcsOut.empty() || vcsOut[0].empty()) - return vcali; - scurl.ParseString(vcsOut[0]); - - // the next function is passed the contents of the returned URL, and returns - // an empty string on failure; on success, returns XML matches in the form: - // <results> - // <entity> - // <title>... - // ... (with the usual CScraperUrl decorations like post or spoof) - // ... - // ... - // ... (scale defaults to 1; score is divided by it) - // - // ... - // - vcsOut = RunNoThrow("GetAlbumSearchResults", scurl, fcurl); - - // parse the returned XML into a vector of album objects - for (vector::const_iterator i = vcsOut.begin(); i != vcsOut.end(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(*i, TIXML_ENCODING_UTF8); - TiXmlHandle xhDoc(&doc); - - for (TiXmlElement* pxeAlbum = xhDoc.FirstChild("results").FirstChild("entity").Element(); - pxeAlbum; pxeAlbum = pxeAlbum->NextSiblingElement()) - { - std::string sTitle; - if (XMLUtils::GetString(pxeAlbum, "title", sTitle) && !sTitle.empty()) - { - std::string sArtist; - std::string sAlbumName; - if (XMLUtils::GetString(pxeAlbum, "artist", sArtist) && !sArtist.empty()) - sAlbumName = StringUtils::Format("%s - %s", sArtist.c_str(), sTitle.c_str()); - else - sAlbumName = sTitle; - - std::string sYear; - if (XMLUtils::GetString(pxeAlbum, "year", sYear) && !sYear.empty()) - sAlbumName = StringUtils::Format("%s (%s)", sAlbumName.c_str(), sYear.c_str()); - - // if no URL is provided, use the URL we got back from CreateAlbumSearchUrl - // (e.g., in case we only got one result back and were sent to the detail page) - TiXmlElement* pxeLink = pxeAlbum->FirstChildElement("url"); - CScraperUrl scurlAlbum; - if (!pxeLink) - scurlAlbum.ParseString(scurl.m_xml); - for ( ; pxeLink && pxeLink->FirstChild(); pxeLink = pxeLink->NextSiblingElement("url")) - scurlAlbum.ParseElement(pxeLink); - - if (!scurlAlbum.m_url.size()) - continue; - - CMusicAlbumInfo ali(sTitle, sArtist, sAlbumName, scurlAlbum); - - TiXmlElement* pxeRel = pxeAlbum->FirstChildElement("relevance"); - if (pxeRel && pxeRel->FirstChild()) - { - const char* szScale = pxeRel->Attribute("scale"); - float flScale = szScale ? float(atof(szScale)) : 1; - ali.SetRelevance(float(atof(pxeRel->FirstChild()->Value())) / flScale); - } - - vcali.push_back(ali); - } - } - } - return vcali; -} - -// find artist, using fcurl for web fetches -// returns a list of artists (empty if no match or failure) -std::vector CScraper::FindArtist(CCurlFile &fcurl, - const std::string &sArtist) -{ - CLog::Log(LOGDEBUG, "%s: Searching for '%s' using %s scraper " - "(file: '%s', content: '%s', version: '%s')", __FUNCTION__, sArtist.c_str(), - Name().c_str(), Path().c_str(), - ADDON::TranslateContent(Content()).c_str(), Version().asString().c_str()); - - std::vector vcari; - if (IsNoop()) - return vcari; - - // scraper function is given the artist as parameter and - // returns an XML element parseable by CScraperUrl - std::vector extras(1); - g_charsetConverter.utf8To(SearchStringEncoding(), sArtist, extras[0]); - extras[0] = CURL::Encode(extras[0]); - CScraperUrl scurl; - vector vcsOut = RunNoThrow("CreateArtistSearchUrl", scurl, fcurl, &extras); - - if (vcsOut.empty() || vcsOut[0].empty()) - return vcari; - scurl.ParseString(vcsOut[0]); - - // the next function is passed the contents of the returned URL, and returns - // an empty string on failure; on success, returns XML matches in the form: - // - // - // ... - // ... - // ... - // ... (with the usual CScraperUrl decorations like post or spoof) - // - // ... - // - vcsOut = RunNoThrow("GetArtistSearchResults", scurl, fcurl); - - // parse the returned XML into a vector of artist objects - for (vector::const_iterator i = vcsOut.begin(); i != vcsOut.end(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(*i, TIXML_ENCODING_UTF8); - if (!doc.RootElement()) - { - CLog::Log(LOGERROR, "%s: Unable to parse XML", __FUNCTION__); - return vcari; - } - TiXmlHandle xhDoc(&doc); - for (TiXmlElement* pxeArtist = xhDoc.FirstChild("results").FirstChild("entity").Element(); - pxeArtist; pxeArtist = pxeArtist->NextSiblingElement()) - { - TiXmlNode* pxnTitle = pxeArtist->FirstChild("title"); - if (pxnTitle && pxnTitle->FirstChild()) - { - CScraperUrl scurlArtist; - - TiXmlElement* pxeLink = pxeArtist->FirstChildElement("url"); - if (!pxeLink) - scurlArtist.ParseString(scurl.m_xml); - for ( ; pxeLink && pxeLink->FirstChild(); pxeLink = pxeLink->NextSiblingElement("url")) - scurlArtist.ParseElement(pxeLink); - - if (!scurlArtist.m_url.size()) - continue; - - CMusicArtistInfo ari(pxnTitle->FirstChild()->Value(), scurlArtist); - std::string genre; - XMLUtils::GetString(pxeArtist, "genre", genre); - if (!genre.empty()) - ari.GetArtist().genre = StringUtils::Split(genre, g_advancedSettings.m_musicItemSeparator); - XMLUtils::GetString(pxeArtist, "year", ari.GetArtist().strBorn); - - vcari.push_back(ari); - } - } - } - return vcari; -} - -// fetch list of episodes from URL (from video database) -EPISODELIST CScraper::GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl) -{ - EPISODELIST vcep; - if (scurl.m_url.empty()) - return vcep; - - CLog::Log(LOGDEBUG, "%s: Searching '%s' using %s scraper " - "(file: '%s', content: '%s', version: '%s')", __FUNCTION__, - scurl.m_url[0].m_url.c_str(), Name().c_str(), Path().c_str(), - ADDON::TranslateContent(Content()).c_str(), Version().asString().c_str()); - - vector vcsIn; - vcsIn.push_back(scurl.m_url[0].m_url); - vector vcsOut = RunNoThrow("GetEpisodeList", scurl, fcurl, &vcsIn); - - // parse the XML response - for (vector::const_iterator i = vcsOut.begin(); i != vcsOut.end(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(*i); - if (!doc.RootElement()) - { - CLog::Log(LOGERROR, "%s: Unable to parse XML",__FUNCTION__); - continue; - } - - TiXmlHandle xhDoc(&doc); - for (TiXmlElement *pxeMovie = xhDoc.FirstChild("episodeguide").FirstChild("episode"). - Element(); pxeMovie; pxeMovie = pxeMovie->NextSiblingElement()) - { - EPISODE ep; - TiXmlElement *pxeLink = pxeMovie->FirstChildElement("url"); - std::string strEpNum; - if (pxeLink && XMLUtils::GetInt(pxeMovie, "season", ep.iSeason) && - XMLUtils::GetString(pxeMovie, "epnum", strEpNum) && !strEpNum.empty()) - { - CScraperUrl &scurlEp(ep.cScraperUrl); - size_t dot = strEpNum.find("."); - ep.iEpisode = atoi(strEpNum.c_str()); - ep.iSubepisode = (dot != std::string::npos) ? atoi(strEpNum.substr(dot + 1).c_str()) : 0; - if (!XMLUtils::GetString(pxeMovie, "title", scurlEp.strTitle) || scurlEp.strTitle.empty() ) - scurlEp.strTitle = g_localizeStrings.Get(416); - XMLUtils::GetString(pxeMovie, "id", scurlEp.strId); - - for ( ; pxeLink && pxeLink->FirstChild(); pxeLink = pxeLink->NextSiblingElement("url")) - scurlEp.ParseElement(pxeLink); - - // date must be the format of yyyy-mm-dd - ep.cDate.SetValid(FALSE); - std::string sDate; - if (XMLUtils::GetString(pxeMovie, "aired", sDate) && sDate.length() == 10) - { - tm tm; - if (strptime(sDate.c_str(), "%Y-%m-%d", &tm)) - ep.cDate.SetDate(1900+tm.tm_year, tm.tm_mon + 1, tm.tm_mday); - } - vcep.push_back(ep); - } - } - } - - return vcep; -} - -// takes URL; returns true and populates video details on success, false otherwise -bool CScraper::GetVideoDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl, - bool fMovie/*else episode*/, CVideoInfoTag &video) -{ - CLog::Log(LOGDEBUG, "%s: Reading %s '%s' using %s scraper " - "(file: '%s', content: '%s', version: '%s')", __FUNCTION__, - fMovie ? MediaTypeMovie : MediaTypeEpisode, scurl.m_url[0].m_url.c_str(), Name().c_str(), Path().c_str(), - ADDON::TranslateContent(Content()).c_str(), Version().asString().c_str()); - - video.Reset(); - std::string sFunc = fMovie ? "GetDetails" : "GetEpisodeDetails"; - vector vcsIn; - vcsIn.push_back(scurl.strId); - vcsIn.push_back(scurl.m_url[0].m_url); - vector vcsOut = RunNoThrow(sFunc, scurl, fcurl, &vcsIn); - - // parse XML output - bool fRet(false); - for (vector::const_iterator i = vcsOut.begin(); i != vcsOut.end(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(*i, TIXML_ENCODING_UTF8); - if (!doc.RootElement()) - { - CLog::Log(LOGERROR, "%s: Unable to parse XML", __FUNCTION__); - continue; - } - - TiXmlHandle xhDoc(&doc); - TiXmlElement *pxeDetails = xhDoc.FirstChild("details").Element(); - if (!pxeDetails) - { - CLog::Log(LOGERROR, "%s: Invalid XML file (want
)", __FUNCTION__); - continue; - } - video.Load(pxeDetails, true/*fChain*/); - fRet = true; // but don't exit in case of chaining - } - return fRet; -} - -// takes a URL; returns true and populates album on success, false otherwise -bool CScraper::GetAlbumDetails(CCurlFile &fcurl, const CScraperUrl &scurl, CAlbum &album) -{ - CLog::Log(LOGDEBUG, "%s: Reading '%s' using %s scraper " - "(file: '%s', content: '%s', version: '%s')", __FUNCTION__, - scurl.m_url[0].m_url.c_str(), Name().c_str(), Path().c_str(), - ADDON::TranslateContent(Content()).c_str(), Version().asString().c_str()); - - vector vcsOut = RunNoThrow("GetAlbumDetails", scurl, fcurl); - - // parse the returned XML into an album object (see CAlbum::Load for details) - bool fRet(false); - for (vector::const_iterator i = vcsOut.begin(); i != vcsOut.end(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(*i, TIXML_ENCODING_UTF8); - if (!doc.RootElement()) - { - CLog::Log(LOGERROR, "%s: Unable to parse XML", __FUNCTION__); - return false; - } - fRet = album.Load(doc.RootElement(), i != vcsOut.begin()); - } - return fRet; -} - -// takes a URL (one returned from FindArtist), the original search string, and -// returns true and populates artist on success, false on failure -bool CScraper::GetArtistDetails(CCurlFile &fcurl, const CScraperUrl &scurl, - const std::string &sSearch, CArtist &artist) -{ - if (!scurl.m_url.size()) - return false; - - CLog::Log(LOGDEBUG, "%s: Reading '%s' ('%s') using %s scraper " - "(file: '%s', content: '%s', version: '%s')", __FUNCTION__, - scurl.m_url[0].m_url.c_str(), sSearch.c_str(), Name().c_str(), Path().c_str(), - ADDON::TranslateContent(Content()).c_str(), Version().asString().c_str()); - - // pass in the original search string for chaining to search other sites - vector vcIn; - vcIn.push_back(sSearch); - vcIn[0] = CURL::Encode(vcIn[0]); - - vector vcsOut = RunNoThrow("GetArtistDetails", scurl, fcurl, &vcIn); - - // ok, now parse the xml file - bool fRet(false); - for (vector::const_iterator i = vcsOut.begin(); i != vcsOut.end(); ++i) - { - CXBMCTinyXML doc; - doc.Parse(*i, TIXML_ENCODING_UTF8); - if (!doc.RootElement()) - { - CLog::Log(LOGERROR, "%s: Unable to parse XML", __FUNCTION__); - return false; - } - - fRet = artist.Load(doc.RootElement(), i != vcsOut.begin()); - } - return fRet; -} - -} - diff --git a/xbmc/addons/Scraper.h b/xbmc/addons/Scraper.h deleted file mode 100644 index 7302972..0000000 --- a/xbmc/addons/Scraper.h +++ /dev/null @@ -1,178 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "addons/Addon.h" -#include "XBDateTime.h" -#include "utils/ScraperUrl.h" -#include "utils/ScraperParser.h" -#include "video/Episode.h" - -class CAlbum; -class CArtist; -class CVideoInfoTag; - -namespace MUSIC_GRABBER -{ -class CMusicAlbumInfo; -class CMusicArtistInfo; -} - -typedef enum -{ - CONTENT_MOVIES, - CONTENT_TVSHOWS, - CONTENT_MUSICVIDEOS, - CONTENT_ALBUMS, - CONTENT_ARTISTS, - CONTENT_NONE, -} CONTENT_TYPE; - -namespace XFILE -{ - class CCurlFile; -} - -class CScraperUrl; - -namespace ADDON -{ -class CScraper; -typedef std::shared_ptr ScraperPtr; - -std::string TranslateContent(const CONTENT_TYPE &content, bool pretty=false); -CONTENT_TYPE TranslateContent(const std::string &string); -TYPE ScraperTypeFromContent(const CONTENT_TYPE &content); - -// thrown as exception to signal abort or show error dialog -class CScraperError -{ -public: - CScraperError() : m_fAborted(true) {} - CScraperError(const std::string &sTitle, const std::string &sMessage) : - m_fAborted(false), m_sTitle(sTitle), m_sMessage(sMessage) {} - - bool FAborted() const { return m_fAborted; } - const std::string &Title() const { return m_sTitle; } - const std::string &Message() const { return m_sMessage; } - -private: - bool m_fAborted; - std::string m_sTitle; - std::string m_sMessage; -}; - -class CScraper : public CAddon -{ -public: - CScraper(const AddonProps &props) : CAddon(props), m_fLoaded(false) {} - CScraper(const cp_extension_t *ext); - virtual ~CScraper() {} - virtual AddonPtr Clone() const; - - /*! \brief Set the scraper settings for a particular path from an XML string - Loads the default and user settings (if not already loaded) and, if the given XML string is non-empty, - overrides the user settings with the XML. - \param content Content type of the path - \param xml string of XML with the settings. If non-empty this overrides any saved user settings. - \return true if settings are available, false otherwise - \sa GetPathSettings - */ - bool SetPathSettings(CONTENT_TYPE content, const std::string& xml); - - /*! \brief Get the scraper settings for a particular path in the form of an XML string - Loads the default and user settings (if not already loaded) and returns the user settings in the - form or an XML string - \return a string containing the XML settings - \sa SetPathSettings - */ - std::string GetPathSettings(); - - /*! \brief Clear any previously cached results for this scraper - Any previously cached files are cleared if they have been cached for longer than the specified - cachepersistence. - */ - void ClearCache(); - - CONTENT_TYPE Content() const { return m_pathContent; } - const std::string& Language() const { return m_language; } - bool RequiresSettings() const { return m_requiressettings; } - bool Supports(const CONTENT_TYPE &content) const; - - bool IsInUse() const; - bool IsNoop(); - - // scraper media functions - CScraperUrl NfoUrl(const std::string &sNfoContent); - - /*! \brief Resolve an external ID (e.g. MusicBrainz IDs) to a URL using scrapers - If we have an ID in hand, e.g. MusicBrainz IDs or TheTVDB Season IDs - we can get directly to a URL instead of searching by name and choosing from - the search results. The correct scraper type should be used to get the right - URL for a given ID, so we can differentiate albums, artists, TV Seasons, etc. - \param externalID the external ID - e.g. MusicBrainzArtist/AlbumID - \return a populated URL pointing to the details page for the given ID or - an empty URL if we couldn't resolve the ID. - */ - CScraperUrl ResolveIDToUrl(const std::string &externalID); - - std::vector FindMovie(XFILE::CCurlFile &fcurl, - const std::string &sMovie, bool fFirst); - std::vector FindAlbum(XFILE::CCurlFile &fcurl, - const std::string &sAlbum, const std::string &sArtist = ""); - std::vector FindArtist( - XFILE::CCurlFile &fcurl, const std::string &sArtist); - VIDEO::EPISODELIST GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl); - - bool GetVideoDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl, - bool fMovie/*else episode*/, CVideoInfoTag &video); - bool GetAlbumDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl, - CAlbum &album); - bool GetArtistDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl, - const std::string &sSearch, CArtist &artist); - -private: - CScraper(const CScraper &rhs); - std::string SearchStringEncoding() const - { return m_parser.GetSearchStringEncoding(); } - - bool Load(); - std::vector Run(const std::string& function, - const CScraperUrl& url, - XFILE::CCurlFile& http, - const std::vector* extras = NULL); - std::vector RunNoThrow(const std::string& function, - const CScraperUrl& url, - XFILE::CCurlFile& http, - const std::vector* extras = NULL); - std::string InternalRun(const std::string& function, - const CScraperUrl& url, - XFILE::CCurlFile& http, - const std::vector* extras); - - bool m_fLoaded; - std::string m_language; - bool m_requiressettings; - CDateTimeSpan m_persistence; - CONTENT_TYPE m_pathContent; - CScraperParser m_parser; -}; - -} - diff --git a/xbmc/addons/ScreenSaver.cpp b/xbmc/addons/ScreenSaver.cpp deleted file mode 100644 index ef345f5..0000000 --- a/xbmc/addons/ScreenSaver.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "ScreenSaver.h" -#include "guilib/GraphicContext.h" -#include "interfaces/generic/ScriptInvocationManager.h" -#include "settings/DisplaySettings.h" -#include "utils/AlarmClock.h" -#include "windowing/WindowingFactory.h" - -// What sound does a python screensaver make? -#define SCRIPT_ALARM "sssssscreensaver" - -#define SCRIPT_TIMEOUT 5 // seconds - -namespace ADDON -{ - - CScreenSaver::CScreenSaver(const char *addonID) - : ADDON::CAddonDll(AddonProps(addonID, ADDON_UNKNOWN, "", "")) - { - } - -AddonPtr CScreenSaver::Clone() const -{ - // Copy constructor is generated by compiler and calls parent copy constructor - return AddonPtr(new CScreenSaver(*this)); -} - -bool CScreenSaver::CreateScreenSaver() -{ - if (CScriptInvocationManager::Get().HasLanguageInvoker(LibPath())) - { - // Don't allow a previously-scheduled alarm to kill our new screensaver - g_alarmClock.Stop(SCRIPT_ALARM, true); - - if (!CScriptInvocationManager::Get().Stop(LibPath())) - CScriptInvocationManager::Get().ExecuteAsync(LibPath(), Clone()); - return true; - } - // pass it the screen width,height - // and the name of the screensaver - int iWidth = g_graphicsContext.GetWidth(); - int iHeight = g_graphicsContext.GetHeight(); - - m_pInfo = new SCR_PROPS; -#ifdef HAS_DX - m_pInfo->device = g_Windowing.Get3DDevice(); -#else - m_pInfo->device = NULL; -#endif - m_pInfo->x = 0; - m_pInfo->y = 0; - m_pInfo->width = iWidth; - m_pInfo->height = iHeight; - m_pInfo->pixelRatio = g_graphicsContext.GetResInfo().fPixelRatio; - m_pInfo->name = strdup(Name().c_str()); - m_pInfo->presets = strdup(CSpecialProtocol::TranslatePath(Path()).c_str()); - m_pInfo->profile = strdup(CSpecialProtocol::TranslatePath(Profile()).c_str()); - - if (CAddonDll::Create() == ADDON_STATUS_OK) - return true; - - return false; -} - -void CScreenSaver::Start() -{ - // notify screen saver that they should start - if (Initialized()) m_pStruct->Start(); -} - -void CScreenSaver::Render() -{ - // ask screensaver to render itself - if (Initialized()) m_pStruct->Render(); -} - -void CScreenSaver::GetInfo(SCR_INFO *info) -{ - // get info from screensaver - if (Initialized()) m_pStruct->GetInfo(info); -} - -void CScreenSaver::Destroy() -{ -#ifdef HAS_PYTHON - if (URIUtils::HasExtension(LibPath(), ".py")) - { - g_alarmClock.Start(SCRIPT_ALARM, SCRIPT_TIMEOUT, "StopScript(" + LibPath() + ")", true, false); - return; - } -#endif - // Release what was allocated in method CScreenSaver::CreateScreenSaver. - if (m_pInfo) - { - free((void *) m_pInfo->name); - free((void *) m_pInfo->presets); - free((void *) m_pInfo->profile); - - delete m_pInfo; - m_pInfo = NULL; - } - - CAddonDll::Destroy(); -} - -} /*namespace ADDON*/ - diff --git a/xbmc/addons/ScreenSaver.h b/xbmc/addons/ScreenSaver.h deleted file mode 100644 index 1b2a741..0000000 --- a/xbmc/addons/ScreenSaver.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#pragma once - -#include "AddonDll.h" -#include "include/xbmc_scr_types.h" - -typedef DllAddon DllScreenSaver; - -namespace ADDON -{ - -class CScreenSaver : public ADDON::CAddonDll -{ -public: - CScreenSaver(const AddonProps &props) : ADDON::CAddonDll(props) {}; - CScreenSaver(const cp_extension_t *ext) : ADDON::CAddonDll(ext) {}; - CScreenSaver(const char *addonID); - virtual ~CScreenSaver() {} - virtual AddonPtr Clone() const; - - // Things that MUST be supplied by the child classes - bool CreateScreenSaver(); - void Start(); - void Render(); - void GetInfo(SCR_INFO *info); - void Destroy(); -}; - -} /*namespace ADDON*/ diff --git a/xbmc/addons/Service.cpp b/xbmc/addons/Service.cpp deleted file mode 100644 index 2fc7670..0000000 --- a/xbmc/addons/Service.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "Service.h" -#include "AddonManager.h" -#include "interfaces/generic/ScriptInvocationManager.h" -#include "utils/log.h" -#include "system.h" - -using namespace std; - -namespace ADDON -{ - -CService::CService(const cp_extension_t *ext) - : CAddon(ext), m_type(UNKNOWN), m_startOption(LOGIN) -{ - BuildServiceType(); - - std::string start = CAddonMgr::Get().GetExtValue(ext->configuration, "@start"); - if (start == "startup") - m_startOption = STARTUP; -} - - -CService::CService(const AddonProps &props) - : CAddon(props), m_type(UNKNOWN), m_startOption(LOGIN) -{ - BuildServiceType(); -} - -AddonPtr CService::Clone() const -{ - return AddonPtr(new CService(*this)); -} - -bool CService::Start() -{ - bool ret = true; - switch (m_type) - { -#ifdef HAS_PYTHON - case PYTHON: - ret = (CScriptInvocationManager::Get().ExecuteAsync(LibPath(), this->shared_from_this()) != -1); - break; -#endif - - case UNKNOWN: - default: - ret = false; - break; - } - - return ret; -} - -bool CService::Stop() -{ - bool ret = true; - - switch (m_type) - { -#ifdef HAS_PYTHON - case PYTHON: - ret = CScriptInvocationManager::Get().Stop(LibPath()); - break; -#endif - - case UNKNOWN: - default: - ret = false; - break; - } - - return ret; -} - -void CService::BuildServiceType() -{ - std::string str = LibPath(); - std::string ext; - - size_t p = str.find_last_of('.'); - if (p != string::npos) - ext = str.substr(p + 1); - -#ifdef HAS_PYTHON - std::string pythonExt = ADDON_PYTHON_EXT; - pythonExt.erase(0, 2); - if ( ext == pythonExt ) - m_type = PYTHON; - else -#endif - { - m_type = UNKNOWN; - CLog::Log(LOGERROR, "ADDON: extension '%s' is not currently supported for service addon", ext.c_str()); - } -} - -void CService::OnDisabled() -{ - Stop(); -} - -void CService::OnEnabled() -{ - Start(); -} - -bool CService::OnPreInstall() -{ - // make sure the addon is stopped - AddonPtr localAddon; // need to grab the local addon so we have the correct library path to stop - if (CAddonMgr::Get().GetAddon(ID(), localAddon, ADDON_SERVICE, false)) - { - std::shared_ptr service = std::dynamic_pointer_cast(localAddon); - if (service) - service->Stop(); - } - return !CAddonMgr::Get().IsAddonDisabled(ID()); -} - -void CService::OnPostInstall(bool restart, bool update, bool modal) -{ - if (restart) // reload/start it if it was running - { - AddonPtr localAddon; // need to grab the local addon so we have the correct library path to stop - if (CAddonMgr::Get().GetAddon(ID(), localAddon, ADDON_SERVICE, false)) - { - std::shared_ptr service = std::dynamic_pointer_cast(localAddon); - if (service) - service->Start(); - } - } -} - -void CService::OnPreUnInstall() -{ - Stop(); -} - -} diff --git a/xbmc/addons/Service.h b/xbmc/addons/Service.h deleted file mode 100644 index f7394de..0000000 --- a/xbmc/addons/Service.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "Addon.h" - -namespace ADDON -{ - - class CService: public CAddon - { - public: - - enum TYPE - { - UNKNOWN, - PYTHON - }; - - enum START_OPTION - { - STARTUP, - LOGIN - }; - - CService(const cp_extension_t *ext); - CService(const AddonProps &props); - virtual AddonPtr Clone() const; - - bool Start(); - bool Stop(); - TYPE GetServiceType() { return m_type; } - START_OPTION GetStartOption() { return m_startOption; } - virtual void OnDisabled(); - virtual void OnEnabled(); - virtual bool OnPreInstall(); - virtual void OnPostInstall(bool restart, bool update, bool modal); - virtual void OnPreUnInstall(); - - protected: - void BuildServiceType(); - - private: - TYPE m_type; - START_OPTION m_startOption; - }; -} diff --git a/xbmc/addons/Skin.cpp b/xbmc/addons/Skin.cpp deleted file mode 100644 index acb5799..0000000 --- a/xbmc/addons/Skin.cpp +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "Skin.h" -#include "AddonManager.h" -#include "LangInfo.h" -#include "Util.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "dialogs/GUIDialogYesNo.h" -#include "filesystem/File.h" -#include "filesystem/SpecialProtocol.h" -#include "guilib/GUIWindowManager.h" -#include "guilib/WindowIDs.h" -#include "settings/Settings.h" -#include "settings/lib/Setting.h" -#include "utils/URIUtils.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "ApplicationMessenger.h" - -// fallback for new skin resolution code -#include "filesystem/Directory.h" - -using namespace std; -using namespace XFILE; - -std::shared_ptr g_SkinInfo; - -namespace ADDON -{ - -CSkinInfo::CSkinInfo(const AddonProps &props, const RESOLUTION_INFO &resolution) - : CAddon(props), m_defaultRes(resolution), m_version(""), m_effectsSlowDown(1.f), m_debugging(false) -{ -} - -CSkinInfo::CSkinInfo(const cp_extension_t *ext) - : CAddon(ext), m_version(""), m_effectsSlowDown(1.f) -{ - ELEMENTS elements; - if (CAddonMgr::Get().GetExtElements(ext->configuration, "res", elements)) - { - for (ELEMENTS::iterator i = elements.begin(); i != elements.end(); ++i) - { - int width = atoi(CAddonMgr::Get().GetExtValue(*i, "@width").c_str()); - int height = atoi(CAddonMgr::Get().GetExtValue(*i, "@height").c_str()); - bool defRes = CAddonMgr::Get().GetExtValue(*i, "@default") == "true"; - std::string folder = CAddonMgr::Get().GetExtValue(*i, "@folder"); - float aspect = 0; - std::string strAspect = CAddonMgr::Get().GetExtValue(*i, "@aspect"); - vector fracs = StringUtils::Split(strAspect, ':'); - if (fracs.size() == 2) - aspect = (float)(atof(fracs[0].c_str())/atof(fracs[1].c_str())); - if (width > 0 && height > 0) - { - RESOLUTION_INFO res(width, height, aspect, folder); - res.strId = strAspect; // for skin usage, store aspect string in strId - if (defRes) - m_defaultRes = res; - m_resolutions.push_back(res); - } - } - } - else - { // no resolutions specified -> backward compatibility - std::string defaultWide = CAddonMgr::Get().GetExtValue(ext->configuration, "@defaultwideresolution"); - if (defaultWide.empty()) - defaultWide = CAddonMgr::Get().GetExtValue(ext->configuration, "@defaultresolution"); - TranslateResolution(defaultWide, m_defaultRes); - } - - std::string str = CAddonMgr::Get().GetExtValue(ext->configuration, "@effectslowdown"); - if (!str.empty()) - m_effectsSlowDown = (float)atof(str.c_str()); - - m_debugging = CAddonMgr::Get().GetExtValue(ext->configuration, "@debugging") == "true"; - - LoadStartupWindows(ext); - - // figure out the version - m_version = GetDependencyVersion("xbmc.gui"); -} - -CSkinInfo::~CSkinInfo() -{ -} - -AddonPtr CSkinInfo::Clone() const -{ - return AddonPtr(new CSkinInfo(*this)); -} - -struct closestRes -{ - closestRes(const RESOLUTION_INFO &target) : m_target(target) { }; - bool operator()(const RESOLUTION_INFO &i, const RESOLUTION_INFO &j) - { - float diff = fabs(i.DisplayRatio() - m_target.DisplayRatio()) - fabs(j.DisplayRatio() - m_target.DisplayRatio()); - if (diff < 0) return true; - if (diff > 0) return false; - diff = fabs((float)i.iHeight - m_target.iHeight) - fabs((float)j.iHeight - m_target.iHeight); - if (diff < 0) return true; - if (diff > 0) return false; - return fabs((float)i.iWidth - m_target.iWidth) < fabs((float)j.iWidth - m_target.iWidth); - } - RESOLUTION_INFO m_target; -}; - -void CSkinInfo::Start() -{ - if (!m_resolutions.size()) - { // try falling back to whatever resolutions exist in the directory - CFileItemList items; - CDirectory::GetDirectory(Path(), items, "", DIR_FLAG_NO_FILE_DIRS); - for (int i = 0; i < items.Size(); i++) - { - RESOLUTION_INFO res; - if (items[i]->m_bIsFolder && TranslateResolution(items[i]->GetLabel(), res)) - m_resolutions.push_back(res); - } - } - - if (!m_resolutions.empty()) - { - // find the closest resolution - const RESOLUTION_INFO &target = g_graphicsContext.GetResInfo(); - RESOLUTION_INFO& res = *std::min_element(m_resolutions.begin(), m_resolutions.end(), closestRes(target)); - m_currentAspect = res.strId; - } -} - -std::string CSkinInfo::GetSkinPath(const std::string& strFile, RESOLUTION_INFO *res, const std::string& strBaseDir /* = "" */) const -{ - if (m_resolutions.empty()) - return ""; // invalid skin - - std::string strPathToUse = Path(); - if (!strBaseDir.empty()) - strPathToUse = strBaseDir; - - // if the caller doesn't care about the resolution just use a temporary - RESOLUTION_INFO tempRes; - if (!res) - res = &tempRes; - - // find the closest resolution - const RESOLUTION_INFO &target = g_graphicsContext.GetResInfo(); - *res = *std::min_element(m_resolutions.begin(), m_resolutions.end(), closestRes(target)); - - std::string strPath = URIUtils::AddFileToFolder(strPathToUse, res->strMode); - strPath = URIUtils::AddFileToFolder(strPath, strFile); - if (CFile::Exists(strPath)) - return strPath; - - // use the default resolution - *res = m_defaultRes; - - strPath = URIUtils::AddFileToFolder(strPathToUse, res->strMode); - strPath = URIUtils::AddFileToFolder(strPath, strFile); - return strPath; -} - -bool CSkinInfo::HasSkinFile(const std::string &strFile) const -{ - return CFile::Exists(GetSkinPath(strFile)); -} - -void CSkinInfo::LoadIncludes() -{ - std::string includesPath = CSpecialProtocol::TranslatePathConvertCase(GetSkinPath("includes.xml")); - CLog::Log(LOGINFO, "Loading skin includes from %s", includesPath.c_str()); - m_includes.ClearIncludes(); - m_includes.LoadIncludes(includesPath); -} - -void CSkinInfo::ResolveIncludes(TiXmlElement *node, std::map* xmlIncludeConditions /* = NULL */) -{ - if(xmlIncludeConditions) - xmlIncludeConditions->clear(); - - m_includes.ResolveIncludes(node, xmlIncludeConditions); -} - -int CSkinInfo::GetStartWindow() const -{ - int windowID = CSettings::Get().GetInt("lookandfeel.startupwindow"); - assert(m_startupWindows.size()); - for (vector::const_iterator it = m_startupWindows.begin(); it != m_startupWindows.end(); ++it) - { - if (windowID == (*it).m_id) - return windowID; - } - // return our first one - return m_startupWindows[0].m_id; -} - -bool CSkinInfo::LoadStartupWindows(const cp_extension_t *ext) -{ - m_startupWindows.clear(); - m_startupWindows.push_back(CStartupWindow(WINDOW_HOME, "513")); - m_startupWindows.push_back(CStartupWindow(WINDOW_TV_CHANNELS, "19180")); - m_startupWindows.push_back(CStartupWindow(WINDOW_RADIO_CHANNELS, "19183")); - m_startupWindows.push_back(CStartupWindow(WINDOW_PROGRAMS, "0")); - m_startupWindows.push_back(CStartupWindow(WINDOW_PICTURES, "1")); - m_startupWindows.push_back(CStartupWindow(WINDOW_MUSIC, "2")); - m_startupWindows.push_back(CStartupWindow(WINDOW_VIDEOS, "3")); - m_startupWindows.push_back(CStartupWindow(WINDOW_FILES, "7")); - m_startupWindows.push_back(CStartupWindow(WINDOW_SETTINGS_MENU, "5")); - m_startupWindows.push_back(CStartupWindow(WINDOW_WEATHER, "8")); - return true; -} - -void CSkinInfo::GetSkinPaths(std::vector &paths) const -{ - RESOLUTION_INFO res; - GetSkinPath("Home.xml", &res); - if (!res.strMode.empty()) - paths.push_back(URIUtils::AddFileToFolder(Path(), res.strMode)); - if (res.strMode != m_defaultRes.strMode) - paths.push_back(URIUtils::AddFileToFolder(Path(), m_defaultRes.strMode)); -} - -bool CSkinInfo::TranslateResolution(const std::string &name, RESOLUTION_INFO &res) -{ - std::string lower(name); StringUtils::ToLower(lower); - if (lower == "pal") - res = RESOLUTION_INFO(720, 576, 4.0f/3, "pal"); - else if (lower == "pal16x9") - res = RESOLUTION_INFO(720, 576, 16.0f/9, "pal16x9"); - else if (lower == "ntsc") - res = RESOLUTION_INFO(720, 480, 4.0f/3, "ntsc"); - else if (lower == "ntsc16x9") - res = RESOLUTION_INFO(720, 480, 16.0f/9, "ntsc16x9"); - else if (lower == "720p") - res = RESOLUTION_INFO(1280, 720, 0, "720p"); - else if (lower == "1080i") - res = RESOLUTION_INFO(1920, 1080, 0, "1080i"); - else - return false; - return true; -} - -int CSkinInfo::GetFirstWindow() const -{ - int startWindow = GetStartWindow(); - if (HasSkinFile("Startup.xml")) - startWindow = WINDOW_STARTUP_ANIM; - return startWindow; -} - -bool CSkinInfo::IsInUse() const -{ - // Could extend this to prompt for reverting to the standard skin perhaps - return CSettings::Get().GetString("lookandfeel.skin") == ID(); -} - -const INFO::CSkinVariableString* CSkinInfo::CreateSkinVariable(const std::string& name, int context) -{ - return m_includes.CreateSkinVariable(name, context); -} - -bool CSkinInfo::OnPreInstall() -{ - // check whether this is an active skin - we need to unload it if so - if (IsInUse()) - { - CApplicationMessenger::Get().ExecBuiltIn("UnloadSkin", true); - return true; - } - return false; -} - -void CSkinInfo::OnPostInstall(bool restart, bool update, bool modal) -{ - if (restart || (!update && !modal && CGUIDialogYesNo::ShowAndGetInput(Name(), g_localizeStrings.Get(24099),"",""))) - { - CGUIDialogKaiToast *toast = (CGUIDialogKaiToast *)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST); - if (toast) - { - toast->ResetTimer(); - toast->Close(true); - } - if (CSettings::Get().GetString("lookandfeel.skin") == ID()) - CApplicationMessenger::Get().ExecBuiltIn("ReloadSkin", true); - else - CSettings::Get().SetString("lookandfeel.skin", ID()); - } -} - -void CSkinInfo::SettingOptionsSkinColorsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data) -{ - std::string settingValue = ((const CSettingString*)setting)->GetValue(); - // Remove the .xml extension from the Themes - if (URIUtils::HasExtension(settingValue, ".xml")) - URIUtils::RemoveExtension(settingValue); - current = "SKINDEFAULT"; - - // There is a default theme (just defaults.xml) - // any other *.xml files are additional color themes on top of this one. - - // add the default label - list.push_back(make_pair(g_localizeStrings.Get(15109), "SKINDEFAULT")); // the standard defaults.xml will be used! - - // Search for colors in the Current skin! - vector vecColors; - string strPath = URIUtils::AddFileToFolder(g_SkinInfo->Path(), "colors"); - - CFileItemList items; - CDirectory::GetDirectory(CSpecialProtocol::TranslatePathConvertCase(strPath), items, ".xml"); - // Search for Themes in the Current skin! - for (int i = 0; i < items.Size(); ++i) - { - CFileItemPtr pItem = items[i]; - if (!pItem->m_bIsFolder && !StringUtils::EqualsNoCase(pItem->GetLabel(), "defaults.xml")) - { // not the default one - vecColors.push_back(pItem->GetLabel().substr(0, pItem->GetLabel().size() - 4)); - } - } - sort(vecColors.begin(), vecColors.end(), sortstringbyname()); - for (int i = 0; i < (int) vecColors.size(); ++i) - list.push_back(make_pair(vecColors[i], vecColors[i])); - - // try to find the best matching value - for (vector< pair >::const_iterator it = list.begin(); it != list.end(); ++it) - { - if (StringUtils::EqualsNoCase(it->second, settingValue)) - current = settingValue; - } -} - -void CSkinInfo::SettingOptionsSkinFontsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data) -{ - std::string settingValue = ((const CSettingString*)setting)->GetValue(); - bool currentValueSet = false; - std::string strPath = g_SkinInfo->GetSkinPath("Font.xml"); - - CXBMCTinyXML xmlDoc; - if (!xmlDoc.LoadFile(strPath)) - { - CLog::Log(LOGERROR, "FillInSkinFonts: Couldn't load %s", strPath.c_str()); - return; - } - - const TiXmlElement* pRootElement = xmlDoc.RootElement(); - if (!pRootElement || pRootElement->ValueStr() != "fonts") - { - CLog::Log(LOGERROR, "FillInSkinFonts: file %s doesn't start with ", strPath.c_str()); - return; - } - - const TiXmlElement *pChild = pRootElement->FirstChildElement("fontset"); - while (pChild) - { - const char* idAttr = pChild->Attribute("id"); - const char* idLocAttr = pChild->Attribute("idloc"); - if (idAttr != NULL) - { - if (idLocAttr) - list.push_back(make_pair(g_localizeStrings.Get(atoi(idLocAttr)), idAttr)); - else - list.push_back(make_pair(idAttr, idAttr)); - - if (StringUtils::EqualsNoCase(idAttr, settingValue)) - currentValueSet = true; - } - pChild = pChild->NextSiblingElement("fontset"); - } - - if (list.empty()) - { // Since no fontset is defined, there is no selection of a fontset, so disable the component - list.push_back(make_pair(g_localizeStrings.Get(13278), "")); - current = ""; - currentValueSet = true; - } - - if (!currentValueSet) - current = list[0].second; -} - -void CSkinInfo::SettingOptionsSkinSoundFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data) -{ - std::string settingValue = ((const CSettingString*)setting)->GetValue(); - current = "SKINDEFAULT"; - - //find skins... - CFileItemList items; - CDirectory::GetDirectory("special://xbmc/sounds/", items); - CDirectory::GetDirectory("special://home/sounds/", items); - - vector vecSoundSkins; - for (int i = 0; i < items.Size(); i++) - { - CFileItemPtr pItem = items[i]; - if (pItem->m_bIsFolder) - { - if (StringUtils::EqualsNoCase(pItem->GetLabel(), ".svn") || - StringUtils::EqualsNoCase(pItem->GetLabel(), "fonts") || - StringUtils::EqualsNoCase(pItem->GetLabel(), "media")) - continue; - - vecSoundSkins.push_back(pItem->GetLabel()); - } - } - - list.push_back(make_pair(g_localizeStrings.Get(474), "OFF")); - list.push_back(make_pair(g_localizeStrings.Get(15109), "SKINDEFAULT")); - - sort(vecSoundSkins.begin(), vecSoundSkins.end(), sortstringbyname()); - for (unsigned int i = 0; i < vecSoundSkins.size(); i++) - list.push_back(make_pair(vecSoundSkins[i], vecSoundSkins[i])); - - // try to find the best matching value - for (vector< pair >::const_iterator it = list.begin(); it != list.end(); ++it) - { - if (StringUtils::EqualsNoCase(it->second, settingValue)) - current = settingValue; - } -} - -void CSkinInfo::SettingOptionsSkinThemesFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data) -{ - // get the choosen theme and remove the extension from the current theme (backward compat) - std::string settingValue = ((const CSettingString*)setting)->GetValue(); - URIUtils::RemoveExtension(settingValue); - current = "SKINDEFAULT"; - - // there is a default theme (just Textures.xpr/xbt) - // any other *.xpr|*.xbt files are additional themes on top of this one. - - // add the default Label - list.push_back(make_pair(g_localizeStrings.Get(15109), "SKINDEFAULT")); // the standard Textures.xpr/xbt will be used - - // search for themes in the current skin! - vector vecTheme; - CUtil::GetSkinThemes(vecTheme); - - // sort the themes for GUI and list them - for (int i = 0; i < (int) vecTheme.size(); ++i) - list.push_back(make_pair(vecTheme[i], vecTheme[i])); - - // try to find the best matching value - for (vector< pair >::const_iterator it = list.begin(); it != list.end(); ++it) - { - if (StringUtils::EqualsNoCase(it->second, settingValue)) - current = settingValue; - } -} - -void CSkinInfo::SettingOptionsStartupWindowsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t, void *data) -{ - int settingValue = ((const CSettingInt *)setting)->GetValue(); - current = -1; - - const vector &startupWindows = g_SkinInfo->GetStartupWindows(); - - for (vector::const_iterator it = startupWindows.begin(); it != startupWindows.end(); ++it) - { - string windowName = it->m_name; - if (StringUtils::IsNaturalNumber(windowName)) - windowName = g_localizeStrings.Get(atoi(windowName.c_str())); - int windowID = it->m_id; - - list.push_back(make_pair(windowName, windowID)); - - if (settingValue == windowID) - current = settingValue; - } - - // if the current value hasn't been properly set, set it to the first window in the list - if (current < 0) - current = list[0].second; -} - -} /*namespace ADDON*/ diff --git a/xbmc/addons/Skin.h b/xbmc/addons/Skin.h deleted file mode 100644 index 42bddf8..0000000 --- a/xbmc/addons/Skin.h +++ /dev/null @@ -1,155 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include - -#include "Addon.h" -#include "guilib/GraphicContext.h" // needed for the RESOLUTION members -#include "guilib/GUIIncludes.h" // needed for the GUIInclude member -#define CREDIT_LINE_LENGTH 50 - -class CSetting; - -namespace ADDON -{ - -class CSkinInfo : public CAddon -{ -public: - class CStartupWindow - { - public: - CStartupWindow(int id, const std::string &name): - m_id(id), m_name(name) - { - }; - int m_id; - std::string m_name; - }; - - //FIXME remove this, kept for current repo handling - CSkinInfo(const AddonProps &props, const RESOLUTION_INFO &res = RESOLUTION_INFO()); - CSkinInfo(const cp_extension_t *ext); - virtual ~CSkinInfo(); - virtual AddonPtr Clone() const; - - /*! \brief Load resultion information from directories in Path(). - */ - void Start(); - - bool HasSkinFile(const std::string &strFile) const; - - /*! \brief Get the full path to the specified file in the skin - We search for XML files in the skin folder that best matches the current resolution. - \param file XML file to look for - \param res [out] If non-NULL, the resolution that the returned XML file is in is returned. Defaults to NULL. - \param baseDir [in] If non-empty, the given directory is searched instead of the skin's directory. Defaults to empty. - \return path to the XML file - */ - std::string GetSkinPath(const std::string& file, RESOLUTION_INFO *res = NULL, const std::string& baseDir = "") const; - - AddonVersion APIVersion() const { return m_version; }; - - /*! \brief Return whether skin debugging is enabled - \return true if skin debugging (set via true in skin.xml) is enabled. - */ - bool IsDebugging() const { return m_debugging; }; - - /*! \brief Get the id of the first window to load - The first window is generally Startup.xml unless it doesn't exist or if the skinner - has specified which start windows they support and the user is going to somewhere other - than the home screen. - \return id of the first window to load - */ - int GetFirstWindow() const; - - /*! \brief Get the id of the window the user wants to start in after any skin animation - \return id of the start window - */ - int GetStartWindow() const; - - /*! \brief Translate a resolution string - \param name the string to translate - \param res [out] the resolution structure if name is valid - \return true if the resolution is valid, false otherwise - */ - static bool TranslateResolution(const std::string &name, RESOLUTION_INFO &res); - - void ResolveIncludes(TiXmlElement *node, std::map* xmlIncludeConditions = NULL); - - float GetEffectsSlowdown() const { return m_effectsSlowDown; }; - - const std::vector &GetStartupWindows() const { return m_startupWindows; }; - - /*! \brief Retrieve the skin paths to search for skin XML files - \param paths [out] vector of paths to search, in order. - */ - void GetSkinPaths(std::vector &paths) const; - - bool IsInUse() const; - - const std::string& GetCurrentAspect() const { return m_currentAspect; } - - void LoadIncludes(); - const INFO::CSkinVariableString* CreateSkinVariable(const std::string& name, int context); - - static void SettingOptionsSkinColorsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data); - static void SettingOptionsSkinFontsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data); - static void SettingOptionsSkinSoundFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data); - static void SettingOptionsSkinThemesFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t, void *data); - static void SettingOptionsStartupWindowsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t, void *data); - - virtual bool OnPreInstall(); - virtual void OnPostInstall(bool restart, bool update, bool modal); -protected: - /*! \brief Given a resolution, retrieve the corresponding directory name - \param res RESOLUTION to translate - \return directory name for res - */ - std::string GetDirFromRes(RESOLUTION res) const; - - /*! \brief grab a resolution tag from a skin's configuration data - \param props passed addoninfo structure to check for resolution - \param tag name of the tag to look for - \param res resolution to return - \return true if we find a valid resolution, false otherwise - */ - void GetDefaultResolution(const cp_extension_t *ext, const char *tag, RESOLUTION &res, const RESOLUTION &def) const; - - bool LoadStartupWindows(const cp_extension_t *ext); - - RESOLUTION_INFO m_defaultRes; - std::vector m_resolutions; - - AddonVersion m_version; - - float m_effectsSlowDown; - CGUIIncludes m_includes; - std::string m_currentAspect; - - std::vector m_startupWindows; - bool m_debugging; -}; - -} /*namespace ADDON*/ - -extern std::shared_ptr g_SkinInfo; diff --git a/xbmc/addons/Visualisation.cpp b/xbmc/addons/Visualisation.cpp deleted file mode 100644 index a64ee59..0000000 --- a/xbmc/addons/Visualisation.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#include "system.h" -#include "Visualisation.h" -#include "utils/fft.h" -#include "GUIInfoManager.h" -#include "Application.h" -#include "guilib/GraphicContext.h" -#include "guilib/WindowIDs.h" -#include "music/tags/MusicInfoTag.h" -#include "settings/Settings.h" -#include "settings/AdvancedSettings.h" -#include "settings/DisplaySettings.h" -#include "windowing/WindowingFactory.h" -#include "utils/URIUtils.h" -#include "utils/StringUtils.h" -#include "cores/IPlayer.h" -#include "cores/AudioEngine/AEFactory.h" -#ifdef TARGET_POSIX -#include -#include "filesystem/SpecialProtocol.h" -#endif - -using namespace std; -using namespace MUSIC_INFO; -using namespace ADDON; - -CAudioBuffer::CAudioBuffer(int iSize) -{ - m_iLen = iSize; - m_pBuffer = new float[iSize]; -} - -CAudioBuffer::~CAudioBuffer() -{ - delete [] m_pBuffer; -} - -const float* CAudioBuffer::Get() const -{ - return m_pBuffer; -} - -void CAudioBuffer::Set(const float* psBuffer, int iSize) -{ - if (iSize<0) - return; - memcpy(m_pBuffer, psBuffer, iSize * sizeof(float)); - for (int i = iSize; i < m_iLen; ++i) m_pBuffer[i] = 0; -} - -bool CVisualisation::Create(int x, int y, int w, int h, void *device) -{ - m_pInfo = new VIS_PROPS; - #ifdef HAS_DX - m_pInfo->device = g_Windowing.Get3DDevice(); -#else - m_pInfo->device = NULL; -#endif - m_pInfo->x = x; - m_pInfo->y = y; - m_pInfo->width = w; - m_pInfo->height = h; - m_pInfo->pixelRatio = g_graphicsContext.GetResInfo().fPixelRatio; - - m_pInfo->name = strdup(Name().c_str()); - m_pInfo->presets = strdup(CSpecialProtocol::TranslatePath(Path()).c_str()); - m_pInfo->profile = strdup(CSpecialProtocol::TranslatePath(Profile()).c_str()); - m_pInfo->submodule = NULL; - - if (CAddonDll::Create() == ADDON_STATUS_OK) - { - // Start the visualisation - std::string strFile = URIUtils::GetFileName(g_application.CurrentFile()); - CLog::Log(LOGDEBUG, "Visualisation::Start()\n"); - try - { - m_pStruct->Start(m_iChannels, m_iSamplesPerSec, m_iBitsPerSample, strFile.c_str()); - } - catch (std::exception e) - { - HandleException(e, "m_pStruct->Start() (CVisualisation::Create)"); - return false; - } - - GetPresets(); - - if (GetSubModules()) - m_pInfo->submodule = strdup(CSpecialProtocol::TranslatePath(m_submodules.front()).c_str()); - else - m_pInfo->submodule = NULL; - - CreateBuffers(); - - CAEFactory::RegisterAudioCallback(this); - - return true; - } - return false; -} - -void CVisualisation::Start(int iChannels, int iSamplesPerSec, int iBitsPerSample, const std::string &strSongName) -{ - // notify visz. that new song has been started - // pass it the nr of audio channels, sample rate, bits/sample and offcourse the songname - if (Initialized()) - { - try - { - m_pStruct->Start(iChannels, iSamplesPerSec, iBitsPerSample, strSongName.c_str()); - } - catch (std::exception e) - { - HandleException(e, "m_pStruct->Start (CVisualisation::Start)"); - } - } -} - -void CVisualisation::AudioData(const float* pAudioData, int iAudioDataLength, float *pFreqData, int iFreqDataLength) -{ - // pass audio data to visz. - // audio data: is short audiodata [channel][iAudioDataLength] containing the raw audio data - // iAudioDataLength = length of audiodata array - // pFreqData = fft-ed audio data - // iFreqDataLength = length of pFreqData - if (Initialized()) - { - try - { - m_pStruct->AudioData(pAudioData, iAudioDataLength, pFreqData, iFreqDataLength); - } - catch (std::exception e) - { - HandleException(e, "m_pStruct->AudioData (CVisualisation::AudioData)"); - } - } -} - -void CVisualisation::Render() -{ - // ask visz. to render itself - g_graphicsContext.BeginPaint(); - if (Initialized()) - { - try - { - m_pStruct->Render(); - } - catch (std::exception e) - { - HandleException(e, "m_pStruct->Render (CVisualisation::Render)"); - } - } - g_graphicsContext.EndPaint(); -} - -void CVisualisation::Stop() -{ - CAEFactory::UnregisterAudioCallback(); - if (Initialized()) - { - CAddonDll::Stop(); - } -} - -void CVisualisation::GetInfo(VIS_INFO *info) -{ - if (Initialized()) - { - try - { - m_pStruct->GetInfo(info); - } - catch (std::exception e) - { - HandleException(e, "m_pStruct->GetInfo (CVisualisation::GetInfo)"); - } - } -} - -bool CVisualisation::OnAction(VIS_ACTION action, void *param) -{ - if (!Initialized()) - return false; - - // see if vis wants to handle the input - // returns false if vis doesnt want the input - // returns true if vis handled the input - try - { - if (action != VIS_ACTION_NONE && m_pStruct->OnAction) - { - // if this is a VIS_ACTION_UPDATE_TRACK action, copy relevant - // tags from CMusicInfoTag to VisTag - if ( action == VIS_ACTION_UPDATE_TRACK && param ) - { - const CMusicInfoTag* tag = (const CMusicInfoTag*)param; - std::string artist(StringUtils::Join(tag->GetArtist(), g_advancedSettings.m_musicItemSeparator)); - std::string albumArtist(StringUtils::Join(tag->GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator)); - std::string genre(StringUtils::Join(tag->GetGenre(), g_advancedSettings.m_musicItemSeparator)); - - VisTrack track; - track.title = tag->GetTitle().c_str(); - track.artist = artist.c_str(); - track.album = tag->GetAlbum().c_str(); - track.albumArtist = albumArtist.c_str(); - track.genre = genre.c_str(); - track.comment = tag->GetComment().c_str(); - track.lyrics = tag->GetLyrics().c_str(); - track.trackNumber = tag->GetTrackNumber(); - track.discNumber = tag->GetDiscNumber(); - track.duration = tag->GetDuration(); - track.year = tag->GetYear(); - track.rating = tag->GetRating(); - - return m_pStruct->OnAction(action, &track); - } - return m_pStruct->OnAction((int)action, param); - } - } - catch (std::exception e) - { - HandleException(e, "m_pStruct->OnAction (CVisualisation::OnAction)"); - } - return false; -} - -void CVisualisation::OnInitialize(int iChannels, int iSamplesPerSec, int iBitsPerSample) -{ - if (!m_pStruct) - return ; - CLog::Log(LOGDEBUG, "OnInitialize() started"); - - m_iChannels = iChannels; - m_iSamplesPerSec = iSamplesPerSec; - m_iBitsPerSample = iBitsPerSample; - UpdateTrack(); - - CLog::Log(LOGDEBUG, "OnInitialize() done"); -} - -void CVisualisation::OnAudioData(const float* pAudioData, int iAudioDataLength) -{ - if (!m_pStruct) - return ; - - // FIXME: iAudioDataLength should never be less than 0 - if (iAudioDataLength<0) - return; - - // Save our audio data in the buffers - unique_ptr pBuffer ( new CAudioBuffer(AUDIO_BUFFER_SIZE) ); - pBuffer->Set(pAudioData, iAudioDataLength); - m_vecBuffers.push_back( pBuffer.release() ); - - if ( (int)m_vecBuffers.size() < m_iNumBuffers) return ; - - unique_ptr ptrAudioBuffer ( m_vecBuffers.front() ); - m_vecBuffers.pop_front(); - // Fourier transform the data if the vis wants it... - if (m_bWantsFreq) - { - const float *psAudioData = ptrAudioBuffer->Get(); - memcpy(m_fFreq, psAudioData, AUDIO_BUFFER_SIZE * sizeof(float)); - - // FFT the data - twochanwithwindow(m_fFreq, AUDIO_BUFFER_SIZE); - - // Normalize the data - float fMinData = (float)AUDIO_BUFFER_SIZE * AUDIO_BUFFER_SIZE * 3 / 8 * 0.5 * 0.5; // 3/8 for the Hann window, 0.5 as minimum amplitude - float fInvMinData = 1.0f/fMinData; - for (int i = 0; i < AUDIO_BUFFER_SIZE + 2; i++) - { - m_fFreq[i] *= fInvMinData; - } - - // Transfer data to our visualisation - AudioData(psAudioData, AUDIO_BUFFER_SIZE, m_fFreq, AUDIO_BUFFER_SIZE); - } - else - { // Transfer data to our visualisation - AudioData(ptrAudioBuffer->Get(), AUDIO_BUFFER_SIZE, NULL, 0); - } - return ; -} - -void CVisualisation::CreateBuffers() -{ - ClearBuffers(); - - // Get the number of buffers from the current vis - VIS_INFO info; - m_pStruct->GetInfo(&info); - m_iNumBuffers = info.iSyncDelay + 1; - m_bWantsFreq = (info.bWantsFreq != 0); - if (m_iNumBuffers > MAX_AUDIO_BUFFERS) - m_iNumBuffers = MAX_AUDIO_BUFFERS; - if (m_iNumBuffers < 1) - m_iNumBuffers = 1; -} - -void CVisualisation::ClearBuffers() -{ - m_bWantsFreq = false; - m_iNumBuffers = 0; - - while (!m_vecBuffers.empty()) - { - CAudioBuffer* pAudioBuffer = m_vecBuffers.front(); - delete pAudioBuffer; - m_vecBuffers.pop_front(); - } - for (int j = 0; j < AUDIO_BUFFER_SIZE*2; j++) - { - m_fFreq[j] = 0.0f; - } -} - -bool CVisualisation::UpdateTrack() -{ - bool handled = false; - if (Initialized()) - { - // get the current album art filename - m_AlbumThumb = CSpecialProtocol::TranslatePath(g_infoManager.GetImage(MUSICPLAYER_COVER, WINDOW_INVALID)); - - // get the current track tag - const CMusicInfoTag* tag = g_infoManager.GetCurrentSongTag(); - - if (m_AlbumThumb == "DefaultAlbumCover.png") - m_AlbumThumb = ""; - else - CLog::Log(LOGDEBUG,"Updating visualisation albumart: %s", m_AlbumThumb.c_str()); - - // inform the visualisation of the current album art - if (OnAction( VIS_ACTION_UPDATE_ALBUMART, (void*)( m_AlbumThumb.c_str() ) ) ) - handled = true; - - // inform the visualisation of the current track's tag information - if ( tag && OnAction( VIS_ACTION_UPDATE_TRACK, (void*)tag ) ) - handled = true; - } - return handled; -} - -bool CVisualisation::GetPresetList(std::vector &vecpresets) -{ - vecpresets = m_presets; - return !m_presets.empty(); -} - -bool CVisualisation::GetPresets() -{ - m_presets.clear(); - char **presets = NULL; - unsigned int entries = 0; - try - { - entries = m_pStruct->GetPresets(&presets); - } - catch (std::exception e) - { - HandleException(e, "m_pStruct->OnAction (CVisualisation::GetPresets)"); - return false; - } - if (presets && entries > 0) - { - for (unsigned i=0; i < entries; i++) - { - if (presets[i]) - { - m_presets.push_back(presets[i]); - } - } - } - return (!m_presets.empty()); -} - -bool CVisualisation::GetSubModuleList(std::vector &vecmodules) -{ - vecmodules = m_submodules; - return !m_submodules.empty(); -} - -bool CVisualisation::GetSubModules() -{ - m_submodules.clear(); - char **modules = NULL; - unsigned int entries = 0; - try - { - entries = m_pStruct->GetSubModules(&modules); - } - catch (...) - { - CLog::Log(LOGERROR, "Exception in Visualisation::GetSubModules()"); - return false; - } - if (modules && entries > 0) - { - for (unsigned i=0; i < entries; i++) - { - if (modules[i]) - { - m_submodules.push_back(modules[i]); - } - } - } - return (!m_submodules.empty()); -} - -std::string CVisualisation::GetFriendlyName(const std::string& strVisz, - const std::string& strSubModule) -{ - // should be of the format "moduleName (visName)" - return strSubModule + " (" + strVisz + ")"; -} - -bool CVisualisation::IsLocked() -{ - if (!m_presets.empty()) - { - if (!m_pStruct) - return false; - - return m_pStruct->IsLocked(); - } - return false; -} - -void CVisualisation::Destroy() -{ - // Free what was allocated in method CVisualisation::Create - if (m_pInfo) - { - free((void *) m_pInfo->name); - free((void *) m_pInfo->presets); - free((void *) m_pInfo->profile); - free((void *) m_pInfo->submodule); - - delete m_pInfo; - m_pInfo = NULL; - } - - CAddonDll::Destroy(); -} - -unsigned CVisualisation::GetPreset() -{ - unsigned index = 0; - try - { - index = m_pStruct->GetPreset(); - } - catch(...) - { - return 0; - } - return index; -} - -std::string CVisualisation::GetPresetName() -{ - if (!m_presets.empty()) - return m_presets[GetPreset()]; - else - return ""; -} - diff --git a/xbmc/addons/Visualisation.h b/xbmc/addons/Visualisation.h deleted file mode 100644 index 0a2a1cb..0000000 --- a/xbmc/addons/Visualisation.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ -#pragma once - -#include "AddonDll.h" -#include "cores/IAudioCallback.h" -#include "include/xbmc_vis_types.h" -#include "guilib/IRenderingCallback.h" - -#include -#include -#include - -#define AUDIO_BUFFER_SIZE 512 // MUST BE A POWER OF 2!!! -#define MAX_AUDIO_BUFFERS 16 - -class CCriticalSection; - -typedef DllAddon DllVisualisation; - -class CAudioBuffer -{ -public: - CAudioBuffer(int iSize); - virtual ~CAudioBuffer(); - const float* Get() const; - void Set(const float* psBuffer, int iSize); -private: - CAudioBuffer(); - float* m_pBuffer; - int m_iLen; -}; - -namespace ADDON -{ - class CVisualisation : public CAddonDll - , public IAudioCallback - , public IRenderingCallback - { - public: - CVisualisation(const ADDON::AddonProps &props) : CAddonDll(props) {} - CVisualisation(const cp_extension_t *ext) : CAddonDll(ext) {} - virtual void OnInitialize(int iChannels, int iSamplesPerSec, int iBitsPerSample); - virtual void OnAudioData(const float* pAudioData, int iAudioDataLength); - bool Create(int x, int y, int w, int h, void *device); - void Start(int iChannels, int iSamplesPerSec, int iBitsPerSample, const std::string &strSongName); - void AudioData(const float *pAudioData, int iAudioDataLength, float *pFreqData, int iFreqDataLength); - void Render(); - void Stop(); - void GetInfo(VIS_INFO *info); - bool OnAction(VIS_ACTION action, void *param = NULL); - bool UpdateTrack(); - bool HasSubModules() { return !m_submodules.empty(); } - bool IsLocked(); - unsigned GetPreset(); - std::string GetPresetName(); - bool GetPresetList(std::vector& vecpresets); - bool GetSubModuleList(std::vector& vecmodules); - static std::string GetFriendlyName(const std::string& vis, const std::string& module); - void Destroy(); - - private: - void CreateBuffers(); - void ClearBuffers(); - - bool GetPresets(); - bool GetSubModules(); - - // attributes of the viewport we render to - int m_xPos; - int m_yPos; - int m_width; - int m_height; - - // cached preset list - std::vector m_presets; - // cached submodule list - std::vector m_submodules; - int m_currentModule; - - // audio properties - int m_iChannels; - int m_iSamplesPerSec; - int m_iBitsPerSample; - std::list m_vecBuffers; - int m_iNumBuffers; // Number of Audio buffers - bool m_bWantsFreq; - float m_fFreq[2*AUDIO_BUFFER_SIZE]; // Frequency data - bool m_bCalculate_Freq; // True if the vis wants freq data - - // track information - std::string m_AlbumThumb; - }; -} diff --git a/xbmc/addons/Webinterface.cpp b/xbmc/addons/Webinterface.cpp deleted file mode 100644 index 5745b1c..0000000 --- a/xbmc/addons/Webinterface.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2015 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 - * . - * - */ - -#include "Webinterface.h" -#include "addons/AddonManager.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" - -using namespace ADDON; - -CWebinterface::CWebinterface(const ADDON::AddonProps &props, WebinterfaceType type /* = WebinterfaceTypeStatic */, const std::string &entryPoint /* = "WEBINTERFACE_DEFAULT_ENTRY_POINT" */) - : CAddon(props), - m_type(type), - m_entryPoint(entryPoint) -{ } - -CWebinterface::CWebinterface(const cp_extension_t *ext) - : CAddon(ext), - m_type(WebinterfaceTypeStatic), - m_entryPoint(WEBINTERFACE_DEFAULT_ENTRY_POINT) -{ - // determine the type of the webinterface - std::string webinterfaceType = CAddonMgr::Get().GetExtValue(ext->configuration, "@type"); - if (StringUtils::EqualsNoCase(webinterfaceType.c_str(), "wsgi")) - m_type = WebinterfaceTypeWsgi; - else if (!webinterfaceType.empty() && !StringUtils::EqualsNoCase(webinterfaceType.c_str(), "static") && !StringUtils::EqualsNoCase(webinterfaceType.c_str(), "html")) - CLog::Log(LOGWARNING, "Webinterface addon \"%s\" has specified an unsupported type \"%s\"", ID().c_str(), webinterfaceType.c_str()); - - // determine the entry point of the webinterface - std::string entryPoint = CAddonMgr::Get().GetExtValue(ext->configuration, "@entry"); - if (!entryPoint.empty()) - m_entryPoint = entryPoint; -} - -CWebinterface::~CWebinterface() -{ } - -std::string CWebinterface::GetEntryPoint(const std::string &path) const -{ - if (m_type == WebinterfaceTypeWsgi) - return LibPath(); - - return URIUtils::AddFileToFolder(path, m_entryPoint); -} - -std::string CWebinterface::GetBaseLocation() const -{ - if (m_type == WebinterfaceTypeWsgi) - return "/addons/" + ID(); - - return ""; -} - -AddonPtr CWebinterface::Clone() const -{ - return AddonPtr(new CWebinterface(*this)); -} \ No newline at end of file diff --git a/xbmc/addons/Webinterface.h b/xbmc/addons/Webinterface.h deleted file mode 100644 index 0a4773f..0000000 --- a/xbmc/addons/Webinterface.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -/* - * Copyright (C) 2015 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 - * . - * - */ - -#include "Addon.h" - -#define WEBINTERFACE_DEFAULT_ENTRY_POINT "index.html" - -namespace ADDON -{ - typedef enum WebinterfaceType - { - WebinterfaceTypeStatic = 0, - WebinterfaceTypeWsgi - } WebinterfaceType; - - class CWebinterface : public CAddon - { - public: - explicit CWebinterface(const ADDON::AddonProps &props, WebinterfaceType type = WebinterfaceTypeStatic, const std::string &entryPoint = WEBINTERFACE_DEFAULT_ENTRY_POINT); - explicit CWebinterface(const cp_extension_t *ext); - virtual ~CWebinterface(); - - WebinterfaceType GetType() const { return m_type; } - const std::string& EntryPoint() const { return m_entryPoint; } - - std::string GetEntryPoint(const std::string &path) const; - std::string GetBaseLocation() const; - - // specializations of CAddon - virtual AddonPtr Clone() const; - - private: - WebinterfaceType m_type; - std::string m_entryPoint; - }; -} diff --git a/xbmc/addons/addon-bindings.mk b/xbmc/addons/addon-bindings.mk index 50d75bc..4a33cfd 100644 --- a/xbmc/addons/addon-bindings.mk +++ b/xbmc/addons/addon-bindings.mk @@ -3,6 +3,8 @@ BINDINGS+=xbmc/addons/include/xbmc_addon_dll.h BINDINGS+=xbmc/addons/include/xbmc_addon_types.h BINDINGS+=xbmc/addons/include/xbmc_audioenc_dll.h BINDINGS+=xbmc/addons/include/xbmc_audioenc_types.h +BINDINGS+=xbmc/addons/include/kodi_audiodec_dll.h +BINDINGS+=xbmc/addons/include/kodi_audiodec_types.h BINDINGS+=xbmc/addons/include/xbmc_codec_types.h BINDINGS+=xbmc/addons/include/xbmc_epg_types.h BINDINGS+=xbmc/addons/include/xbmc_pvr_dll.h @@ -17,4 +19,4 @@ BINDINGS+=addons/library.xbmc.gui/libXBMC_gui.h BINDINGS+=addons/library.xbmc.pvr/libXBMC_pvr.h BINDINGS+=addons/library.xbmc.codec/libXBMC_codec.h BINDINGS+=xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPacket.h - +BINDINGS+=xbmc/cores/AudioEngine/Utils/AEChannelData.h diff --git a/xbmc/addons/include/NOTE b/xbmc/addons/include/NOTE deleted file mode 100644 index dbcc329..0000000 --- a/xbmc/addons/include/NOTE +++ /dev/null @@ -1,12 +0,0 @@ -NOTE: - -This directory contains independent Headers to build Add-on's -without the whole XBMC source tree. The Add-on itself can add -this headers to his source tree without dependencies to any -XBMC related classes or functions. - -Also this headers are never changed without a API Version -change. - -The current PVR API version can be found in xbmc_pvr_types.h: -XBMC_PVR_API_VERSION diff --git a/xbmc/addons/include/kodi_audiodec_dll.h b/xbmc/addons/include/kodi_audiodec_dll.h new file mode 100644 index 0000000..78bc3cc --- /dev/null +++ b/xbmc/addons/include/kodi_audiodec_dll.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005-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 + * . + * + */ + +#pragma once + +#include +#include "xbmc_addon_dll.h" +#include "kodi_audiodec_types.h" + +extern "C" +{ + //! \copydoc AudioDecoder::Init + void* Init(const char* file, unsigned int filecache, int* channels, + int* samplerate, int* bitspersample, int64_t* totaltime, + int* bitrate, AEDataFormat* format, const AEChannel** channelinfo); + + //! \copydoc AudioDecoder::ReadPCM + int ReadPCM(void* context, uint8_t* buffer, int size, int* actualsize); + + //! \copydoc AudioDecoder::Seek + int64_t Seek(void* context, int64_t time); + + //! \copydoc AudioDecoder::ReadTag + bool ReadTag(const char* file, char* title, + char* artist, int* length); + + //! \copydoc AudioDecoder::TrackCount + int TrackCount(const char* file); + + //! \copydoc AudioDecoder::DeInit + bool DeInit(void* context); + + // function to export the above structure to XBMC + void __declspec(dllexport) get_addon(struct AudioDecoder* pScr) + { + pScr->Init = Init; + pScr->ReadPCM = ReadPCM; + pScr->Seek = Seek; + pScr->ReadTag = ReadTag; + pScr->TrackCount = TrackCount; + pScr->DeInit = DeInit; + }; +}; diff --git a/xbmc/addons/include/kodi_audiodec_types.h b/xbmc/addons/include/kodi_audiodec_types.h new file mode 100644 index 0000000..50c4cc4 --- /dev/null +++ b/xbmc/addons/include/kodi_audiodec_types.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2005-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 + * . + * + */ + +#pragma once + +#include +#ifdef BUILD_KODI_ADDON +#include "kodi/AEChannelData.h" +#else +#include "cores/AudioEngine/Utils/AEChannelData.h" +#endif + +extern "C" +{ + struct AUDIODEC_INFO + { + int dummy; + }; + + struct AUDIODEC_PROPS + { + int dummy; + }; + + struct AudioDecoder + { + //! \brief Initialize a decoder + //! \param file The file to read + //! \param filecache The file cache size + //! \param channels Number of channels in output stream + //! \param samplerate Samplerate of output stream + //! \param bitspersample Bits per sample in output stream + //! \param totaltime Total time for stream + //! \param bitrate Average bitrate of input stream + //! \param format Data format for output stream + //! \param info Channel mapping for output stream + //! \return Context of output stream + //! \sa ICodec::Init + void* (__cdecl* Init) (const char* file, unsigned int filecache, + int* channels, int* samplerate, + int* bitspersample, int64_t* totaltime, + int* bitrate, AEDataFormat* format, + const AEChannel** info); + + //! \brief Produce some noise + //! \param context Context of output stream + //! \param buffer Output buffer + //! \param size Size of output buffer + //! \param actualsize Actual number of bytes written to output buffer + //! \return 0 on success, -1 on end of stream, 1 on failure + //! \sa ICodec::ReadPCM + int (__cdecl* ReadPCM) (void* context, uint8_t* buffer, int size, int* actualsize); + + + //! \brief Seek in output stream + //! \param context Context of output stream + //! \param time Time position to seek to in milliseconds + //! \return Time position seek ended up on + //! \sa ICodec::Seek + int64_t (__cdecl* Seek) (void* context, int64_t time); + + //! \brief Read tag of a file + //! \param file File to read tag for + //! \param title Title of file + //! \param artist Artist of file + //! \param length Length of file + //! \return True on success, false on failure + //! \sa IMusicInfoTagLoader::ReadTag + bool (__cdecl* ReadTag)(const char* file, char* title, + char* artist, int* length); + + //! \brief Get number of tracks in a file + //! \param file File to read tag for + //! \return Number of tracks in file + //! \sa CMusicFileDirectory + int (__cdecl* TrackCount) (const char* file); + + //! \brief Close down an output stream + //! \param context Context of stream + //! \return True on success, false on failure + //! \sa ICodec::DeInit + bool (__cdecl* DeInit)(void* context); + }; +} diff --git a/xbmc/addons/test/Makefile b/xbmc/addons/test/Makefile deleted file mode 100644 index bf74bd6..0000000 --- a/xbmc/addons/test/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -SRCS= \ - TestAddonVersion.cpp - -LIB=addonsTest.a - -INCLUDES += -I../../../lib/gtest/include - -include ../../../Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/addons/test/TestAddonVersion.cpp b/xbmc/addons/test/TestAddonVersion.cpp deleted file mode 100644 index 41e71a4..0000000 --- a/xbmc/addons/test/TestAddonVersion.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * 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 - * . - * - */ - -#include "addons/AddonVersion.h" - -#include "gtest/gtest.h" - -using namespace ADDON; - -class TestAddonVersion : public testing::Test -{ -public: - TestAddonVersion() - : v1_0("1.0"), - v1_00("1.00"), - v1_0_0("1.0.0"), - v1_1("1.1"), - v1_01("1.01"), - v1_0_1("1.0.1"), - e1_v1_0_0("1:1.0.0"), - e1_v1_0_1("1:1.0.1"), - e2_v1_0_0("2:1.0.0"), - e1_v1_0_0_r1("1:1.0.0-1"), - e1_v1_0_1_r1("1:1.0.1-1"), - e1_v1_0_0_r2("1:1.0.0-2"), - v1_0_0_beta("1.0.0~beta"), - v1_0_0_alpha("1.0.0~alpha"), - v1_0_0_alpha2("1.0.0~alpha2"), - v1_0_0_alpha3("1.0.0~alpha3"), - v1_0_0_alpha10("1.0.0~alpha10") - { - } - - AddonVersion v1_0; - AddonVersion v1_00; - AddonVersion v1_0_0; - AddonVersion v1_1; - AddonVersion v1_01; - AddonVersion v1_0_1; - AddonVersion e1_v1_0_0; - AddonVersion e1_v1_0_1; - AddonVersion e2_v1_0_0; - AddonVersion e1_v1_0_0_r1; - AddonVersion e1_v1_0_1_r1; - AddonVersion e1_v1_0_0_r2; - AddonVersion v1_0_0_beta; - AddonVersion v1_0_0_alpha; - AddonVersion v1_0_0_alpha2; - AddonVersion v1_0_0_alpha3; - AddonVersion v1_0_0_alpha10; -}; - -TEST_F(TestAddonVersion, Constructor) -{ - EXPECT_EQ(v1_0.Upstream(), "1.0"); - EXPECT_EQ(v1_0.Epoch(), 0); - EXPECT_TRUE(v1_0.Revision().empty()); - - EXPECT_EQ(v1_00.Upstream(), "1.00"); - EXPECT_EQ(v1_00.Epoch(), 0); - EXPECT_TRUE(v1_00.Revision().empty()); - - EXPECT_EQ(v1_0_0.Upstream(), "1.0.0"); - EXPECT_EQ(v1_0_0.Epoch(), 0); - EXPECT_TRUE(v1_0_0.Revision().empty()); - - EXPECT_EQ(v1_1.Upstream(), "1.1"); - EXPECT_EQ(v1_1.Epoch(), 0); - EXPECT_TRUE(v1_1.Revision().empty()); - - EXPECT_EQ(v1_01.Upstream(), "1.01"); - EXPECT_EQ(v1_01.Epoch(), 0); - EXPECT_TRUE(v1_01.Revision().empty()); - - EXPECT_EQ(v1_0_1.Upstream(), "1.0.1"); - EXPECT_EQ(v1_0_1.Epoch(), 0); - EXPECT_TRUE(v1_0_1.Revision().empty()); - - EXPECT_EQ(e1_v1_0_0.Upstream(), "1.0.0"); - EXPECT_EQ(e1_v1_0_0.Epoch(), 1); - EXPECT_TRUE(e1_v1_0_0.Revision().empty()); - - EXPECT_EQ(e1_v1_0_1.Upstream(), "1.0.1"); - EXPECT_EQ(e1_v1_0_1.Epoch(), 1); - EXPECT_TRUE(e1_v1_0_1.Revision().empty()); - - EXPECT_EQ(e2_v1_0_0.Upstream(), "1.0.0"); - EXPECT_EQ(e2_v1_0_0.Epoch(), 2); - EXPECT_TRUE(e2_v1_0_0.Revision().empty()); - - EXPECT_EQ(e1_v1_0_0_r1.Upstream(), "1.0.0"); - EXPECT_EQ(e1_v1_0_0_r1.Epoch(), 1); - EXPECT_EQ(e1_v1_0_0_r1.Revision(), "1"); - - EXPECT_EQ(e1_v1_0_1_r1.Upstream(), "1.0.1"); - EXPECT_EQ(e1_v1_0_1_r1.Epoch(), 1); - EXPECT_EQ(e1_v1_0_1_r1.Revision(), "1"); - - EXPECT_EQ(e1_v1_0_0_r2.Upstream(), "1.0.0"); - EXPECT_EQ(e1_v1_0_0_r2.Epoch(), 1); - EXPECT_EQ(e1_v1_0_0_r2.Revision(), "2"); - - EXPECT_EQ(v1_0_0_beta.Upstream(), "1.0.0~beta"); - EXPECT_EQ(v1_0_0_beta.Epoch(), 0); - EXPECT_TRUE(v1_0_0_beta.Revision().empty()); - - EXPECT_EQ(v1_0_0_alpha.Upstream(), "1.0.0~alpha"); - EXPECT_EQ(v1_0_0_alpha.Epoch(), 0); - EXPECT_TRUE(v1_0_0_alpha.Revision().empty()); - - EXPECT_EQ(v1_0_0_alpha2.Upstream(), "1.0.0~alpha2"); - EXPECT_EQ(v1_0_0_alpha2.Epoch(), 0); - EXPECT_TRUE(v1_0_0_alpha2.Revision().empty()); - - EXPECT_EQ(v1_0_0_alpha3.Upstream(), "1.0.0~alpha3"); - EXPECT_EQ(v1_0_0_alpha3.Epoch(), 0); - EXPECT_TRUE(v1_0_0_alpha3.Revision().empty()); - - EXPECT_EQ(v1_0_0_alpha10.Upstream(), "1.0.0~alpha10"); - EXPECT_EQ(v1_0_0_alpha10.Epoch(), 0); - EXPECT_TRUE(v1_0_0_alpha10.Revision().empty()); -} - -TEST_F(TestAddonVersion, asString) -{ - EXPECT_EQ(v1_0.asString(), "1.0"); - EXPECT_EQ(v1_00.asString(), "1.00"); - EXPECT_EQ(v1_0_0.asString(), "1.0.0"); - EXPECT_EQ(v1_1.asString(), "1.1"); - EXPECT_EQ(v1_01.asString(), "1.01"); - EXPECT_EQ(v1_0_1.asString(), "1.0.1"); - EXPECT_EQ(e1_v1_0_0.asString(), "1:1.0.0"); - EXPECT_EQ(e1_v1_0_1.asString(), "1:1.0.1"); - EXPECT_EQ(e2_v1_0_0.asString(), "2:1.0.0"); - EXPECT_EQ(e1_v1_0_0_r1.asString(), "1:1.0.0-1"); - EXPECT_EQ(e1_v1_0_1_r1.asString(), "1:1.0.1-1"); - EXPECT_EQ(e1_v1_0_0_r2.asString(), "1:1.0.0-2"); - EXPECT_EQ(v1_0_0_beta.asString(), "1.0.0~beta"); - EXPECT_EQ(v1_0_0_alpha.asString(), "1.0.0~alpha"); - EXPECT_EQ(v1_0_0_alpha2.asString(), "1.0.0~alpha2"); - EXPECT_EQ(v1_0_0_alpha3.asString(), "1.0.0~alpha3"); - EXPECT_EQ(v1_0_0_alpha10.asString(), "1.0.0~alpha10"); -} - -TEST_F(TestAddonVersion, Equals) -{ - EXPECT_EQ(v1_0, AddonVersion("1.0")); - EXPECT_EQ(v1_00, AddonVersion("1.00")); - EXPECT_EQ(v1_0_0, AddonVersion("1.0.0")); - EXPECT_EQ(v1_1, AddonVersion("1.1")); - EXPECT_EQ(v1_01, AddonVersion("1.01")); - EXPECT_EQ(v1_0_1, AddonVersion("1.0.1")); - EXPECT_EQ(e1_v1_0_0, AddonVersion("1:1.0.0")); - EXPECT_EQ(e1_v1_0_1, AddonVersion("1:1.0.1")); - EXPECT_EQ(e2_v1_0_0, AddonVersion("2:1.0.0")); - EXPECT_EQ(e1_v1_0_0_r1, AddonVersion("1:1.0.0-1")); - EXPECT_EQ(e1_v1_0_1_r1, AddonVersion("1:1.0.1-1")); - EXPECT_EQ(e1_v1_0_0_r2, AddonVersion("1:1.0.0-2")); - EXPECT_EQ(v1_0_0_beta, AddonVersion("1.0.0~beta")); - EXPECT_EQ(v1_0_0_alpha, AddonVersion("1.0.0~alpha")); - EXPECT_EQ(v1_0_0_alpha2, AddonVersion("1.0.0~alpha2")); - EXPECT_EQ(v1_0_0_alpha3, AddonVersion("1.0.0~alpha3")); - EXPECT_EQ(v1_0_0_alpha10, AddonVersion("1.0.0~alpha10")); -} - -TEST_F(TestAddonVersion, Equivalent) -{ - EXPECT_FALSE(v1_0 != v1_00); - EXPECT_FALSE(v1_0 < v1_00); - EXPECT_FALSE(v1_0 > v1_00); - EXPECT_TRUE(v1_0 == v1_00); - - EXPECT_FALSE(v1_01 != v1_1); - EXPECT_FALSE(v1_01 < v1_1); - EXPECT_FALSE(v1_01 > v1_1); - EXPECT_TRUE(v1_01 == v1_1); -} - -TEST_F(TestAddonVersion, LessThan) -{ - EXPECT_LT(v1_0, v1_0_0); - EXPECT_LT(v1_0, v1_1); - EXPECT_LT(v1_0, v1_01); - EXPECT_LT(v1_0, v1_0_1); - - EXPECT_LT(v1_00, v1_0_0); - EXPECT_LT(v1_00, v1_1); - EXPECT_LT(v1_00, v1_01); - EXPECT_LT(v1_00, v1_0_1); - - EXPECT_LT(v1_0_0, v1_1); - EXPECT_LT(v1_0_0, v1_01); - EXPECT_LT(v1_0_0, v1_0_1); - - EXPECT_LT(v1_0_1, v1_01); - EXPECT_LT(v1_0_1, v1_1); - - // epochs - EXPECT_LT(v1_0_0, e1_v1_0_0); - EXPECT_LT(v1_0_0, e1_v1_0_1); - EXPECT_LT(v1_0_0, e2_v1_0_0); - EXPECT_LT(v1_0_1, e1_v1_0_1); - EXPECT_LT(v1_0_1, e2_v1_0_0); - - EXPECT_LT(e1_v1_0_0, e1_v1_0_1); - EXPECT_LT(e1_v1_0_0, e2_v1_0_0); - EXPECT_LT(e1_v1_0_1, e2_v1_0_0); - - // revisions - EXPECT_LT(e1_v1_0_0, e1_v1_0_0_r1); - EXPECT_LT(e1_v1_0_0, e1_v1_0_1_r1); - EXPECT_LT(e1_v1_0_0, e1_v1_0_0_r2); - EXPECT_LT(e1_v1_0_1, e1_v1_0_1_r1); - EXPECT_LT(e1_v1_0_0_r1, e1_v1_0_1); - EXPECT_LT(e1_v1_0_0_r1, e1_v1_0_1_r1); - EXPECT_LT(e1_v1_0_0_r1, e1_v1_0_0_r2); - EXPECT_LT(e1_v1_0_0_r2, e1_v1_0_1); - EXPECT_LT(e1_v1_0_0_r2, e1_v1_0_1_r1); - EXPECT_LT(e1_v1_0_1_r1, e2_v1_0_0); - - // alpha, beta - EXPECT_LT(v1_0_0_beta, v1_0_0); - EXPECT_LT(v1_0_0_alpha, v1_0_0); - EXPECT_LT(v1_0_0_alpha, v1_0_0_beta); - EXPECT_LT(v1_0_0_alpha, v1_0_0_alpha2); - EXPECT_LT(v1_0_0_alpha, v1_0_0_alpha3); - EXPECT_LT(v1_0_0_alpha, v1_0_0_alpha10); - EXPECT_LT(v1_0_0_alpha2, v1_0_0); - EXPECT_LT(v1_0_0_alpha2, v1_0_0_beta); - EXPECT_LT(v1_0_0_alpha2, v1_0_0_alpha3); - EXPECT_LT(v1_0_0_alpha2, v1_0_0_alpha10); - EXPECT_LT(v1_0_0_alpha3, v1_0_0); - EXPECT_LT(v1_0_0_alpha3, v1_0_0_beta); - EXPECT_LT(v1_0_0_alpha3, v1_0_0_alpha10); - EXPECT_LT(v1_0_0_alpha10, v1_0_0); - EXPECT_LT(v1_0_0_alpha10, v1_0_0_beta); -} diff --git a/xbmc/cores/AudioEngine/Utils/AEChannelData.h b/xbmc/cores/AudioEngine/Utils/AEChannelData.h new file mode 100644 index 0000000..5d47651 --- /dev/null +++ b/xbmc/cores/AudioEngine/Utils/AEChannelData.h @@ -0,0 +1,128 @@ +#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 + * . + * + */ + +/** + * The possible channels + */ +enum AEChannel +{ + AE_CH_NULL = -1, + AE_CH_RAW , + + AE_CH_FL , AE_CH_FR , AE_CH_FC , AE_CH_LFE, AE_CH_BL , AE_CH_BR , AE_CH_FLOC, + AE_CH_FROC, AE_CH_BC , AE_CH_SL , AE_CH_SR , AE_CH_TFL , AE_CH_TFR , AE_CH_TFC , + AE_CH_TC , AE_CH_TBL, AE_CH_TBR, AE_CH_TBC, AE_CH_BLOC, AE_CH_BROC, + + /* p16v devices */ + AE_CH_UNKNOWN1, + AE_CH_UNKNOWN2, + AE_CH_UNKNOWN3, + AE_CH_UNKNOWN4, + AE_CH_UNKNOWN5, + AE_CH_UNKNOWN6, + AE_CH_UNKNOWN7, + AE_CH_UNKNOWN8, + AE_CH_UNKNOWN9, + AE_CH_UNKNOWN10, + AE_CH_UNKNOWN11, + AE_CH_UNKNOWN12, + AE_CH_UNKNOWN13, + AE_CH_UNKNOWN14, + AE_CH_UNKNOWN15, + AE_CH_UNKNOWN16, + + AE_CH_MAX +}; + +/** + * Standard channel layouts + */ +enum AEStdChLayout +{ + AE_CH_LAYOUT_INVALID = -1, + + AE_CH_LAYOUT_1_0 = 0, + AE_CH_LAYOUT_2_0, + AE_CH_LAYOUT_2_1, + AE_CH_LAYOUT_3_0, + AE_CH_LAYOUT_3_1, + AE_CH_LAYOUT_4_0, + AE_CH_LAYOUT_4_1, + AE_CH_LAYOUT_5_0, + AE_CH_LAYOUT_5_1, + AE_CH_LAYOUT_7_0, + AE_CH_LAYOUT_7_1, + + AE_CH_LAYOUT_MAX +}; + +/** + * The various data formats + * LE = Little Endian, BE = Big Endian, NE = Native Endian + * @note This is ordered from the worst to best preferred formats + */ +enum AEDataFormat +{ + AE_FMT_INVALID = -1, + + AE_FMT_U8, + + AE_FMT_S16BE, + AE_FMT_S16LE, + AE_FMT_S16NE, + + AE_FMT_S32BE, + AE_FMT_S32LE, + AE_FMT_S32NE, + + AE_FMT_S24BE4, + AE_FMT_S24LE4, + AE_FMT_S24NE4, // 24 bits in lower 3 bytes + AE_FMT_S24NE4MSB, // S32 with bits_per_sample < 32 + + AE_FMT_S24BE3, + AE_FMT_S24LE3, + AE_FMT_S24NE3, /* S24 in 3 bytes */ + + AE_FMT_DOUBLE, + AE_FMT_FLOAT, + + /* Bitstream formats */ + AE_FMT_AAC, + AE_FMT_AC3, + AE_FMT_DTS, + AE_FMT_EAC3, + AE_FMT_TRUEHD, + AE_FMT_DTSHD, + AE_FMT_LPCM, + + /* planar formats */ + AE_FMT_U8P, + AE_FMT_S16NEP, + AE_FMT_S32NEP, + AE_FMT_S24NE4P, + AE_FMT_S24NE4MSBP, + AE_FMT_S24NE3P, + AE_FMT_DOUBLEP, + AE_FMT_FLOATP, + + AE_FMT_MAX +}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp deleted file mode 100644 index 2f833c5..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DVDDemux.h" -#include "DVDCodecs/DVDCodecs.h" - -void CDemuxStreamTeletext::GetStreamInfo(std::string& strInfo) -{ - strInfo = "Teletext Data Stream"; -} - -void CDemuxStreamAudio::GetStreamType(std::string& strInfo) -{ - char sInfo[64]; - - if (codec == AV_CODEC_ID_AC3) strcpy(sInfo, "AC3 "); - else if (codec == AV_CODEC_ID_DTS) - { -#ifdef FF_PROFILE_DTS_HD_MA - if (profile == FF_PROFILE_DTS_HD_MA) - strcpy(sInfo, "DTS-HD MA "); - else if (profile == FF_PROFILE_DTS_HD_HRA) - strcpy(sInfo, "DTS-HD HRA "); - else -#endif - strcpy(sInfo, "DTS "); - } - else if (codec == AV_CODEC_ID_MP2) strcpy(sInfo, "MP2 "); - else if (codec == AV_CODEC_ID_TRUEHD) strcpy(sInfo, "Dolby TrueHD "); - else strcpy(sInfo, ""); - - if (iChannels == 1) strcat(sInfo, "Mono"); - else if (iChannels == 2) strcat(sInfo, "Stereo"); - else if (iChannels == 6) strcat(sInfo, "5.1"); - else if (iChannels == 8) strcat(sInfo, "7.1"); - else if (iChannels != 0) - { - char temp[32]; - sprintf(temp, " %d%s", iChannels, "-chs"); - strcat(sInfo, temp); - } - strInfo = sInfo; -} - -int CDVDDemux::GetNrOfAudioStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_AUDIO) iCounter++; - } - - return iCounter; -} - -int CDVDDemux::GetNrOfVideoStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_VIDEO) iCounter++; - } - - return iCounter; -} - -int CDVDDemux::GetNrOfSubtitleStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_SUBTITLE) iCounter++; - } - - return iCounter; -} - -int CDVDDemux::GetNrOfTeletextStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_TELETEXT) iCounter++; - } - - return iCounter; -} - -CDemuxStreamAudio* CDVDDemux::GetStreamFromAudioId(int iAudioIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_AUDIO) counter++; - if (iAudioIndex == counter) - return (CDemuxStreamAudio*)pStream; - } - return NULL; -} - -CDemuxStreamVideo* CDVDDemux::GetStreamFromVideoId(int iVideoIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_VIDEO) counter++; - if (iVideoIndex == counter) - return (CDemuxStreamVideo*)pStream; - } - return NULL; -} - -CDemuxStreamSubtitle* CDVDDemux::GetStreamFromSubtitleId(int iSubtitleIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_SUBTITLE) counter++; - if (iSubtitleIndex == counter) - return (CDemuxStreamSubtitle*)pStream; - } - return NULL; -} - -CDemuxStreamTeletext* CDVDDemux::GetStreamFromTeletextId(int iTeletextIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_TELETEXT) counter++; - if (iTeletextIndex == counter) - return (CDemuxStreamTeletext*)pStream; - } - return NULL; -} - -void CDemuxStream::GetStreamName( std::string& strInfo ) -{ - strInfo = ""; -} - -AVDiscard CDemuxStream::GetDiscard() -{ - return AVDISCARD_NONE; -} - -void CDemuxStream::SetDiscard(AVDiscard discard) -{ - return; -} - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h deleted file mode 100644 index fca164d..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +++ /dev/null @@ -1,359 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include -#include "system.h" -#include "DVDDemuxPacket.h" - -class CDVDInputStream; - -#ifndef __GNUC__ -#pragma warning(push) -#pragma warning(disable:4244) -#endif - -#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS) - #include "config.h" -#endif - -extern "C" { -#include "libavcodec/avcodec.h" -} - -#ifndef __GNUC__ -#pragma warning(pop) -#endif - -enum AVDiscard; - -enum StreamType -{ - STREAM_NONE = 0,// if unknown - STREAM_AUDIO, // audio stream - STREAM_VIDEO, // video stream - STREAM_DATA, // data stream - STREAM_SUBTITLE,// subtitle stream - STREAM_TELETEXT // Teletext data stream -}; - -enum StreamSource { - STREAM_SOURCE_NONE = 0x000, - STREAM_SOURCE_DEMUX = 0x100, - STREAM_SOURCE_NAV = 0x200, - STREAM_SOURCE_DEMUX_SUB = 0x300, - STREAM_SOURCE_TEXT = 0x400, - STREAM_SOURCE_VIDEOMUX = 0x500 -}; - -#define STREAM_SOURCE_MASK(a) ((a) & 0xf00) - -/* - * CDemuxStream - * Base class for all demuxer streams - */ -class CDemuxStream -{ -public: - CDemuxStream() - { - iId = 0; - iPhysicalId = 0; - codec = (AVCodecID)0; // AV_CODEC_ID_NONE - codec_fourcc = 0; - profile = FF_PROFILE_UNKNOWN; - level = FF_LEVEL_UNKNOWN; - type = STREAM_NONE; - source = STREAM_SOURCE_NONE; - iDuration = 0; - pPrivate = NULL; - ExtraData = NULL; - ExtraSize = 0; - memset(language, 0, sizeof(language)); - disabled = false; - changes = 0; - flags = FLAG_NONE; - orig_type = 0; - } - - virtual ~CDemuxStream() - { - delete [] ExtraData; - } - - virtual void GetStreamInfo(std::string& strInfo) - { - strInfo = ""; - } - - virtual void GetStreamName(std::string& strInfo); - - virtual void SetDiscard(AVDiscard discard); - virtual AVDiscard GetDiscard(); - - int iId; // most of the time starting from 0 - int iPhysicalId; // id - AVCodecID codec; - unsigned int codec_fourcc; // if available - int profile; // encoder profile of the stream reported by the decoder. used to qualify hw decoders. - int level; // encoder level of the stream reported by the decoder. used to qualify hw decoders. - StreamType type; - int source; - - int iDuration; // in mseconds - void* pPrivate; // private pointer for the demuxer - uint8_t* ExtraData; // extra data for codec to use - unsigned int ExtraSize; // size of extra data - - char language[4]; // ISO 639 3-letter language code (empty string if undefined) - bool disabled; // set when stream is disabled. (when no decoder exists) - - int changes; // increment on change which player may need to know about - - int orig_type; // type of original source - - enum EFlags - { FLAG_NONE = 0x0000 - , FLAG_DEFAULT = 0x0001 - , FLAG_DUB = 0x0002 - , FLAG_ORIGINAL = 0x0004 - , FLAG_COMMENT = 0x0008 - , FLAG_LYRICS = 0x0010 - , FLAG_KARAOKE = 0x0020 - , FLAG_FORCED = 0x0040 - , FLAG_HEARING_IMPAIRED = 0x0080 - , FLAG_VISUAL_IMPAIRED = 0x0100 - } flags; -}; - -class CDemuxStreamVideo : public CDemuxStream -{ -public: - CDemuxStreamVideo() : CDemuxStream() - { - iFpsScale = 0; - iFpsRate = 0; - irFpsScale = 0; - irFpsRate = 0; - iHeight = 0; - iWidth = 0; - fAspect = 0.0; - bVFR = false; - bPTSInvalid = false; - bForcedAspect = false; - type = STREAM_VIDEO; - iOrientation = 0; - iBitsPerPixel = 0; - } - - virtual ~CDemuxStreamVideo() {} - int iFpsScale; // scale of 1000 and a rate of 29970 will result in 29.97 fps - int iFpsRate; - int irFpsScale; - int irFpsRate; - int iHeight; // height of the stream reported by the demuxer - int iWidth; // width of the stream reported by the demuxer - float fAspect; // display aspect of stream - bool bVFR; // variable framerate - bool bPTSInvalid; // pts cannot be trusted (avi's). - bool bForcedAspect; // aspect is forced from container - int iOrientation; // orientation of the video in degress counter clockwise - int iBitsPerPixel; - std::string stereo_mode; // expected stereo mode -}; - -class CDemuxStreamAudio : public CDemuxStream -{ -public: - CDemuxStreamAudio() : CDemuxStream() - { - iChannels = 0; - iSampleRate = 0; - iBlockAlign = 0; - iBitRate = 0; - iBitsPerSample = 0; - type = STREAM_AUDIO; - } - - virtual ~CDemuxStreamAudio() {} - - void GetStreamType(std::string& strInfo); - - int iChannels; - int iSampleRate; - int iBlockAlign; - int iBitRate; - int iBitsPerSample; -}; - -class CDemuxStreamSubtitle : public CDemuxStream -{ -public: - CDemuxStreamSubtitle() : CDemuxStream() - { - type = STREAM_SUBTITLE; - } -}; - -class CDemuxStreamTeletext : public CDemuxStream -{ -public: - CDemuxStreamTeletext() : CDemuxStream() - { - type = STREAM_TELETEXT; - } - virtual void GetStreamInfo(std::string& strInfo); -}; - -class CDVDDemux -{ -public: - - CDVDDemux() {} - virtual ~CDVDDemux() {} - - - /* - * Reset the entire demuxer (same result as closing and opening it) - */ - virtual void Reset() = 0; - - /* - * Aborts any internal reading that might be stalling main thread - * NOTICE - this can be called from another thread - */ - virtual void Abort() = 0; - - /* - * Flush the demuxer, if any data is kept in buffers, this should be freed now - */ - virtual void Flush() = 0; - - /* - * Read a packet, returns NULL on error - * - */ - virtual DemuxPacket* Read() = 0; - - /* - * Seek, time in msec calculated from stream start - */ - virtual bool SeekTime(int time, bool backwords = false, double* startpts = NULL) = 0; - - /* - * Seek to a specified chapter. - * startpts can be updated to the point where display should start - */ - virtual bool SeekChapter(int chapter, double* startpts = NULL) { return false; } - - /* - * Get the number of chapters available - */ - virtual int GetChapterCount() { return 0; } - - /* - * Get current chapter - */ - virtual int GetChapter() { return 0; } - - /* - * Get the name of a chapter - * \param strChapterName[out] Name of chapter - * \param chapterIdx -1 for current chapter, else a chapter index - */ - virtual void GetChapterName(std::string& strChapterName, int chapterIdx=-1) {} - - /* - * Get the position of a chapter - * \param chapterIdx -1 for current chapter, else a chapter index - */ - virtual int64_t GetChapterPos(int chapterIdx=-1) { return 0; } - - /* - * Set the playspeed, if demuxer can handle different - * speeds of playback - */ - virtual void SetSpeed(int iSpeed) = 0; - - /* - * returns the total time in msec - */ - virtual int GetStreamLength() = 0; - - /* - * returns the stream or NULL on error, starting from 0 - */ - virtual CDemuxStream* GetStream(int iStreamId) = 0; - - /* - * return nr of streams, 0 if none - */ - virtual int GetNrOfStreams() = 0; - - /* - * returns opened filename - */ - virtual std::string GetFileName() = 0; - /* - * return nr of audio streams, 0 if none - */ - int GetNrOfAudioStreams(); - - /* - * return nr of video streams, 0 if none - */ - int GetNrOfVideoStreams(); - - /* - * return nr of subtitle streams, 0 if none - */ - int GetNrOfSubtitleStreams(); - - /* - * return nr of teletext streams, 0 if none - */ - int GetNrOfTeletextStreams(); - - /* - * return the audio stream, or NULL if it does not exist - */ - CDemuxStreamAudio* GetStreamFromAudioId(int iAudioIndex); - - /* - * return the video stream, or NULL if it does not exist - */ - CDemuxStreamVideo* GetStreamFromVideoId(int iVideoIndex); - - /* - * return the subtitle stream, or NULL if it does not exist - */ - CDemuxStreamSubtitle* GetStreamFromSubtitleId(int iSubtitleIndex); - - /* - * return the teletext stream, or NULL if it does not exist - */ - CDemuxStreamTeletext* GetStreamFromTeletextId(int iTeletextIndex); - - /* - * return a user-presentable codec name of the given stream - */ - virtual void GetStreamCodecName(int iStreamId, std::string &strName) {}; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp deleted file mode 100644 index 9786983..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDDemuxBXA.h" -#include "DVDDemuxUtils.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "../DVDClock.h" - -// AirTunes audio Demuxer. - -using namespace std; - -class CDemuxStreamAudioBXA - : public CDemuxStreamAudio -{ - CDVDDemuxBXA *m_parent; - string m_codec; -public: - CDemuxStreamAudioBXA(CDVDDemuxBXA *parent, const string& codec) - : m_parent(parent) - , m_codec(codec) - - {} - void GetStreamInfo(string& strInfo) - { - strInfo = StringUtils::Format("%s", m_codec.c_str()); - } -}; - -CDVDDemuxBXA::CDVDDemuxBXA() : CDVDDemux() -{ - m_pInput = NULL; - m_stream = NULL; - m_bytes = 0; - memset(&m_header, 0x0, sizeof(Demux_BXA_FmtHeader)); -} - -CDVDDemuxBXA::~CDVDDemuxBXA() -{ - Dispose(); -} - -bool CDVDDemuxBXA::Open(CDVDInputStream* pInput) -{ - Abort(); - - Dispose(); - - if(!pInput || !pInput->IsStreamType(DVDSTREAM_TYPE_FILE)) - return false; - - if(pInput->Read((uint8_t *)&m_header, sizeof(Demux_BXA_FmtHeader)) < 1) - return false; - - // file valid? - if (strncmp(m_header.fourcc, "BXA ", 4) != 0 || m_header.type != BXA_PACKET_TYPE_FMT_DEMUX) - { - pInput->Seek(0, SEEK_SET); - return false; - } - - m_pInput = pInput; - - m_stream = new CDemuxStreamAudioBXA(this, "BXA"); - - if(!m_stream) - return false; - - m_stream->iSampleRate = m_header.sampleRate; - m_stream->iBitsPerSample = m_header.bitsPerSample; - m_stream->iBitRate = m_header.sampleRate * m_header.channels * m_header.bitsPerSample; - m_stream->iChannels = m_header.channels; - m_stream->type = STREAM_AUDIO; - m_stream->codec = AV_CODEC_ID_PCM_S16LE; - - return true; -} - -void CDVDDemuxBXA::Dispose() -{ - delete m_stream; - m_stream = NULL; - - m_pInput = NULL; - m_bytes = 0; - - memset(&m_header, 0x0, sizeof(Demux_BXA_FmtHeader)); -} - -void CDVDDemuxBXA::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxBXA::Abort() -{ - if(m_pInput) - return m_pInput->Abort(); -} - -void CDVDDemuxBXA::Flush() -{ -} - -#define BXA_READ_SIZE 4096 -DemuxPacket* CDVDDemuxBXA::Read() -{ - if(!m_pInput) - return NULL; - - DemuxPacket* pPacket = CDVDDemuxUtils::AllocateDemuxPacket(BXA_READ_SIZE); - - if (!pPacket) - { - if (m_pInput) - m_pInput->Close(); - return NULL; - } - - pPacket->iSize = m_pInput->Read(pPacket->pData, BXA_READ_SIZE); - pPacket->iStreamId = 0; - - if(pPacket->iSize < 1) - { - delete pPacket; - pPacket = NULL; - } - else - { - int n = (m_header.channels * m_header.bitsPerSample * m_header.sampleRate)>>3; - if (n > 0) - { - m_bytes += pPacket->iSize; - pPacket->dts = (double)m_bytes * DVD_TIME_BASE / n; - pPacket->pts = pPacket->dts; - } - else - { - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - } - } - - return pPacket; -} - -CDemuxStream* CDVDDemuxBXA::GetStream(int iStreamId) -{ - if(iStreamId != 0) - return NULL; - - return m_stream; -} - -int CDVDDemuxBXA::GetNrOfStreams() -{ - return (m_stream == NULL ? 0 : 1); -} - -std::string CDVDDemuxBXA::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -void CDVDDemuxBXA::GetStreamCodecName(int iStreamId, std::string &strName) -{ - if (m_stream && iStreamId == 0) - strName = "BXA"; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h deleted file mode 100644 index bdb65b4..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "DVDDemux.h" - -#ifdef TARGET_WINDOWS -#define __attribute__(dummy_val) -#else -#include -#endif - -#ifdef TARGET_WINDOWS -#pragma pack(push) -#pragma pack(1) -#endif - -typedef struct -{ - char fourcc[4]; - uint32_t type; - uint32_t channels; - uint32_t sampleRate; - uint32_t bitsPerSample; - uint64_t durationMs; -} __attribute__((__packed__)) Demux_BXA_FmtHeader; - -#ifdef TARGET_WINDOWS -#pragma pack(pop) -#endif - -#include - -#define BXA_PACKET_TYPE_FMT_DEMUX 1 - -class CDemuxStreamAudioBXA; - -class CDVDDemuxBXA : public CDVDDemux -{ -public: - - CDVDDemuxBXA(); - ~CDVDDemuxBXA(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Abort(); - void Flush(); - DemuxPacket* Read(); - bool SeekTime(int time, bool backwords = false, double* startpts = NULL) { return false; } - void SetSpeed(int iSpeed) {}; - int GetStreamLength() { return (int)m_header.durationMs; } - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - std::string GetFileName(); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - -protected: - friend class CDemuxStreamAudioBXA; - CDVDInputStream* m_pInput; - int64_t m_bytes; - - CDemuxStreamAudioBXA *m_stream; - - Demux_BXA_FmtHeader m_header; -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp deleted file mode 100644 index 24d56da..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/* - * 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 - * . - * - */ - -#include "DVDDemuxUtils.h" -#include "DVDClock.h" -#include "DVDDemuxCC.h" -#include "cores/dvdplayer/DVDCodecs/Overlay/contrib/cc_decoder708.h" -#include "utils/log.h" - -#include - -class CBitstream -{ -public: - CBitstream(uint8_t *data, int bits) - { - m_data = data; - m_offset = 0; - m_len = bits; - m_error = false; - } - unsigned int readBits(int num) - { - int r = 0; - while (num > 0) - { - if (m_offset >= m_len) - { - m_error = true; - return 0; - } - num--; - if (m_data[m_offset / 8] & (1 << (7 - (m_offset & 7)))) - r |= 1 << num; - m_offset++; - } - return r; - } - unsigned int readGolombUE(int maxbits = 32) - { - int lzb = -1; - int bits = 0; - for (int b = 0; !b; lzb++, bits++) - { - if (bits > maxbits) - return 0; - b = readBits(1); - } - return (1 << lzb) - 1 + readBits(lzb); - } - -private: - uint8_t *m_data; - int m_offset; - int m_len; - bool m_error; -}; - -class CCaptionBlock -{ -public: - CCaptionBlock(int size) - { - m_data = (uint8_t*)malloc(size); - m_size = size; - } - virtual ~CCaptionBlock() - { - free(m_data); - } - double m_pts; - uint8_t *m_data; - int m_size; -}; - -bool reorder_sort (CCaptionBlock *lhs, CCaptionBlock *rhs) -{ - return (lhs->m_pts > rhs->m_pts); -} - -CDVDDemuxCC::CDVDDemuxCC(AVCodecID codec) -{ - m_hasData = false; - m_curPts = 0; - m_ccDecoder = NULL; - m_codec = codec; -} - -CDVDDemuxCC::~CDVDDemuxCC() -{ - Dispose(); -} - -CDemuxStream* CDVDDemuxCC::GetStream(int iStreamId) -{ - return &m_streams[iStreamId]; -} - -int CDVDDemuxCC::GetNrOfStreams() -{ - return m_streams.size(); -} - -DemuxPacket* CDVDDemuxCC::Read(DemuxPacket *pSrcPacket) -{ - DemuxPacket *pPacket = NULL; - uint32_t startcode = 0xffffffff; - int picType = 0; - int p = 0; - int len; - - if (!pSrcPacket) - { - pPacket = Decode(); - return pPacket; - } - if (pSrcPacket->pts == DVD_NOPTS_VALUE) - { - return pPacket; - } - - while (!m_ccTempBuffer.empty()) - { - m_ccReorderBuffer.push_back(m_ccTempBuffer.back()); - m_ccTempBuffer.pop_back(); - } - - while ((len = pSrcPacket->iSize - p) > 3) - { - if ((startcode & 0xffffff00) == 0x00000100) - { - if (m_codec == AV_CODEC_ID_MPEG2VIDEO) - { - int scode = startcode & 0xFF; - if (scode == 0x00) - { - if (len > 4) - { - uint8_t *buf = pSrcPacket->pData + p; - picType = (buf[1] & 0x38) >> 3; - } - } - else if (scode == 0xb2) // user data - { - uint8_t *buf = pSrcPacket->pData + p; - if (len >= 6 && - buf[0] == 'G' && buf[1] == 'A' && buf[2] == '9' && buf[3] == '4' && - buf[4] == 3 && (buf[5] & 0x40)) - { - int cc_count = buf[5] & 0x1f; - if (cc_count > 0 && len >= 7 + cc_count * 3) - { - CCaptionBlock *cc = new CCaptionBlock(cc_count * 3); - memcpy(cc->m_data, buf + 7, cc_count * 3); - cc->m_pts = pSrcPacket->pts; - if (picType == 1 || picType == 2) - m_ccTempBuffer.push_back(cc); - else - m_ccReorderBuffer.push_back(cc); - } - } - else if (len >= 6 && - buf[0] == 'C' && buf[1] == 'C' && buf[2] == 1) - { - int oddidx = (buf[4] & 0x80) ? 0 : 1; - int cc_count = (buf[4] & 0x3e) >> 1; - int extrafield = buf[4] & 0x01; - if (extrafield) - cc_count++; - - if (cc_count > 0 && len >= 5 + cc_count * 3 * 2) - { - CCaptionBlock *cc = new CCaptionBlock(cc_count * 3); - uint8_t *src = buf + 5; - uint8_t *dst = cc->m_data; - - for (int i = 0; i < cc_count; i++) - { - for (int j = 0; j < 2; j++) - { - if (i == cc_count - 1 && extrafield && j == 1) - break; - - if ((oddidx == j) && (src[0] == 0xFF)) - { - dst[0] = 0x04; - dst[1] = src[1]; - dst[2] = src[2]; - dst += 3; - } - src += 3; - } - } - cc->m_pts = pSrcPacket->pts; - m_ccReorderBuffer.push_back(cc); - picType = 1; - } - } - } - } - else if (m_codec == AV_CODEC_ID_H264) - { - int scode = startcode & 0x9F; - // slice data comes after SEI - if (scode >= 1 && scode <= 5) - { - uint8_t *buf = pSrcPacket->pData + p; - CBitstream bs(buf, len * 8); - bs.readGolombUE(); - int sliceType = bs.readGolombUE(); - if (sliceType == 2 || sliceType == 7) // I slice - picType = 1; - else if (sliceType == 0 || sliceType == 5) // P slice - picType = 2; - if (picType == 0) - { - while (!m_ccTempBuffer.empty()) - { - m_ccReorderBuffer.push_back(m_ccTempBuffer.back()); - m_ccTempBuffer.pop_back(); - } - } - } - if (scode == 0x06) // SEI - { - uint8_t *buf = pSrcPacket->pData + p; - if (len >= 12 && - buf[3] == 0 && buf[4] == 49 && - buf[5] == 'G' && buf[6] == 'A' && buf[7] == '9' && buf[8] == '4' && buf[9] == 3) - { - uint8_t *userdata = buf + 10; - int cc_count = userdata[0] & 0x1f; - if (len >= cc_count * 3 + 10) - { - CCaptionBlock *cc = new CCaptionBlock(cc_count * 3); - memcpy(cc->m_data, userdata + 2, cc_count * 3); - cc->m_pts = pSrcPacket->pts; - m_ccTempBuffer.push_back(cc); - } - } - } - } - } - startcode = startcode << 8 | pSrcPacket->pData[p++]; - } - - if ((picType == 1 || picType == 2) && !m_ccReorderBuffer.empty()) - { - if (!m_ccDecoder) - { - if (!OpenDecoder()) - return NULL; - } - std::sort(m_ccReorderBuffer.begin(), m_ccReorderBuffer.end(), reorder_sort); - pPacket = Decode(); - } - return pPacket; -} - -void CDVDDemuxCC::Handler(int service, void *userdata) -{ - CDVDDemuxCC *ctx = (CDVDDemuxCC*)userdata; - - unsigned int idx; - - // switch back from 608 fallback if we got 708 - if (ctx->m_ccDecoder->m_seen608 && ctx->m_ccDecoder->m_seen708) - { - for (idx = 0; idx < ctx->m_streamdata.size(); idx++) - { - if (ctx->m_streamdata[idx].service == 0) - break; - } - if (idx < ctx->m_streamdata.size()) - { - ctx->m_streamdata.erase(ctx->m_streamdata.begin() + idx); - ctx->m_ccDecoder->m_seen608 = false; - } - if (service == 0) - return; - } - - for (idx = 0; idx < ctx->m_streamdata.size(); idx++) - { - if (ctx->m_streamdata[idx].service == service) - break; - } - if (idx >= ctx->m_streamdata.size()) - { - CDemuxStreamSubtitle stream; - strcpy(stream.language, "cc"); - stream.codec = AV_CODEC_ID_TEXT; - stream.iPhysicalId = service; - stream.iId = idx; - ctx->m_streams.push_back(stream); - - streamdata data; - data.streamIdx = idx; - data.service = service; - ctx->m_streamdata.push_back(data); - - if (service == 0) - ctx->m_ccDecoder->m_seen608 = true; - else - ctx->m_ccDecoder->m_seen708 = true; - } - - ctx->m_streamdata[idx].pts = ctx->m_curPts; - ctx->m_streamdata[idx].hasData = true; - ctx->m_hasData = true; -} - -bool CDVDDemuxCC::OpenDecoder() -{ - m_ccDecoder = new CDecoderCC708(); - m_ccDecoder->Init(Handler, this); - return true; -} - -void CDVDDemuxCC::Dispose() -{ - m_streams.clear(); - m_streamdata.clear(); - delete m_ccDecoder; - m_ccDecoder = NULL; - - while (!m_ccReorderBuffer.empty()) - { - delete m_ccReorderBuffer.back(); - m_ccReorderBuffer.pop_back(); - } - while (!m_ccTempBuffer.empty()) - { - delete m_ccTempBuffer.back(); - m_ccTempBuffer.pop_back(); - } -} - -DemuxPacket* CDVDDemuxCC::Decode() -{ - DemuxPacket *pPacket = NULL; - - while(!m_hasData && !m_ccReorderBuffer.empty()) - { - CCaptionBlock *cc = m_ccReorderBuffer.back(); - m_ccReorderBuffer.pop_back(); - m_curPts = cc->m_pts; - m_ccDecoder->Decode(cc->m_data, cc->m_size); - delete cc; - } - - if (m_hasData) - { - for (unsigned int i=0; im_cc608decoder->text; - len = m_ccDecoder->m_cc608decoder->textlen; - } - else - { - data = m_ccDecoder->m_cc708decoders[service].text; - len = m_ccDecoder->m_cc708decoders[service].textlen; - } - - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(len); - pPacket->iSize = len; - memcpy(pPacket->pData, data, pPacket->iSize); - - pPacket->iStreamId = i; - pPacket->pts = m_streamdata[i].pts; - pPacket->duration = 0; - m_streamdata[i].hasData = false; - break; - } - m_hasData = false; - } - } - return pPacket; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h deleted file mode 100644 index ae78298..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 - * . - * - */ - -#pragma once -#include "DVDDemux.h" -#include - -class CCaptionBlock; -class CDecoderCC708; - -class CDVDDemuxCC : public CDVDDemux -{ -public: - CDVDDemuxCC(AVCodecID codec); - virtual ~CDVDDemuxCC(); - - virtual void Reset() {}; - virtual void Abort() {}; - virtual void Flush() {}; - virtual DemuxPacket* Read() { return NULL; }; - virtual bool SeekTime(int time, bool backwords = false, double* startpts = NULL) {return true;}; - virtual void SetSpeed(int iSpeed) {}; - virtual int GetStreamLength() {return 0;}; - virtual CDemuxStream* GetStream(int iStreamId); - virtual int GetNrOfStreams(); - virtual std::string GetFileName() {return "";}; - - DemuxPacket* Read(DemuxPacket *packet); - static void Handler(int service, void *userdata); - -protected: - bool OpenDecoder(); - void Dispose(); - DemuxPacket* Decode(); - - struct streamdata - { - int streamIdx; - int service; - bool hasData ; - double pts; - }; - std::vector m_streamdata; - std::vector m_streams; - bool m_hasData; - double m_curPts; - std::vector m_ccReorderBuffer; - std::vector m_ccTempBuffer; - CDecoderCC708 *m_ccDecoder; - AVCodecID m_codec; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp deleted file mode 100644 index 72067da..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 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 - * . - * - */ - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDDemuxCDDA.h" -#include "DVDDemuxUtils.h" -#include "utils/log.h" -#include "../DVDClock.h" - -// CDDA audio demuxer based on AirTunes audio Demuxer. - -using namespace std; - -class CDemuxStreamAudioCDDA - : public CDemuxStreamAudio -{ -public: - void GetStreamInfo(string& strInfo) - { - strInfo = "pcm"; - } -}; - -CDVDDemuxCDDA::CDVDDemuxCDDA() : CDVDDemux() -{ - m_pInput = NULL; - m_stream = NULL; - m_bytes = 0; -} - -CDVDDemuxCDDA::~CDVDDemuxCDDA() -{ - Dispose(); -} - -bool CDVDDemuxCDDA::Open(CDVDInputStream* pInput) -{ - Abort(); - - Dispose(); - - if(!pInput || !pInput->IsStreamType(DVDSTREAM_TYPE_FILE)) - return false; - - m_pInput = pInput; - - m_stream = new CDemuxStreamAudioCDDA(); - - if(!m_stream) - return false; - - m_stream->iSampleRate = 44100; - m_stream->iBitsPerSample = 16; - m_stream->iBitRate = 44100 * 2 * 16; - m_stream->iChannels = 2; - m_stream->type = STREAM_AUDIO; - m_stream->codec = AV_CODEC_ID_PCM_S16LE; - - return true; -} - -void CDVDDemuxCDDA::Dispose() -{ - delete m_stream; - m_stream = NULL; - - m_pInput = NULL; - m_bytes = 0; -} - -void CDVDDemuxCDDA::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxCDDA::Abort() -{ - if(m_pInput) - return m_pInput->Abort(); -} - -void CDVDDemuxCDDA::Flush() -{ -} - -#define CDDA_READ_SIZE 4096 -DemuxPacket* CDVDDemuxCDDA::Read() -{ - if(!m_pInput) - return NULL; - - DemuxPacket* pPacket = CDVDDemuxUtils::AllocateDemuxPacket(CDDA_READ_SIZE); - - if (!pPacket) - { - if (m_pInput) - m_pInput->Close(); - return NULL; - } - - pPacket->iSize = m_pInput->Read(pPacket->pData, CDDA_READ_SIZE); - pPacket->iStreamId = 0; - - if(pPacket->iSize < 1) - { - delete pPacket; - pPacket = NULL; - } - else - { - int n = m_stream->iBitRate>>3; - if (n > 0) - { - m_bytes += pPacket->iSize; - pPacket->dts = (double)m_bytes * DVD_TIME_BASE / n; - pPacket->pts = pPacket->dts; - } - else - { - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - } - } - - return pPacket; -} - -bool CDVDDemuxCDDA::SeekTime(int time, bool backwords, double* startpts) -{ - int bytes_per_second = m_stream->iBitRate>>3; - // clamp seeks to bytes per full sample - int clamp_bytes = (m_stream->iBitsPerSample>>3) * m_stream->iChannels; - - // time is in milliseconds - int64_t seekPos = m_pInput->Seek((((int64_t)time * bytes_per_second / 1000) / clamp_bytes ) * clamp_bytes, SEEK_SET) > 0; - if (seekPos > 0) - m_bytes = seekPos; - - if (startpts) - *startpts = (double)m_bytes * DVD_TIME_BASE / bytes_per_second; - - return seekPos > 0; -}; - -int CDVDDemuxCDDA::GetStreamLength() -{ - int64_t num_track_bytes = m_pInput->GetLength(); - int bytes_per_second = (m_stream->iBitRate>>3); - int64_t track_mseconds = num_track_bytes*1000 / bytes_per_second; - return (int)track_mseconds; -} - -CDemuxStream* CDVDDemuxCDDA::GetStream(int iStreamId) -{ - if(iStreamId != 0) - return NULL; - - return m_stream; -} - -int CDVDDemuxCDDA::GetNrOfStreams() -{ - return (m_stream == NULL ? 0 : 1); -} - -std::string CDVDDemuxCDDA::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -void CDVDDemuxCDDA::GetStreamCodecName(int iStreamId, std::string &strName) -{ - if (m_stream && iStreamId == 0) - strName = "pcm"; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h deleted file mode 100644 index 6a3c50a..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once -/* - * Copyright (C) 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 - * . - * - */ - -#include "DVDDemux.h" -#include "utils/log.h" - -#ifdef TARGET_WINDOWS -#define __attribute__(dummy_val) -#else -#include -#endif - -class CDemuxStreamAudioCDDA; - -class CDVDDemuxCDDA : public CDVDDemux -{ -public: - - CDVDDemuxCDDA(); - ~CDVDDemuxCDDA(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Abort(); - void Flush(); - DemuxPacket* Read(); - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - void SetSpeed(int iSpeed) {}; - int GetStreamLength() ; - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - std::string GetFileName(); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - -protected: - friend class CDemuxStreamAudioCDDA; - CDVDInputStream* m_pInput; - int64_t m_bytes; - - CDemuxStreamAudioCDDA *m_stream; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp deleted file mode 100644 index f58472f..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ /dev/null @@ -1,1767 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "system.h" -#ifndef __STDC_CONSTANT_MACROS -#define __STDC_CONSTANT_MACROS -#endif -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS -#endif -#ifdef TARGET_POSIX -#include "stdint.h" -#endif -#include "DVDDemuxFFmpeg.h" -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDInputStreams/DVDInputStreamNavigator.h" -#ifdef HAVE_LIBBLURAY -#include "DVDInputStreams/DVDInputStreamBluray.h" -#endif -#include "DVDInputStreams/DVDInputStreamPVRManager.h" -#include "DVDInputStreams/DVDInputStreamFFmpeg.h" -#include "DVDDemuxUtils.h" -#include "DVDClock.h" // for DVD_TIME_BASE -#include "commons/Exception.h" -#include "settings/AdvancedSettings.h" -#include "settings/Settings.h" -#include "filesystem/File.h" -#include "filesystem/CurlFile.h" -#include "filesystem/Directory.h" -#include "utils/log.h" -#include "threads/Thread.h" -#include "threads/SystemClock.h" -#include "utils/TimeUtils.h" -#include "utils/StringUtils.h" -#include "URL.h" -#include "cores/FFmpeg.h" - -extern "C" { -#include "libavutil/opt.h" -} - -struct StereoModeConversionMap -{ - const char* name; - const char* mode; -}; - -// we internally use the matroska string representation of stereoscopic modes. -// This struct is a conversion map to convert stereoscopic mode values -// from asf/wmv to the internally used matroska ones -static const struct StereoModeConversionMap WmvToInternalStereoModeMap[] = -{ - { "SideBySideRF", "right_left" }, - { "SideBySideLF", "left_right" }, - { "OverUnderRT", "bottom_top" }, - { "OverUnderLT", "top_bottom" }, - {} -}; - -#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE) - -void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo) -{ - if(!m_stream) return; - char temp[128]; - avcodec_string(temp, 128, m_stream->codec, 0); - strInfo = temp; -} - -void CDemuxStreamAudioFFmpeg::GetStreamName(std::string& strInfo) -{ - if(!m_stream) return; - if(!m_description.empty()) - strInfo = m_description; - else - CDemuxStream::GetStreamName(strInfo); -} - -void CDemuxStreamSubtitleFFmpeg::GetStreamName(std::string& strInfo) -{ - if(!m_stream) return; - if(!m_description.empty()) - strInfo = m_description; - else - CDemuxStream::GetStreamName(strInfo); -} - -void CDemuxStreamVideoFFmpeg::GetStreamInfo(std::string& strInfo) -{ - if(!m_stream) return; - char temp[128]; - avcodec_string(temp, 128, m_stream->codec, 0); - strInfo = temp; -} - -void CDemuxStreamSubtitleFFmpeg::GetStreamInfo(std::string& strInfo) -{ - if(!m_stream) return; - char temp[128]; - avcodec_string(temp, 128, m_stream->codec, 0); - strInfo = temp; -} - -static int interrupt_cb(void* ctx) -{ - CDVDDemuxFFmpeg* demuxer = static_cast(ctx); - if(demuxer && demuxer->Aborted()) - return 1; - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -/* -static int dvd_file_open(URLContext *h, const char *filename, int flags) -{ - return -1; -} -*/ - -static int dvd_file_read(void *h, uint8_t* buf, int size) -{ - if(interrupt_cb(h)) - return AVERROR_EXIT; - - CDVDInputStream* pInputStream = static_cast(h)->m_pInput; - return pInputStream->Read(buf, size); -} -/* -static int dvd_file_write(URLContext *h, uint8_t* buf, int size) -{ - return -1; -} -*/ -static int64_t dvd_file_seek(void *h, int64_t pos, int whence) -{ - if(interrupt_cb(h)) - return AVERROR_EXIT; - - CDVDInputStream* pInputStream = static_cast(h)->m_pInput; - if(whence == AVSEEK_SIZE) - return pInputStream->GetLength(); - else - return pInputStream->Seek(pos, whence & ~AVSEEK_FORCE); -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// - -CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux() -{ - m_pFormatContext = NULL; - m_pInput = NULL; - m_ioContext = NULL; - m_currentPts = DVD_NOPTS_VALUE; - m_bMatroska = false; - m_bAVI = false; - m_speed = DVD_PLAYSPEED_NORMAL; - m_program = UINT_MAX; - m_pkt.result = -1; - memset(&m_pkt.pkt, 0, sizeof(AVPacket)); - m_streaminfo = true; /* set to true if we want to look for streams before playback */ - m_checkvideo = false; -} - -CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg() -{ - Dispose(); - ff_flush_avutil_log_buffers(); -} - -bool CDVDDemuxFFmpeg::Aborted() -{ - if(m_timeout.IsTimePast()) - return true; - - CDVDInputStreamFFmpeg * input = dynamic_cast(m_pInput); - if(input && input->Aborted()) - return true; - - return false; -} - -bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo, bool fileinfo) -{ - AVInputFormat* iformat = NULL; - std::string strFile; - m_streaminfo = streaminfo; - m_currentPts = DVD_NOPTS_VALUE; - m_speed = DVD_PLAYSPEED_NORMAL; - m_program = UINT_MAX; - const AVIOInterruptCB int_cb = { interrupt_cb, this }; - - if (!pInput) return false; - - m_pInput = pInput; - strFile = m_pInput->GetFileName(); - - if( m_pInput->GetContent().length() > 0 ) - { - std::string content = m_pInput->GetContent(); - StringUtils::ToLower(content); - - /* check if we can get a hint from content */ - if ( content.compare("video/x-vobsub") == 0 ) - iformat = av_find_input_format("mpeg"); - else if( content.compare("video/x-dvd-mpeg") == 0 ) - iformat = av_find_input_format("mpeg"); - else if( content.compare("video/mp2t") == 0 ) - iformat = av_find_input_format("mpegts"); - else if( content.compare("multipart/x-mixed-replace") == 0 ) - iformat = av_find_input_format("mjpeg"); - } - - // open the demuxer - m_pFormatContext = avformat_alloc_context(); - m_pFormatContext->interrupt_callback = int_cb; - - // try to abort after 30 seconds - m_timeout.Set(30000); - - if( m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG) ) - { - // special stream type that makes avformat handle file opening - // allows internal ffmpeg protocols to be used - CURL url = m_pInput->GetURL(); - - AVDictionary *options = GetFFMpegOptionsFromURL(url); - - int result=-1; - if (url.IsProtocol("mms")) - { - // try mmsh, then mmst - url.SetProtocol("mmsh"); - url.SetProtocolOptions(""); - result = avformat_open_input(&m_pFormatContext, url.Get().c_str(), iformat, &options); - if (result < 0) - { - url.SetProtocol("mmst"); - strFile = url.Get(); - } - } - if (result < 0 && avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0 ) - { - CLog::Log(LOGDEBUG, "Error, could not open file %s", CURL::GetRedacted(strFile).c_str()); - Dispose(); - av_dict_free(&options); - return false; - } - av_dict_free(&options); - } - else - { - unsigned char* buffer = (unsigned char*)av_malloc(FFMPEG_FILE_BUFFER_SIZE); - m_ioContext = avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, this, dvd_file_read, NULL, dvd_file_seek); - m_ioContext->max_packet_size = m_pInput->GetBlockSize(); - if(m_ioContext->max_packet_size) - m_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size; - - if(m_pInput->Seek(0, SEEK_POSSIBLE) == 0) - m_ioContext->seekable = 0; - - std::string content = m_pInput->GetContent(); - StringUtils::ToLower(content); - if (StringUtils::StartsWith(content, "audio/l16")) - iformat = av_find_input_format("s16be"); - - if( iformat == NULL ) - { - // let ffmpeg decide which demuxer we have to open - - bool trySPDIFonly = (m_pInput->GetContent() == "audio/x-spdif-compressed"); - - if (!trySPDIFonly) - av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0); - - // Use the more low-level code in case we have been built against an old - // FFmpeg without the above av_probe_input_buffer(), or in case we only - // want to probe for spdif (DTS or IEC 61937) compressed audio - // specifically, or in case the file is a wav which may contain DTS or - // IEC 61937 (e.g. ac3-in-wav) and we want to check for those formats. - if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0)) - { - AVProbeData pd; - uint8_t probe_buffer[FFMPEG_FILE_BUFFER_SIZE + AVPROBE_PADDING_SIZE]; - - // init probe data - pd.buf = probe_buffer; - pd.filename = strFile.c_str(); - - // av_probe_input_buffer might have changed the buffer_size beyond our allocated amount - int buffer_size = std::min((int) FFMPEG_FILE_BUFFER_SIZE, m_ioContext->buffer_size); - // read data using avformat's buffers - pd.buf_size = avio_read(m_ioContext, pd.buf, m_ioContext->max_packet_size ? m_ioContext->max_packet_size : buffer_size); - if (pd.buf_size <= 0) - { - CLog::Log(LOGERROR, "%s - error reading from input stream, %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); - return false; - } - memset(pd.buf+pd.buf_size, 0, AVPROBE_PADDING_SIZE); - - // restore position again - avio_seek(m_ioContext , 0, SEEK_SET); - - // the advancedsetting is for allowing the user to force outputting the - // 44.1 kHz DTS wav file as PCM, so that an A/V receiver can decode - // it (this is temporary until we handle 44.1 kHz passthrough properly) - if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0 && !g_advancedSettings.m_dvdplayerIgnoreDTSinWAV)) - { - // check for spdif and dts - // This is used with wav files and audio CDs that may contain - // a DTS or AC3 track padded for S/PDIF playback. If neither of those - // is present, we assume it is PCM audio. - // AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS - // may be just padded. - AVInputFormat *iformat2; - iformat2 = av_find_input_format("spdif"); - - if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) - { - iformat = iformat2; - } - else - { - // not spdif or no spdif demuxer, try dts - iformat2 = av_find_input_format("dts"); - - if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) - { - iformat = iformat2; - } - else if (trySPDIFonly) - { - // not dts either, return false in case we were explicitely - // requested to only check for S/PDIF padded compressed audio - CLog::Log(LOGDEBUG, "%s - not spdif or dts file, fallbacking", __FUNCTION__); - return false; - } - } - } - } - - if(!iformat) - { - std::string content = m_pInput->GetContent(); - - /* check if we can get a hint from content */ - if( content.compare("audio/aacp") == 0 ) - iformat = av_find_input_format("aac"); - else if( content.compare("audio/aac") == 0 ) - iformat = av_find_input_format("aac"); - else if( content.compare("video/flv") == 0 ) - iformat = av_find_input_format("flv"); - else if( content.compare("video/x-flv") == 0 ) - iformat = av_find_input_format("flv"); - } - - if (!iformat) - { - CLog::Log(LOGERROR, "%s - error probing input format, %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); - return false; - } - else - { - if (iformat->name) - CLog::Log(LOGDEBUG, "%s - probing detected format [%s]", __FUNCTION__, iformat->name); - else - CLog::Log(LOGDEBUG, "%s - probing detected unnamed format", __FUNCTION__); - } - } - - - m_pFormatContext->pb = m_ioContext; - - AVDictionary *options = NULL; - if (iformat->name && (strcmp(iformat->name, "mp3") == 0 || strcmp(iformat->name, "mp2") == 0)) - { - CLog::Log(LOGDEBUG, "%s - setting usetoc to 0 for accurate VBR MP3 seek", __FUNCTION__); - av_dict_set(&options, "usetoc", "0", 0); - } - - if (StringUtils::StartsWith(content, "audio/l16")) - { - int channels = 2; - int samplerate = 44100; - GetL16Parameters(channels, samplerate); - av_dict_set_int(&options, "channels", channels, 0); - av_dict_set_int(&options, "sample_rate", samplerate, 0); - } - - if (avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0) - { - CLog::Log(LOGERROR, "%s - Error, could not open file %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); - Dispose(); - av_dict_free(&options); - return false; - } - av_dict_free(&options); - } - - // Avoid detecting framerate if advancedsettings.xml says so - if (g_advancedSettings.m_videoFpsDetect == 0) - m_pFormatContext->fps_probe_size = 0; - - // analyse very short to speed up mjpeg playback start - if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) - av_opt_set_int(m_pFormatContext, "analyzeduration", 500000, 0); - - bool skipCreateStreams = false; - bool isBluray = pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY); - if (iformat && (strcmp(iformat->name, "mpegts") == 0) && !fileinfo && !isBluray) - { - av_opt_set_int(m_pFormatContext, "analyzeduration", 500000, 0); - m_checkvideo = true; - skipCreateStreams = true; - } - else if (!iformat || (strcmp(iformat->name, "mpegts") != 0)) - { - m_streaminfo = true; - } - - // we need to know if this is matroska or avi later - m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" - m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; - - if (m_streaminfo) - { - /* to speed up dvd switches, only analyse very short */ - if(m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) - av_opt_set_int(m_pFormatContext, "analyzeduration", 500000, 0); - - CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__); - int iErr = avformat_find_stream_info(m_pFormatContext, NULL); - if (iErr < 0) - { - CLog::Log(LOGWARNING,"could not find codec parameters for %s", CURL::GetRedacted(strFile).c_str()); - if (m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) - || m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY) - || (m_pFormatContext->nb_streams == 1 && m_pFormatContext->streams[0]->codec->codec_id == AV_CODEC_ID_AC3)) - { - // special case, our codecs can still handle it. - } - else - { - Dispose(); - return false; - } - } - CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); - - if (m_checkvideo) - { - // make sure we start video with an i-frame - ResetVideoStreams(); - } - } - else - { - m_program = 0; - m_checkvideo = true; - skipCreateStreams = true; - } - - // reset any timeout - m_timeout.SetInfinite(); - - // if format can be nonblocking, let's use that - m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK; - - // print some extra information - av_dump_format(m_pFormatContext, 0, strFile.c_str(), 0); - - UpdateCurrentPTS(); - - // in case of mpegts and we have not seen pat/pmt, defer creation of streams - if (!skipCreateStreams || m_pFormatContext->nb_programs > 0) - CreateStreams(); - - // allow IsProgramChange to return true - if (skipCreateStreams && GetNrOfStreams() == 0) - m_program = 0; - - return true; -} - -void CDVDDemuxFFmpeg::Dispose() -{ - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - - if (m_pFormatContext) - { - if (m_ioContext && m_pFormatContext->pb && m_pFormatContext->pb != m_ioContext) - { - CLog::Log(LOGWARNING, "CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak"); - m_ioContext = m_pFormatContext->pb; - } - avformat_close_input(&m_pFormatContext); - } - - if(m_ioContext) - { - av_free(m_ioContext->buffer); - av_free(m_ioContext); - } - - m_ioContext = NULL; - m_pFormatContext = NULL; - m_speed = DVD_PLAYSPEED_NORMAL; - - DisposeStreams(); - - m_pInput = NULL; -} - -void CDVDDemuxFFmpeg::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream, m_streaminfo); -} - -void CDVDDemuxFFmpeg::Flush() -{ - // naughty usage of an internal ffmpeg function - if (m_pFormatContext) - av_read_frame_flush(m_pFormatContext); - - m_currentPts = DVD_NOPTS_VALUE; - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); -} - -void CDVDDemuxFFmpeg::Abort() -{ - m_timeout.SetExpired(); -} - -void CDVDDemuxFFmpeg::SetSpeed(int iSpeed) -{ - if(!m_pFormatContext) - return; - - if(m_speed != DVD_PLAYSPEED_PAUSE && iSpeed == DVD_PLAYSPEED_PAUSE) - { - m_pInput->Pause(m_currentPts); - av_read_pause(m_pFormatContext); - } - else if(m_speed == DVD_PLAYSPEED_PAUSE && iSpeed != DVD_PLAYSPEED_PAUSE) - { - m_pInput->Pause(m_currentPts); - av_read_play(m_pFormatContext); - } - m_speed = iSpeed; - - AVDiscard discard = AVDISCARD_NONE; - if(m_speed > 4*DVD_PLAYSPEED_NORMAL) - discard = AVDISCARD_NONKEY; - else if(m_speed > 2*DVD_PLAYSPEED_NORMAL) - discard = AVDISCARD_BIDIR; - else if(m_speed < DVD_PLAYSPEED_PAUSE) - discard = AVDISCARD_NONKEY; - - - for(unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - { - if(m_pFormatContext->streams[i]) - { - if(m_pFormatContext->streams[i]->discard != AVDISCARD_ALL) - m_pFormatContext->streams[i]->discard = discard; - } - } -} - -AVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromURL(const CURL &url) -{ - - AVDictionary *options = NULL; - - if (url.IsProtocol("http") || url.IsProtocol("https")) - { - std::map protocolOptions; - url.GetProtocolOptions(protocolOptions); - std::string headers; - bool hasUserAgent = false; - for(std::map::const_iterator it = protocolOptions.begin(); it != protocolOptions.end(); ++it) - { - std::string name = it->first; StringUtils::ToLower(name); - const std::string &value = it->second; - - if (name == "seekable") - av_dict_set(&options, "seekable", value.c_str(), 0); - else if (name == "user-agent") - { - av_dict_set(&options, "user-agent", value.c_str(), 0); - hasUserAgent = true; - } - else if (name != "auth" && name != "encoding") - // all other protocol options can be added as http header. - headers.append(it->first).append(": ").append(value).append("\r\n"); - } - if (!hasUserAgent) - // set default xbmc user-agent. - av_dict_set(&options, "user-agent", g_advancedSettings.m_userAgent.c_str(), 0); - - if (!headers.empty()) - av_dict_set(&options, "headers", headers.c_str(), 0); - - std::string cookies; - if (XFILE::CCurlFile::GetCookies(url, cookies)) - av_dict_set(&options, "cookies", cookies.c_str(), 0); - - } - return options; -} - -double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num) -{ - if (pts == (int64_t)AV_NOPTS_VALUE) - return DVD_NOPTS_VALUE; - - // do calculations in floats as they can easily overflow otherwise - // we don't care for having a completly exact timestamp anyway - double timestamp = (double)pts * num / den; - double starttime = 0.0f; - - // for dvd's we need the original time - if(CDVDInputStream::IMenus* menu = dynamic_cast(m_pInput)) - starttime = menu->GetTimeStampCorrection() / DVD_TIME_BASE; - else if (m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE) - starttime = (double)m_pFormatContext->start_time / AV_TIME_BASE; - - if(timestamp > starttime) - timestamp -= starttime; - // allow for largest possible difference in pts and dts for a single packet - else if( timestamp + 0.5f > starttime ) - timestamp = 0; - - return timestamp*DVD_TIME_BASE; -} - -DemuxPacket* CDVDDemuxFFmpeg::Read() -{ - DemuxPacket* pPacket = NULL; - // on some cases where the received packet is invalid we will need to return an empty packet (0 length) otherwise the main loop (in CDVDPlayer) - // would consider this the end of stream and stop. - bool bReturnEmpty = false; - { CSingleLock lock(m_critSection); // open lock scope - if (m_pFormatContext) - { - // assume we are not eof - if(m_pFormatContext->pb) - m_pFormatContext->pb->eof_reached = 0; - - // check for saved packet after a program change - if (m_pkt.result < 0) - { - // keep track if ffmpeg doesn't always set these - m_pkt.pkt.size = 0; - m_pkt.pkt.data = NULL; - - // timeout reads after 100ms - m_timeout.Set(20000); - m_pkt.result = av_read_frame(m_pFormatContext, &m_pkt.pkt); - m_timeout.SetInfinite(); - } - - if (m_pkt.result == AVERROR(EINTR) || m_pkt.result == AVERROR(EAGAIN)) - { - // timeout, probably no real error, return empty packet - bReturnEmpty = true; - } - else if (m_pkt.result < 0) - { - Flush(); - } - else if (IsProgramChange()) - { - // update streams - CreateStreams(m_program); - - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0); - pPacket->iStreamId = DMX_SPECIALID_STREAMCHANGE; - - return pPacket; - } - // check size and stream index for being in a valid range - else if (m_pkt.pkt.size < 0 || - m_pkt.pkt.stream_index < 0 || - m_pkt.pkt.stream_index >= (int)m_pFormatContext->nb_streams) - { - // XXX, in some cases ffmpeg returns a negative packet size - if(m_pFormatContext->pb && !m_pFormatContext->pb->eof_reached) - { - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() no valid packet"); - bReturnEmpty = true; - Flush(); - } - else - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() returned invalid packet and eof reached"); - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - } - else - { - ParsePacket(&m_pkt.pkt); - - AVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index]; - - if (IsVideoReady()) - { - if (m_program != UINT_MAX) - { - /* check so packet belongs to selected program */ - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { - if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i]) - { - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); - break; - } - } - - if (!pPacket) - bReturnEmpty = true; - } - else - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); - } - else - bReturnEmpty = true; - - if (pPacket) - { - // lavf sometimes bugs out and gives 0 dts/pts instead of no dts/pts - // since this could only happens on initial frame under normal - // circomstances, let's assume it is wrong all the time - if(m_pkt.pkt.dts == 0) - m_pkt.pkt.dts = AV_NOPTS_VALUE; - if(m_pkt.pkt.pts == 0) - m_pkt.pkt.pts = AV_NOPTS_VALUE; - - if(m_bMatroska && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { // matroska can store different timestamps - // for different formats, for native stored - // stuff it is pts, but for ms compatibility - // tracks, it is really dts. sadly ffmpeg - // sets these two timestamps equal all the - // time, so we select it here instead - if(stream->codec->codec_tag == 0) - m_pkt.pkt.dts = AV_NOPTS_VALUE; - else - m_pkt.pkt.pts = AV_NOPTS_VALUE; - } - - // we need to get duration slightly different for matroska embedded text subtitels - if(m_bMatroska && stream->codec && stream->codec->codec_id == AV_CODEC_ID_TEXT && m_pkt.pkt.convergence_duration != 0) - m_pkt.pkt.duration = m_pkt.pkt.convergence_duration; - - if(m_bAVI && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - // AVI's always have borked pts, specially if m_pFormatContext->flags includes - // AVFMT_FLAG_GENPTS so always use dts - m_pkt.pkt.pts = AV_NOPTS_VALUE; - } - - // copy contents into our own packet - pPacket->iSize = m_pkt.pkt.size; - - // maybe we can avoid a memcpy here by detecting where pkt.destruct is pointing too? - if (m_pkt.pkt.data) - memcpy(pPacket->pData, m_pkt.pkt.data, pPacket->iSize); - - pPacket->pts = ConvertTimestamp(m_pkt.pkt.pts, stream->time_base.den, stream->time_base.num); - pPacket->dts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num); - pPacket->duration = DVD_SEC_TO_TIME((double)m_pkt.pkt.duration * stream->time_base.num / stream->time_base.den); - - // used to guess streamlength - if (pPacket->dts != DVD_NOPTS_VALUE && (pPacket->dts > m_currentPts || m_currentPts == DVD_NOPTS_VALUE)) - m_currentPts = pPacket->dts; - - - // check if stream has passed full duration, needed for live streams - bool bAllowDurationExt = (stream->codec && (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO || stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)); - if(bAllowDurationExt && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE) - { - int64_t duration; - duration = m_pkt.pkt.dts; - if(stream->start_time != (int64_t)AV_NOPTS_VALUE) - duration -= stream->start_time; - - if(duration > stream->duration) - { - stream->duration = duration; - duration = av_rescale_rnd(stream->duration, (int64_t)stream->time_base.num * AV_TIME_BASE, stream->time_base.den, AV_ROUND_NEAR_INF); - if ((m_pFormatContext->duration == (int64_t)AV_NOPTS_VALUE) - || (m_pFormatContext->duration != (int64_t)AV_NOPTS_VALUE && duration > m_pFormatContext->duration)) - m_pFormatContext->duration = duration; - } - } - - // store internal id until we know the continuous id presented to player - // the stream might not have been created yet - pPacket->iStreamId = m_pkt.pkt.stream_index; - } - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - } - } - } // end of lock scope - if (bReturnEmpty && !pPacket) - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0); - - if (!pPacket) return NULL; - - // check streams, can we make this a bit more simple? - if (pPacket && pPacket->iStreamId >= 0) - { - CDemuxStream *stream = GetStreamInternal(pPacket->iStreamId); - if (!stream || - stream->pPrivate != m_pFormatContext->streams[pPacket->iStreamId] || - stream->codec != m_pFormatContext->streams[pPacket->iStreamId]->codec->codec_id) - { - // content has changed, or stream did not yet exist - stream = AddStream(pPacket->iStreamId); - } - // we already check for a valid m_streams[pPacket->iStreamId] above - else if (stream->type == STREAM_AUDIO) - { - if (((CDemuxStreamAudio*)stream)->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codec->channels || - ((CDemuxStreamAudio*)stream)->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codec->sample_rate) - { - // content has changed - stream = AddStream(pPacket->iStreamId); - } - } - else if (stream->type == STREAM_VIDEO) - { - if (((CDemuxStreamVideo*)stream)->iWidth != m_pFormatContext->streams[pPacket->iStreamId]->codec->width || - ((CDemuxStreamVideo*)stream)->iHeight != m_pFormatContext->streams[pPacket->iStreamId]->codec->height) - { - // content has changed - stream = AddStream(pPacket->iStreamId); - } - } - if (!stream) - { - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::AddStream - internal error, stream is null"); - CDVDDemuxUtils::FreeDemuxPacket(pPacket); - return NULL; - } - // set continuous stream id for player - pPacket->iStreamId = stream->iId; - } - return pPacket; -} - -bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) -{ - if (!m_pInput) - return false; - - if(time < 0) - time = 0; - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - - CDVDInputStream::ISeekTime* ist = dynamic_cast(m_pInput); - if (ist) - { - if (!ist->SeekTime(time)) - return false; - - if(startpts) - *startpts = DVD_NOPTS_VALUE; - - Flush(); - - // also empty the internal ffmpeg buffer - m_ioContext->buf_ptr = m_ioContext->buf_end; - - return true; - } - - if(!m_pInput->Seek(0, SEEK_POSSIBLE) - && !m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) - { - CLog::Log(LOGDEBUG, "%s - input stream reports it is not seekable", __FUNCTION__); - return false; - } - - int64_t seek_pts = (int64_t)time * (AV_TIME_BASE / 1000); - bool ismp3 = m_pFormatContext->iformat && (strcmp(m_pFormatContext->iformat->name, "mp3") == 0); - if (m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE && !ismp3) - seek_pts += m_pFormatContext->start_time; - - int ret; - { - CSingleLock lock(m_critSection); - ret = av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0); - - // demuxer will return failure, if you seek behind eof - if (ret < 0 && m_pFormatContext->duration && seek_pts >= (m_pFormatContext->duration + m_pFormatContext->start_time)) - ret = 0; - else if (ret < 0 && m_pInput->IsEOF()) - ret = 0; - - if(ret >= 0) - UpdateCurrentPTS(); - } - - if(m_currentPts == DVD_NOPTS_VALUE) - CLog::Log(LOGDEBUG, "%s - unknown position after seek", __FUNCTION__); - else - CLog::Log(LOGDEBUG, "%s - seek ended up on time %d", __FUNCTION__, (int)(m_currentPts / DVD_TIME_BASE * 1000)); - - // in this case the start time is requested time - if(startpts) - *startpts = DVD_MSEC_TO_TIME(time); - - return (ret >= 0); -} - -bool CDVDDemuxFFmpeg::SeekByte(int64_t pos) -{ - CSingleLock lock(m_critSection); - int ret = av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE); - - if(ret >= 0) - UpdateCurrentPTS(); - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - - return (ret >= 0); -} - -void CDVDDemuxFFmpeg::UpdateCurrentPTS() -{ - m_currentPts = DVD_NOPTS_VALUE; - - int idx = av_find_default_stream_index(m_pFormatContext); - if (idx >= 0) - { - AVStream *stream = m_pFormatContext->streams[idx]; - if(stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE) - { - double ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num); - if(m_currentPts == DVD_NOPTS_VALUE || m_currentPts > ts ) - m_currentPts = ts; - } - } -} - -int CDVDDemuxFFmpeg::GetStreamLength() -{ - if (!m_pFormatContext) - return 0; - - if (m_pFormatContext->duration < 0) - return 0; - - return (int)(m_pFormatContext->duration / (AV_TIME_BASE / 1000)); -} - -/** - * @brief Finds stream based on demuxer index - */ -CDemuxStream* CDVDDemuxFFmpeg::GetStream(int iStreamId) -{ - if(iStreamId >= 0 && (size_t)iStreamId < m_stream_index.size()) - return m_stream_index[iStreamId]->second; - else - return NULL; -} - -/** - * @brief Finds stream based on ffmpeg index - */ -CDemuxStream* CDVDDemuxFFmpeg::GetStreamInternal(int iId) -{ - std::map::iterator it = m_streams.find(iId); - if (it == m_streams.end()) - return NULL; - else - return it->second; -} - -int CDVDDemuxFFmpeg::GetNrOfStreams() -{ - return m_stream_index.size(); -} - -static double SelectAspect(AVStream* st, bool* forced) -{ - *forced = false; - /* if stream aspect is 1:1 or 0:0 use codec aspect */ - if((st->sample_aspect_ratio.den == 1 || st->sample_aspect_ratio.den == 0) - && (st->sample_aspect_ratio.num == 1 || st->sample_aspect_ratio.num == 0) - && st->codec->sample_aspect_ratio.num != 0) - return av_q2d(st->codec->sample_aspect_ratio); - - *forced = true; - if(st->sample_aspect_ratio.num != 0) - return av_q2d(st->sample_aspect_ratio); - - return 0.0; -} - -void CDVDDemuxFFmpeg::CreateStreams(unsigned int program) -{ - DisposeStreams(); - - // add the ffmpeg streams to our own stream map - if (m_pFormatContext->nb_programs) - { - // check if desired program is available - if (program < m_pFormatContext->nb_programs && m_pFormatContext->programs[program]->nb_stream_indexes > 0) - { - m_program = program; - } - else - m_program = UINT_MAX; - - // look for first non empty stream and discard nonselected programs - for (unsigned int i = 0; i < m_pFormatContext->nb_programs; i++) - { - if(m_program == UINT_MAX && m_pFormatContext->programs[i]->nb_stream_indexes > 0) - { - m_program = i; - } - - if(i != m_program) - m_pFormatContext->programs[i]->discard = AVDISCARD_ALL; - } - if(m_program != UINT_MAX) - { - // add streams from selected program - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - AddStream(m_pFormatContext->programs[m_program]->stream_index[i]); - } - } - else - m_program = UINT_MAX; - - // if there were no programs or they were all empty, add all streams - if (m_program == UINT_MAX) - { - for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - AddStream(i); - } -} - -void CDVDDemuxFFmpeg::DisposeStreams() -{ - std::map::iterator it; - for(it = m_streams.begin(); it != m_streams.end(); ++it) - delete it->second; - m_streams.clear(); - m_stream_index.clear(); -} - -CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) -{ - AVStream* pStream = m_pFormatContext->streams[iId]; - if (pStream) - { - CDemuxStream* stream = NULL; - - switch (pStream->codec->codec_type) - { - case AVMEDIA_TYPE_AUDIO: - { - CDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(this, pStream); - stream = st; - st->iChannels = pStream->codec->channels; - st->iSampleRate = pStream->codec->sample_rate; - st->iBlockAlign = pStream->codec->block_align; - st->iBitRate = pStream->codec->bit_rate; - st->iBitsPerSample = pStream->codec->bits_per_raw_sample; - if (st->iBitsPerSample == 0) - st->iBitsPerSample = pStream->codec->bits_per_coded_sample; - - if(av_dict_get(pStream->metadata, "title", NULL, 0)) - st->m_description = av_dict_get(pStream->metadata, "title", NULL, 0)->value; - - break; - } - case AVMEDIA_TYPE_VIDEO: - { - CDemuxStreamVideoFFmpeg* st = new CDemuxStreamVideoFFmpeg(this, pStream); - stream = st; - if(strcmp(m_pFormatContext->iformat->name, "flv") == 0) - st->bVFR = true; - else - st->bVFR = false; - - // never trust pts in avi files with h264. - if (m_bAVI && pStream->codec->codec_id == AV_CODEC_ID_H264) - st->bPTSInvalid = true; - -#if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) - AVRational r_frame_rate = av_stream_get_r_frame_rate(pStream); -#else - AVRational r_frame_rate = pStream->r_frame_rate; -#endif - - //average fps is more accurate for mkv files - if (m_bMatroska && pStream->avg_frame_rate.den && pStream->avg_frame_rate.num) - { - st->iFpsRate = pStream->avg_frame_rate.num; - st->iFpsScale = pStream->avg_frame_rate.den; - } - else if(r_frame_rate.den && r_frame_rate.num) - { - st->iFpsRate = r_frame_rate.num; - st->iFpsScale = r_frame_rate.den; - } - else - { - st->iFpsRate = 0; - st->iFpsScale = 0; - } - - // added for aml hw decoder, mkv frame-rate can be wrong. - if (r_frame_rate.den && r_frame_rate.num) - { - st->irFpsRate = r_frame_rate.num; - st->irFpsScale = r_frame_rate.den; - } - else - { - st->irFpsRate = 0; - st->irFpsScale = 0; - } - - if (pStream->codec_info_nb_frames > 0 - && pStream->codec_info_nb_frames <= 2 - && m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) - { - CLog::Log(LOGDEBUG, "%s - fps may be unreliable since ffmpeg decoded only %d frame(s)", __FUNCTION__, pStream->codec_info_nb_frames); - st->iFpsRate = 0; - st->iFpsScale = 0; - } - - st->iWidth = pStream->codec->width; - st->iHeight = pStream->codec->height; - st->fAspect = SelectAspect(pStream, &st->bForcedAspect) * pStream->codec->width / pStream->codec->height; - st->iOrientation = 0; - st->iBitsPerPixel = pStream->codec->bits_per_coded_sample; - - AVDictionaryEntry *rtag = av_dict_get(pStream->metadata, "rotate", NULL, 0); - if (rtag) - st->iOrientation = atoi(rtag->value); - - // detect stereoscopic mode - std::string stereoMode = GetStereoModeFromMetadata(pStream->metadata); - // check for metadata in file if detection in stream failed - if (stereoMode.empty()) - stereoMode = GetStereoModeFromMetadata(m_pFormatContext->metadata); - if (!stereoMode.empty()) - st->stereo_mode = stereoMode; - - - if ( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) ) - { - if (pStream->codec->codec_id == AV_CODEC_ID_PROBE) - { - // fix MPEG-1/MPEG-2 video stream probe returning AV_CODEC_ID_PROBE for still frames. - // ffmpeg issue 1871, regression from ffmpeg r22831. - if ((pStream->id & 0xF0) == 0xE0) - { - pStream->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO; - pStream->codec->codec_tag = MKTAG('M','P','2','V'); - CLog::Log(LOGERROR, "%s - AV_CODEC_ID_PROBE detected, forcing AV_CODEC_ID_MPEG2VIDEO", __FUNCTION__); - } - } - } - break; - } - case AVMEDIA_TYPE_DATA: - { - stream = new CDemuxStream(); - stream->type = STREAM_DATA; - break; - } - case AVMEDIA_TYPE_SUBTITLE: - { - if (pStream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && CSettings::Get().GetBool("videoplayer.teletextenabled")) - { - CDemuxStreamTeletext* st = new CDemuxStreamTeletext(); - stream = st; - stream->type = STREAM_TELETEXT; - break; - } - else - { - CDemuxStreamSubtitleFFmpeg* st = new CDemuxStreamSubtitleFFmpeg(this, pStream); - stream = st; - - if(av_dict_get(pStream->metadata, "title", NULL, 0)) - st->m_description = av_dict_get(pStream->metadata, "title", NULL, 0)->value; - - break; - } - } - case AVMEDIA_TYPE_ATTACHMENT: - { //mkv attachments. Only bothering with fonts for now. - if(pStream->codec->codec_id == AV_CODEC_ID_TTF - || pStream->codec->codec_id == AV_CODEC_ID_OTF - ) - { - std::string fileName = "special://temp/fonts/"; - XFILE::CDirectory::Create(fileName); - AVDictionaryEntry *nameTag = av_dict_get(pStream->metadata, "filename", NULL, 0); - if (!nameTag) - { - CLog::Log(LOGERROR, "%s: TTF attachment has no name", __FUNCTION__); - } - else - { - fileName += nameTag->value; - XFILE::CFile file; - if(pStream->codec->extradata && file.OpenForWrite(fileName)) - { - 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()); - } - } - } - } - stream = new CDemuxStream(); - stream->type = STREAM_NONE; - break; - } - default: - { - stream = new CDemuxStream(); - stream->type = STREAM_NONE; - break; - } - } - - // set ffmpeg type - stream->orig_type = pStream->codec->codec_type; - - // generic stuff - if (pStream->duration != (int64_t)AV_NOPTS_VALUE) - stream->iDuration = (int)((pStream->duration / AV_TIME_BASE) & 0xFFFFFFFF); - - stream->codec = pStream->codec->codec_id; - stream->codec_fourcc = pStream->codec->codec_tag; - stream->profile = pStream->codec->profile; - stream->level = pStream->codec->level; - - stream->source = STREAM_SOURCE_DEMUX; - stream->pPrivate = pStream; - stream->flags = (CDemuxStream::EFlags)pStream->disposition; - - AVDictionaryEntry *langTag = av_dict_get(pStream->metadata, "language", NULL, 0); - if (langTag) - strncpy(stream->language, langTag->value, 3); - - if( pStream->codec->extradata && pStream->codec->extradata_size > 0 ) - { - stream->ExtraSize = pStream->codec->extradata_size; - stream->ExtraData = new uint8_t[pStream->codec->extradata_size]; - memcpy(stream->ExtraData, pStream->codec->extradata, pStream->codec->extradata_size); - } - -#ifdef HAVE_LIBBLURAY - if( m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) - static_cast(m_pInput)->GetStreamInfo(pStream->id, stream->language); -#endif - if( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) ) - { - // this stuff is really only valid for dvd's. - // this is so that the physicalid matches the - // id's reported from libdvdnav - switch(stream->codec) - { - case AV_CODEC_ID_AC3: - stream->iPhysicalId = pStream->id - 128; - break; - case AV_CODEC_ID_DTS: - stream->iPhysicalId = pStream->id - 136; - break; - case AV_CODEC_ID_MP2: - stream->iPhysicalId = pStream->id - 448; - break; - case AV_CODEC_ID_PCM_S16BE: - stream->iPhysicalId = pStream->id - 160; - break; - case AV_CODEC_ID_DVD_SUBTITLE: - stream->iPhysicalId = pStream->id - 0x20; - break; - default: - stream->iPhysicalId = pStream->id & 0x1f; - break; - } - } - else - stream->iPhysicalId = pStream->id; - - AddStream(iId, stream); - return stream; - } - else - return NULL; -} - -/** - * @brief Adds or updates a demux stream based in ffmpeg id - */ -void CDVDDemuxFFmpeg::AddStream(int iId, CDemuxStream* stream) -{ - std::pair::iterator, bool> res; - - res = m_streams.insert(std::make_pair(iId, stream)); - if(res.second) - { - /* was new stream */ - stream->iId = m_stream_index.size(); - m_stream_index.push_back(res.first); - } - else - { - /* replace old stream, keeping old index */ - stream->iId = res.first->second->iId; - - delete res.first->second; - res.first->second = stream; - } - if(g_advancedSettings.m_logLevel > LOG_LEVEL_NORMAL) - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::AddStream(%d, ...) -> %d", iId, stream->iId); -} - - -std::string CDVDDemuxFFmpeg::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -int CDVDDemuxFFmpeg::GetChapterCount() -{ - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - return ich->GetChapterCount(); - - if(m_pFormatContext == NULL) - return 0; - - return m_pFormatContext->nb_chapters; -} - -int CDVDDemuxFFmpeg::GetChapter() -{ - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - return ich->GetChapter(); - - if(m_pFormatContext == NULL - || m_currentPts == DVD_NOPTS_VALUE) - return 0; - - for(unsigned i = 0; i < m_pFormatContext->nb_chapters; i++) - { - AVChapter *chapter = m_pFormatContext->chapters[i]; - if(m_currentPts >= ConvertTimestamp(chapter->start, chapter->time_base.den, chapter->time_base.num) - && m_currentPts < ConvertTimestamp(chapter->end, chapter->time_base.den, chapter->time_base.num)) - return i + 1; - } - - return 0; -} - -void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName, int chapterIdx) -{ - if (chapterIdx <= 0 || chapterIdx > GetChapterCount()) - chapterIdx = GetChapter(); - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - ich->GetChapterName(strChapterName, chapterIdx); - else - { - if(chapterIdx <= 0) - return; - - AVDictionaryEntry *titleTag = av_dict_get(m_pFormatContext->chapters[chapterIdx-1]->metadata, - "title", NULL, 0); - if (titleTag) - strChapterName = titleTag->value; - } -} - -int64_t CDVDDemuxFFmpeg::GetChapterPos(int chapterIdx) -{ - if (chapterIdx <= 0 || chapterIdx > GetChapterCount()) - chapterIdx = GetChapter(); - if(chapterIdx <= 0) - return 0; - - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - return ich->GetChapterPos(chapterIdx); - - return m_pFormatContext->chapters[chapterIdx-1]->start*av_q2d(m_pFormatContext->chapters[chapterIdx-1]->time_base); -} - -bool CDVDDemuxFFmpeg::SeekChapter(int chapter, double* startpts) -{ - if(chapter < 1) - chapter = 1; - - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - { - CLog::Log(LOGDEBUG, "%s - chapter seeking using input stream", __FUNCTION__); - if(!ich->SeekChapter(chapter)) - return false; - - if(startpts) - { - *startpts = DVD_SEC_TO_TIME(ich->GetChapterPos(chapter)); - } - - Flush(); - return true; - } - - if(m_pFormatContext == NULL) - return false; - - if(chapter < 1 || chapter > (int)m_pFormatContext->nb_chapters) - return false; - - AVChapter *ch = m_pFormatContext->chapters[chapter-1]; - double dts = ConvertTimestamp(ch->start, ch->time_base.den, ch->time_base.num); - return SeekTime(DVD_TIME_TO_MSEC(dts), true, startpts); -} - -void CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId, std::string &strName) -{ - CDemuxStream *stream = GetStream(iStreamId); - if (stream) - { - unsigned int in = stream->codec_fourcc; - // FourCC codes are only valid on video streams, audio codecs in AVI/WAV - // are 2 bytes and audio codecs in transport streams have subtle variation - // e.g AC-3 instead of ac3 - if (stream->type == STREAM_VIDEO && in != 0) - { - char fourcc[5]; -#if defined(__powerpc__) - fourcc[0] = in & 0xff; - fourcc[1] = (in >> 8) & 0xff; - fourcc[2] = (in >> 16) & 0xff; - fourcc[3] = (in >> 24) & 0xff; -#else - memcpy(fourcc, &in, 4); -#endif - fourcc[4] = 0; - // fourccs have to be 4 characters - if (strlen(fourcc) == 4) - { - strName = fourcc; - StringUtils::ToLower(strName); - return; - } - } - -#ifdef FF_PROFILE_DTS_HD_MA - /* use profile to determine the DTS type */ - if (stream->codec == AV_CODEC_ID_DTS) - { - if (stream->profile == FF_PROFILE_DTS_HD_MA) - strName = "dtshd_ma"; - else if (stream->profile == FF_PROFILE_DTS_HD_HRA) - strName = "dtshd_hra"; - else - strName = "dca"; - return; - } -#endif - - AVCodec *codec = avcodec_find_decoder(stream->codec); - if (codec) - strName = codec->name; - } -} - -bool CDVDDemuxFFmpeg::IsProgramChange() -{ - if (m_program == UINT_MAX) - return false; - - if (m_program == 0 && !m_pFormatContext->nb_programs) - return false; - - if(m_pFormatContext->programs[m_program]->nb_stream_indexes != m_streams.size()) - return true; - - if (m_program >= m_pFormatContext->nb_programs) - return true; - - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { - int idx = m_pFormatContext->programs[m_program]->stream_index[i]; - CDemuxStream *stream = GetStreamInternal(idx); - if(!stream) - return true; - if(m_pFormatContext->streams[idx]->codec->codec_type != stream->orig_type) - return true; - } - return false; -} - -std::string CDVDDemuxFFmpeg::GetStereoModeFromMetadata(AVDictionary *pMetadata) -{ - std::string stereoMode; - AVDictionaryEntry *tag = NULL; - - // matroska - tag = av_dict_get(pMetadata, "stereo_mode", NULL, 0); - if (tag && tag->value) - stereoMode = tag->value; - - // asf / wmv - if (stereoMode.empty()) - { - tag = av_dict_get(pMetadata, "Stereoscopic", NULL, 0); - if (tag && tag->value) - { - tag = av_dict_get(pMetadata, "StereoscopicLayout", NULL, 0); - if (tag && tag->value) - stereoMode = ConvertCodecToInternalStereoMode(tag->value, WmvToInternalStereoModeMap); - } - } - - return stereoMode; -} - -std::string CDVDDemuxFFmpeg::ConvertCodecToInternalStereoMode(const std::string &mode, const StereoModeConversionMap *conversionMap) -{ - size_t i = 0; - while (conversionMap[i].name) - { - if (mode == conversionMap[i].name) - return conversionMap[i].mode; - i++; - } - return ""; -} - -void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) -{ - AVStream *st = m_pFormatContext->streams[pkt->stream_index]; - CDemuxStream *stream = GetStreamInternal(pkt->stream_index); - - // if the stream is new, tell ffmpeg to parse the stream - if (!stream && !st->parser) - { - st->need_parsing = AVSTREAM_PARSE_FULL; - } - - // split extradata - if(st->parser && st->parser->parser->split && !st->codec->extradata) - { - int i = st->parser->parser->split(st->codec, pkt->data, pkt->size); - if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) - { - // Found extradata, fill it in. This will cause - // a new stream to be created and used. - st->codec->extradata_size = i; - st->codec->extradata = (uint8_t*)av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (st->codec->extradata) - { - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::Read() fetching extradata, extradata_size(%d)", st->codec->extradata_size); - memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size); - memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE); - } - else - { - st->codec->extradata_size = 0; - } - } - } - - // for video we need a decoder to get desired information into codec context - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec->extradata && - (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) - { - // open a decoder, it will be cleared down by ffmpeg on closing the stream - if (!st->codec->codec) - { - const AVCodec* codec; - AVDictionary *thread_opt = NULL; - codec = avcodec_find_decoder(st->codec->codec_id); - // Force thread count to 1 since the h264 decoder will not extract - // SPS and PPS to extradata during multi-threaded decoding - av_dict_set(&thread_opt, "threads", "1", 0); - int res = avcodec_open2(st->codec, codec, &thread_opt); - if(res < 0) - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::ParsePacket() unable to open codec %d", res); - av_dict_free(&thread_opt); - } - - // We don't need to actually decode here - // we just want to transport SPS data into codec context - st->codec->skip_idct = AVDISCARD_ALL; - // extradata is not decoded if skip_frame >= AVDISCARD_NONREF -// st->codec->skip_frame = AVDISCARD_ALL; - st->codec->skip_loop_filter = AVDISCARD_ALL; - - // We are looking for an IDR frame - AVFrame picture; - memset(&picture, 0, sizeof(AVFrame)); - picture.pts = picture.pkt_dts = picture.pkt_pts = picture.best_effort_timestamp = AV_NOPTS_VALUE; - picture.pkt_pos = -1; - picture.key_frame = 1; - picture.format = -1; - - int got_picture = 0; - avcodec_decode_video2(st->codec, &picture, &got_picture, pkt); - } -} - -bool CDVDDemuxFFmpeg::IsVideoReady() -{ - AVStream *st; - bool hasVideo = false; - - if(!m_checkvideo) - return true; - - if (m_program == 0 && !m_pFormatContext->nb_programs) - return false; - - if(m_program != UINT_MAX) - { - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { - int idx = m_pFormatContext->programs[m_program]->stream_index[i]; - st = m_pFormatContext->streams[idx]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) - return true; - hasVideo = true; - } - } - } - else - { - for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - { - st = m_pFormatContext->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) - return true; - hasVideo = true; - } - } - } - return !hasVideo; -} - -void CDVDDemuxFFmpeg::ResetVideoStreams() -{ - AVStream *st; - for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - { - st = m_pFormatContext->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - if (st->codec->extradata) - av_free(st->codec->extradata); - st->codec->extradata = NULL; - st->codec->width = 0; - } - } -} - -void CDVDDemuxFFmpeg::GetL16Parameters(int &channels, int &samplerate) -{ - std::string content; - if (XFILE::CCurlFile::GetContentType(m_pInput->GetURL(), content)) - { - StringUtils::ToLower(content); - const size_t len = content.length(); - size_t pos = content.find(';'); - while (pos < len) - { - // move to the next non-whitespace character - pos = content.find_first_not_of(" \t", pos + 1); - - if (pos != std::string::npos) - { - if (content.compare(pos, 9, "channels=", 9) == 0) - { - pos += 9; // move position to char after 'channels=' - size_t len = content.find(';', pos); - if (len != std::string::npos) - len -= pos; - std::string no_channels(content, pos, len); - // as we don't support any charset with ';' in name - StringUtils::Trim(no_channels, " \t"); - if (!no_channels.empty()) - { - int val = strtol(no_channels.c_str(), NULL, 0); - if (val > 0) - channels = val; - else - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::%s - no parameter for channels", __FUNCTION__); - } - } - else if (content.compare(pos, 5, "rate=", 5) == 0) - { - pos += 5; // move position to char after 'rate=' - size_t len = content.find(';', pos); - if (len != std::string::npos) - len -= pos; - std::string rate(content, pos, len); - // as we don't support any charset with ';' in name - StringUtils::Trim(rate, " \t"); - if (!rate.empty()) - { - int val = strtol(rate.c_str(), NULL, 0); - if (val > 0) - samplerate = val; - else - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::%s - no parameter for samplerate", __FUNCTION__); - } - } - pos = content.find(';', pos); // find next parameter - } - } - } -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h deleted file mode 100644 index d180e40..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +++ /dev/null @@ -1,172 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DVDDemux.h" -#include "threads/CriticalSection.h" -#include "threads/SystemClock.h" -#include -#include - -extern "C" { -#include "libavformat/avformat.h" -} - -class CDVDDemuxFFmpeg; -class CURL; - -class CDemuxStreamVideoFFmpeg - : public CDemuxStreamVideo -{ - CDVDDemuxFFmpeg *m_parent; - AVStream* m_stream; -public: - CDemuxStreamVideoFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream) - : m_parent(parent) - , m_stream(stream) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - - -class CDemuxStreamAudioFFmpeg - : public CDemuxStreamAudio -{ - CDVDDemuxFFmpeg *m_parent; - AVStream* m_stream; -public: - CDemuxStreamAudioFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream) - : m_parent(parent) - , m_stream(stream) - {} - std::string m_description; - - virtual void GetStreamInfo(std::string& strInfo); - virtual void GetStreamName(std::string& strInfo); -}; - -class CDemuxStreamSubtitleFFmpeg - : public CDemuxStreamSubtitle -{ - CDVDDemuxFFmpeg *m_parent; - AVStream* m_stream; -public: - CDemuxStreamSubtitleFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream) - : m_parent(parent) - , m_stream(stream) - {} - std::string m_description; - - virtual void GetStreamInfo(std::string& strInfo); - virtual void GetStreamName(std::string& strInfo); - -}; - -#define FFMPEG_FILE_BUFFER_SIZE 32768 // default reading size for ffmpeg -#define FFMPEG_DVDNAV_BUFFER_SIZE 2048 // for dvd's - -struct StereoModeConversionMap; - -class CDVDDemuxFFmpeg : public CDVDDemux -{ -public: - CDVDDemuxFFmpeg(); - virtual ~CDVDDemuxFFmpeg(); - - bool Open(CDVDInputStream* pInput, bool streaminfo = true, bool fileinfo = false); - void Dispose(); - void Reset(); - void Flush(); - void Abort(); - void SetSpeed(int iSpeed); - virtual std::string GetFileName(); - - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - bool SeekByte(int64_t pos); - int GetStreamLength(); - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - - bool SeekChapter(int chapter, double* startpts = NULL); - int GetChapterCount(); - int GetChapter(); - void GetChapterName(std::string& strChapterName, int chapterIdx=-1); - int64_t GetChapterPos(int chapterIdx=-1); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - - bool Aborted(); - - AVFormatContext* m_pFormatContext; - CDVDInputStream* m_pInput; - -protected: - friend class CDemuxStreamAudioFFmpeg; - friend class CDemuxStreamVideoFFmpeg; - friend class CDemuxStreamSubtitleFFmpeg; - - int ReadFrame(AVPacket *packet); - CDemuxStream* AddStream(int iId); - void AddStream(int iId, CDemuxStream* stream); - CDemuxStream* GetStreamInternal(int iStreamId); - void CreateStreams(unsigned int program = UINT_MAX); - void DisposeStreams(); - void ParsePacket(AVPacket *pkt); - bool IsVideoReady(); - void ResetVideoStreams(); - - AVDictionary *GetFFMpegOptionsFromURL(const CURL &url); - double ConvertTimestamp(int64_t pts, int den, int num); - void UpdateCurrentPTS(); - bool IsProgramChange(); - - std::string GetStereoModeFromMetadata(AVDictionary *pMetadata); - std::string ConvertCodecToInternalStereoMode(const std::string &mode, const StereoModeConversionMap *conversionMap); - - void GetL16Parameters(int &channels, int &samplerate); - - CCriticalSection m_critSection; - std::map m_streams; - std::vector::iterator> m_stream_index; - - AVIOContext* m_ioContext; - - double m_currentPts; // used for stream length estimation - bool m_bMatroska; - bool m_bAVI; - int m_speed; - unsigned m_program; - XbmcThreads::EndTime m_timeout; - - // Due to limitations of ffmpeg, we only can detect a program change - // with a packet. This struct saves the packet for the next read and - // signals STREAMCHANGE to player - struct - { - AVPacket pkt; // packet ffmpeg returned - int result; // result from av_read_packet - }m_pkt; - - bool m_streaminfo; - bool m_checkvideo; -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp deleted file mode 100644 index 3674416..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - - -#include "DVDCodecs/DVDCodecs.h" -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDInputStreams/DVDInputStreamHTSP.h" -#include "DVDDemuxHTSP.h" -#include "DVDDemuxUtils.h" -#include "DVDClock.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include - -extern "C" { -#include "lib/libhts/net.h" -#include "lib/libhts/htsmsg.h" -#include "lib/libhts/htsmsg_binary.h" -} - -using namespace std; -using namespace HTSP; - -class CDemuxStreamVideoHTSP - : public CDemuxStreamVideo -{ - CDVDDemuxHTSP *m_parent; - string m_codec; -public: - CDemuxStreamVideoHTSP(CDVDDemuxHTSP *parent, const string& codec) - : m_parent(parent) - , m_codec(codec) - {} - void GetStreamInfo(std::string& strInfo) - { - strInfo = StringUtils::Format("%s, delay: %u, drops: %ub %up %ui" - , m_codec.c_str() - , m_parent->m_QueueStatus.delay - , m_parent->m_QueueStatus.bdrops - , m_parent->m_QueueStatus.pdrops - , m_parent->m_QueueStatus.idrops); - } -}; - -class CDemuxStreamAudioHTSP - : public CDemuxStreamAudio -{ - CDVDDemuxHTSP *m_parent; - string m_codec; -public: - CDemuxStreamAudioHTSP(CDVDDemuxHTSP *parent, const string& codec) - : m_parent(parent) - , m_codec(codec) - - {} - void GetStreamInfo(string& strInfo) - { - strInfo = StringUtils::Format("%s", m_codec.c_str()); - } -}; - -CDVDDemuxHTSP::CDVDDemuxHTSP() - : CDVDDemux() - , m_Input(NULL) - , m_StatusCount(0) -{ -} - -CDVDDemuxHTSP::~CDVDDemuxHTSP() -{ - Dispose(); -} - -bool CDVDDemuxHTSP::Open(CDVDInputStream* input) -{ - Dispose(); - - if(!input->IsStreamType(DVDSTREAM_TYPE_HTSP)) - return false; - - m_Input = (CDVDInputStreamHTSP*)input; - m_StatusCount = 0; - - while(m_Streams.empty() && m_StatusCount == 0) - { - DemuxPacket* pkg = Read(); - if(!pkg) - return false; - CDVDDemuxUtils::FreeDemuxPacket(pkg); - } - - return true; -} - -void CDVDDemuxHTSP::Dispose() -{ -} - -void CDVDDemuxHTSP::Reset() -{ -} - - -void CDVDDemuxHTSP::Flush() -{ -} - -bool CDVDDemuxHTSP::ReadStream(uint8_t* buf, int len) -{ - while(len > 0) - { - int ret = m_Input->Read(buf, len); - if(ret <= 0) - return false; - len -= ret; - buf += ret; - } - return true; -} - -htsmsg_t* CDVDDemuxHTSP::ReadStream() -{ - if(m_Input->IsStreamType(DVDSTREAM_TYPE_HTSP)) - return ((CDVDInputStreamHTSP*)m_Input)->ReadStream(); - - uint32_t l; - if(!ReadStream((uint8_t*)&l, 4)) - return NULL; - - l = ntohl(l); - if(l == 0) - return htsmsg_create_map(); - - uint8_t* buf = (uint8_t*)malloc(l); - if(!buf) - return NULL; - - if(!ReadStream(buf, l)) - return NULL; - - return htsmsg_binary_deserialize(buf, l, buf); /* consumes 'buf' */ -} - -DemuxPacket* CDVDDemuxHTSP::Read() -{ - htsmsg_t * msg; - while((msg = ReadStream())) - { - const char* method = htsmsg_get_str(msg, "method"); - if(method == NULL) - break; - - if (strcmp("subscriptionStart", method) == 0) - SubscriptionStart(msg); - else if(strcmp("subscriptionStop", method) == 0) - SubscriptionStop (msg); - else if(strcmp("subscriptionStatus", method) == 0) - SubscriptionStatus(msg); - else if(strcmp("queueStatus" , method) == 0) - CHTSPSession::ParseQueueStatus(msg, m_QueueStatus); - else if(strcmp("muxpkt" , method) == 0) - { - uint32_t index, duration; - const void* bin; - size_t binlen; - int64_t ts; - - if(htsmsg_get_u32(msg, "stream" , &index) || - htsmsg_get_bin(msg, "payload", &bin, &binlen)) - break; - - DemuxPacket* pkt = CDVDDemuxUtils::AllocateDemuxPacket(binlen); - - memcpy(pkt->pData, bin, binlen); - pkt->iSize = binlen; - - if(!htsmsg_get_u32(msg, "duration", &duration)) - pkt->duration = (double)duration * DVD_TIME_BASE / 1000000; - - if(!htsmsg_get_s64(msg, "dts", &ts)) - pkt->dts = (double)ts * DVD_TIME_BASE / 1000000; - else - pkt->dts = DVD_NOPTS_VALUE; - - if(!htsmsg_get_s64(msg, "pts", &ts)) - pkt->pts = (double)ts * DVD_TIME_BASE / 1000000; - else - pkt->pts = DVD_NOPTS_VALUE; - - pkt->iStreamId = -1; - for(int i = 0; i < (int)m_Streams.size(); i++) - { - if(m_Streams[i]->iPhysicalId == (int)index) - { - pkt->iStreamId = i; - break; - } - } - - htsmsg_destroy(msg); - return pkt; - } - - break; - } - - if(msg) - { - htsmsg_destroy(msg); - return CDVDDemuxUtils::AllocateDemuxPacket(0); - } - return NULL; -} - -void CDVDDemuxHTSP::SubscriptionStart (htsmsg_t *m) -{ - htsmsg_t *streams; - htsmsg_t *info; - htsmsg_field_t *f; - - if((info = htsmsg_get_map(m, "sourceinfo"))) - { - HTSMSG_FOREACH(f, info) - { - if(f->hmf_type != HMF_STR) - continue; - CLog::Log(LOGDEBUG, "CDVDDemuxHTSP::SubscriptionStart - %s: %s", f->hmf_name, htsmsg_field_get_string(f)); - } - } - - if((streams = htsmsg_get_list(m, "streams")) == NULL) - { - CLog::Log(LOGERROR, "CDVDDemuxHTSP::SubscriptionStart - malformed message"); - return; - } - - for(int i = 0; i < (int)m_Streams.size(); i++) - delete m_Streams[i]; - m_Streams.clear(); - - HTSMSG_FOREACH(f, streams) - { - uint32_t index; - const char* type; - const char* lang; - htsmsg_t* sub; - - if(f->hmf_type != HMF_MAP) - continue; - sub = &f->hmf_msg; - - if((type = htsmsg_get_str(sub, "type")) == NULL) - continue; - - if(htsmsg_get_u32(sub, "index", &index)) - continue; - - union { - CDemuxStream* g; - CDemuxStreamAudio* a; - CDemuxStreamVideo* v; - CDemuxStreamSubtitle* s; - CDemuxStreamTeletext* t; - } st; - - CLog::Log(LOGDEBUG, "CDVDDemuxHTSP::SubscriptionStart - id: %d, type: %s", index, type); - - if(!strcmp(type, "AC3")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_AC3; - } else if(!strcmp(type, "EAC3")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_EAC3; - } else if(!strcmp(type, "MPEG2AUDIO")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_MP2; - } else if(!strcmp(type, "AAC")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_AAC; - } else if(!strcmp(type, "MPEG2VIDEO")) { - st.v = new CDemuxStreamVideoHTSP(this, type); - st.v->codec = AV_CODEC_ID_MPEG2VIDEO; - st.v->iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); - st.v->iHeight = htsmsg_get_u32_or_default(sub, "height", 0); - } else if(!strcmp(type, "H264")) { - st.v = new CDemuxStreamVideoHTSP(this, type); - st.v->codec = AV_CODEC_ID_H264; - st.v->iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); - st.v->iHeight = htsmsg_get_u32_or_default(sub, "height", 0); - } else if(!strcmp(type, "DVBSUB")) { - st.s = new CDemuxStreamSubtitle(); - st.s->codec = AV_CODEC_ID_DVB_SUBTITLE; - uint32_t composition_id = 0, ancillary_id = 0; - htsmsg_get_u32(sub, "composition_id", &composition_id); - htsmsg_get_u32(sub, "ancillary_id" , &ancillary_id); - if(composition_id || ancillary_id) - { - st.s->ExtraData = new uint8_t[4]; - st.s->ExtraSize = 4; - st.s->ExtraData[0] = (composition_id >> 8) & 0xff; - st.s->ExtraData[1] = (composition_id >> 0) & 0xff; - st.s->ExtraData[2] = (ancillary_id >> 8) & 0xff; - st.s->ExtraData[3] = (ancillary_id >> 0) & 0xff; - } - } else if(!strcmp(type, "TEXTSUB")) { - st.s = new CDemuxStreamSubtitle(); - st.s->codec = AV_CODEC_ID_TEXT; - } else if(!strcmp(type, "TELETEXT")) { - st.t = new CDemuxStreamTeletext(); - st.t->codec = AV_CODEC_ID_DVB_TELETEXT; - } else { - continue; - } - - if((lang = htsmsg_get_str(sub, "language"))) - { - strncpy(st.g->language, lang, sizeof(st.g->language)); - st.g->language[sizeof(st.g->language) - 1] = '\0'; - } - - st.g->iId = m_Streams.size(); - st.g->iPhysicalId = index; - m_Streams.push_back(st.g); - } -} -void CDVDDemuxHTSP::SubscriptionStop (htsmsg_t *m) -{ - for(int i = 0; i < (int)m_Streams.size(); i++) - delete m_Streams[i]; - m_Streams.clear(); -} - -void CDVDDemuxHTSP::SubscriptionStatus(htsmsg_t *m) -{ - const char* status; - status = htsmsg_get_str(m, "status"); - if(status == NULL) - m_Status = ""; - else - { - m_StatusCount++; - m_Status = status; - CLog::Log(LOGDEBUG, "CDVDDemuxHTSP::SubscriptionStatus - %s", status); - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "TVHeadend Status", status, TOAST_DISPLAY_TIME, false); - } -} - -CDemuxStream* CDVDDemuxHTSP::GetStream(int iStreamId) -{ - if(iStreamId >= 0 && iStreamId < (int)m_Streams.size()) - return m_Streams[iStreamId]; - - return NULL; -} - -int CDVDDemuxHTSP::GetNrOfStreams() -{ - return m_Streams.size(); -} - -std::string CDVDDemuxHTSP::GetFileName() -{ - if(m_Input) - return m_Input->GetFileName(); - else - return ""; -} - -void CDVDDemuxHTSP::Abort() -{ - if(m_Input) - return m_Input->Abort(); -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h deleted file mode 100644 index 6d73a9d..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#pragma once -#include "DVDDemux.h" -#include "filesystem/HTSPSession.h" - -class CDVDInputStreamHTSP; -typedef struct htsmsg htsmsg_t; - -class CDVDDemuxHTSP : public CDVDDemux -{ -public: - CDVDDemuxHTSP(); - virtual ~CDVDDemuxHTSP(); - - bool Open(CDVDInputStream* input); - void Dispose(); - void Reset(); - void Flush(); - void Abort(); - void SetSpeed(int iSpeed){}; - - std::string GetFileName(); - - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL) { return false; } - int GetStreamLength() { return 0; } - - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - -protected: - friend class CDemuxStreamVideoHTSP; - - void SubscriptionStart (htsmsg_t *m); - void SubscriptionStop (htsmsg_t *m); - void SubscriptionStatus(htsmsg_t *m); - - htsmsg_t* ReadStream(); - bool ReadStream(uint8_t* buf, int len); - - typedef std::vector TStreams; - - CDVDInputStream* m_Input; - TStreams m_Streams; - std::string m_Status; - int m_StatusCount; - HTSP::SQueueStatus m_QueueStatus; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp deleted file mode 100644 index 4ed2d5c..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDDemuxPVRClient.h" -#include "DVDDemuxUtils.h" -#include "utils/log.h" -#include "pvr/PVRManager.h" -#include "pvr/addons/PVRClients.h" -#include "../DVDClock.h" - -#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE) - -using namespace PVR; - -CDemuxStreamPVRInternal::CDemuxStreamPVRInternal(CDVDDemuxPVRClient *parent) - : m_parent(parent) - , m_parser(NULL) - , m_context(NULL) - , m_parser_split(false) -{ -} - -CDemuxStreamPVRInternal::~CDemuxStreamPVRInternal() -{ - DisposeParser(); -} - -void CDemuxStreamPVRInternal::DisposeParser() -{ - if (m_parser) - { - av_parser_close(m_parser); - m_parser = NULL; - } - if (m_context) - { - avcodec_close(m_context); - m_context = NULL; - } -} - -void CDemuxStreamVideoPVRClient::GetStreamInfo(std::string& strInfo) -{ - switch (codec) - { - case AV_CODEC_ID_MPEG2VIDEO: - strInfo = "mpeg2video"; - break; - case AV_CODEC_ID_H264: - strInfo = "h264"; - break; - default: - break; - } -} - -void CDemuxStreamAudioPVRClient::GetStreamInfo(std::string& strInfo) -{ - switch (codec) - { - case AV_CODEC_ID_AC3: - strInfo = "ac3"; - break; - case AV_CODEC_ID_EAC3: - strInfo = "eac3"; - break; - case AV_CODEC_ID_MP2: - strInfo = "mpeg2audio"; - break; - case AV_CODEC_ID_AAC: - strInfo = "aac"; - break; - case AV_CODEC_ID_DTS: - strInfo = "dts"; - break; - default: - break; - } -} - -void CDemuxStreamSubtitlePVRClient::GetStreamInfo(std::string& strInfo) -{ -} - -CDVDDemuxPVRClient::CDVDDemuxPVRClient() : CDVDDemux() -{ - m_pInput = NULL; - for (int i = 0; i < MAX_STREAMS; i++) m_streams[i] = NULL; -} - -CDVDDemuxPVRClient::~CDVDDemuxPVRClient() -{ - Dispose(); -} - -bool CDVDDemuxPVRClient::Open(CDVDInputStream* pInput) -{ - Abort(); - - m_pInput = pInput; - if (!g_PVRClients->GetPlayingClient(m_pvrClient)) - return false; - - return true; -} - -void CDVDDemuxPVRClient::Dispose() -{ - for (int i = 0; i < MAX_STREAMS; i++) - { - delete m_streams[i]; - m_streams[i] = NULL; - } - - m_pInput = NULL; -} - -void CDVDDemuxPVRClient::DisposeStream(int iStreamId) -{ - if (iStreamId < 0 || iStreamId >= MAX_STREAMS) - return; - delete m_streams[iStreamId]; - m_streams[iStreamId] = NULL; -} - -void CDVDDemuxPVRClient::Reset() -{ - if(m_pInput && g_PVRManager.IsStarted()) - m_pvrClient->DemuxReset(); - - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxPVRClient::Abort() -{ - if(m_pInput) - m_pvrClient->DemuxAbort(); -} - -void CDVDDemuxPVRClient::Flush() -{ - if(m_pInput && g_PVRManager.IsStarted()) - m_pvrClient->DemuxFlush(); -} - -void CDVDDemuxPVRClient::ParsePacket(DemuxPacket* pkt) -{ - CDemuxStream* st = m_streams[pkt->iStreamId]; - if (st == NULL) - return; - - if (st->ExtraSize) - return; - - CDemuxStreamPVRInternal* pvr = dynamic_cast(st); - - if(pvr == NULL - || pvr->m_parser == NULL) - return; - - if(pvr->m_context == NULL) - { - AVCodec *codec = avcodec_find_decoder(st->codec); - if (codec == NULL) - { - CLog::Log(LOGERROR, "%s - can't find decoder", __FUNCTION__); - pvr->DisposeParser(); - return; - } - - pvr->m_context = avcodec_alloc_context3(codec); - if(pvr->m_context == NULL) - { - CLog::Log(LOGERROR, "%s - can't allocate context", __FUNCTION__); - pvr->DisposeParser(); - return; - } - pvr->m_context->time_base.num = 1; - pvr->m_context->time_base.den = DVD_TIME_BASE; - } - - if(pvr->m_parser_split && pvr->m_parser->parser->split) - { - int len = pvr->m_parser->parser->split(pvr->m_context, pkt->pData, pkt->iSize); - if (len > 0 && len < FF_MAX_EXTRADATA_SIZE) - { - if (st->ExtraData) - delete[] (uint8_t*)st->ExtraData; - st->changes++; - st->disabled = false; - st->ExtraSize = len; - st->ExtraData = new uint8_t[len+FF_INPUT_BUFFER_PADDING_SIZE]; - memcpy(st->ExtraData, pkt->pData, len); - memset((uint8_t*)st->ExtraData + len, 0 , FF_INPUT_BUFFER_PADDING_SIZE); - pvr->m_parser_split = false; - } - } - - - uint8_t *outbuf = NULL; - int outbuf_size = 0; - int len = av_parser_parse2(pvr->m_parser - , pvr->m_context, &outbuf, &outbuf_size - , pkt->pData, pkt->iSize - , (int64_t)(pkt->pts * DVD_TIME_BASE) - , (int64_t)(pkt->dts * DVD_TIME_BASE) - , 0); - /* our parse is setup to parse complete frames, so we don't care about outbufs */ - if(len >= 0) - { -#define CHECK_UPDATE(st, trg, src, invalid) do { \ - if(src != invalid \ - && src != st->trg) { \ - CLog::Log(LOGDEBUG, "%s - {%d} " #trg " changed from %d to %d", __FUNCTION__, st->iId, st->trg, src); \ - st->trg = src; \ - st->changes++; \ - st->disabled = false; \ - } \ - } while(0) - - - CHECK_UPDATE(st, profile, pvr->m_context->profile , FF_PROFILE_UNKNOWN); - CHECK_UPDATE(st, level , pvr->m_context->level , FF_LEVEL_UNKNOWN); - - switch (st->type) - { - case STREAM_AUDIO: { - CDemuxStreamAudioPVRClient* sta = static_cast(st); - CHECK_UPDATE(sta, iChannels , pvr->m_context->channels , 0); - CHECK_UPDATE(sta, iSampleRate , pvr->m_context->sample_rate, 0); - break; - } - case STREAM_VIDEO: { - CDemuxStreamVideoPVRClient* stv = static_cast(st); - CHECK_UPDATE(stv, iWidth , pvr->m_context->width , 0); - CHECK_UPDATE(stv, iHeight , pvr->m_context->height, 0); - break; - } - - default: - break; - } - -#undef CHECK_UPDATE - } - else - CLog::Log(LOGDEBUG, "%s - parser returned error %d", __FUNCTION__, len); - - return; -} - -DemuxPacket* CDVDDemuxPVRClient::Read() -{ - if (!g_PVRManager.IsStarted()) - return CDVDDemuxUtils::AllocateDemuxPacket(0); - - DemuxPacket* pPacket = m_pvrClient->DemuxRead(); - if (!pPacket) - { - if (m_pInput) - m_pInput->Close(); - return NULL; - } - - if (pPacket->iStreamId == DMX_SPECIALID_STREAMINFO) - { - RequestStreams(); - CDVDDemuxUtils::FreeDemuxPacket(pPacket); - return CDVDDemuxUtils::AllocateDemuxPacket(0); - } - else if (pPacket->iStreamId == DMX_SPECIALID_STREAMCHANGE) - { - RequestStreams(); - } - else if (pPacket->iStreamId >= 0 - && pPacket->iStreamId < MAX_STREAMS - && m_streams[pPacket->iStreamId]) - { - ParsePacket(pPacket); - } - - return pPacket; -} - -CDemuxStream* CDVDDemuxPVRClient::GetStream(int iStreamId) -{ - if (iStreamId < 0 || iStreamId >= MAX_STREAMS) return NULL; - return m_streams[iStreamId]; -} - -void CDVDDemuxPVRClient::RequestStreams() -{ - if (!g_PVRManager.IsStarted()) - return; - - PVR_STREAM_PROPERTIES props = {}; - m_pvrClient->GetStreamProperties(&props); - unsigned int i; - - for (i = 0; i < props.iStreamCount; ++i) - { - CDemuxStream *stm = m_streams[i]; - - if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_AUDIO) - { - CDemuxStreamAudioPVRClient* st = NULL; - if (stm) - { - st = dynamic_cast(stm); - if (!st || (st->codec != (AVCodecID)props.stream[i].iCodecId)) - DisposeStream(i); - } - if (!m_streams[i]) - { - st = new CDemuxStreamAudioPVRClient(this); - st->m_parser = av_parser_init(props.stream[i].iCodecId); - if(st->m_parser) - st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } - st->iChannels = props.stream[i].iChannels; - st->iSampleRate = props.stream[i].iSampleRate; - st->iBlockAlign = props.stream[i].iBlockAlign; - st->iBitRate = props.stream[i].iBitRate; - st->iBitsPerSample = props.stream[i].iBitsPerSample; - m_streams[i] = st; - st->m_parser_split = true; - st->changes++; - } - else if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_VIDEO) - { - CDemuxStreamVideoPVRClient* st = NULL; - if (stm) - { - st = dynamic_cast(stm); - if (!st - || (st->codec != (AVCodecID)props.stream[i].iCodecId) - || (st->iWidth != props.stream[i].iWidth) - || (st->iHeight != props.stream[i].iHeight)) - DisposeStream(i); - } - if (!m_streams[i]) - { - st = new CDemuxStreamVideoPVRClient(this); - st->m_parser = av_parser_init(props.stream[i].iCodecId); - if(st->m_parser) - st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } - st->iFpsScale = props.stream[i].iFPSScale; - st->iFpsRate = props.stream[i].iFPSRate; - st->iHeight = props.stream[i].iHeight; - st->iWidth = props.stream[i].iWidth; - st->fAspect = props.stream[i].fAspect; - st->stereo_mode = "mono"; - m_streams[i] = st; - st->m_parser_split = true; - } - else if (props.stream[i].iCodecId == AV_CODEC_ID_DVB_TELETEXT) - { - if (stm) - { - if (stm->codec != (AVCodecID)props.stream[i].iCodecId) - DisposeStream(i); - } - if (!m_streams[i]) - m_streams[i] = new CDemuxStreamTeletext(); - } - else if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_SUBTITLE) - { - CDemuxStreamSubtitlePVRClient* st = NULL; - if (stm) - { - st = dynamic_cast(stm); - if (!st || (st->codec != (AVCodecID)props.stream[i].iCodecId)) - DisposeStream(i); - } - if (!m_streams[i]) - { - st = new CDemuxStreamSubtitlePVRClient(this); - } - if(props.stream[i].iIdentifier) - { - st->ExtraData = new uint8_t[4]; - st->ExtraSize = 4; - st->ExtraData[0] = (props.stream[i].iIdentifier >> 8) & 0xff; - st->ExtraData[1] = (props.stream[i].iIdentifier >> 0) & 0xff; - st->ExtraData[2] = (props.stream[i].iIdentifier >> 24) & 0xff; - st->ExtraData[3] = (props.stream[i].iIdentifier >> 16) & 0xff; - } - m_streams[i] = st; - } - else - { - if (m_streams[i]) - DisposeStream(i); - m_streams[i] = new CDemuxStream(); - } - - m_streams[i]->codec = (AVCodecID)props.stream[i].iCodecId; - m_streams[i]->iId = i; - m_streams[i]->iPhysicalId = props.stream[i].iPhysicalId; - m_streams[i]->language[0] = props.stream[i].strLanguage[0]; - m_streams[i]->language[1] = props.stream[i].strLanguage[1]; - m_streams[i]->language[2] = props.stream[i].strLanguage[2]; - m_streams[i]->language[3] = props.stream[i].strLanguage[3]; - - CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::RequestStreams(): added/updated stream %d:%d with codec_id %d", - m_streams[i]->iId, - m_streams[i]->iPhysicalId, - m_streams[i]->codec); - } - // check if we need to dispose any streams no longer in props - for (unsigned int j = i; j < MAX_STREAMS; j++) - { - if (m_streams[j]) - { - CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::RequestStreams(): disposed stream %d:%d with codec_id %d", - m_streams[j]->iId, - m_streams[j]->iPhysicalId, - m_streams[j]->codec); - DisposeStream(j); - } - } -} - -int CDVDDemuxPVRClient::GetNrOfStreams() -{ - int i = 0; - while (i < MAX_STREAMS && m_streams[i]) i++; - return i; -} - -std::string CDVDDemuxPVRClient::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -void CDVDDemuxPVRClient::GetStreamCodecName(int iStreamId, std::string &strName) -{ - CDemuxStream *stream = GetStream(iStreamId); - if (stream) - { - if (stream->codec == AV_CODEC_ID_AC3) - strName = "ac3"; - else if (stream->codec == AV_CODEC_ID_MP2) - strName = "mp2"; - else if (stream->codec == AV_CODEC_ID_AAC) - strName = "aac"; - else if (stream->codec == AV_CODEC_ID_DTS) - strName = "dca"; - else if (stream->codec == AV_CODEC_ID_MPEG2VIDEO) - strName = "mpeg2video"; - else if (stream->codec == AV_CODEC_ID_H264) - strName = "h264"; - else if (stream->codec == AV_CODEC_ID_EAC3) - strName = "eac3"; - } -} - -bool CDVDDemuxPVRClient::SeekTime(int timems, bool backwards, double *startpts) -{ - if (m_pInput) - return m_pvrClient->SeekTime(timems, backwards, startpts); - return false; -} - -void CDVDDemuxPVRClient::SetSpeed ( int speed ) -{ - if (m_pInput) - m_pvrClient->SetSpeed(speed); -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h deleted file mode 100644 index 2fc3c63..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-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 - * . - * - */ - -#include "DVDDemux.h" -#include -#include "pvr/addons/PVRClient.h" - -extern "C" { -#include "libavcodec/avcodec.h" -#include "libavformat/avformat.h" -} - -class CDVDDemuxPVRClient; -struct PVR_STREAM_PROPERTIES; - -class CDemuxStreamPVRInternal -{ -public: - CDemuxStreamPVRInternal(CDVDDemuxPVRClient *parent); - ~CDemuxStreamPVRInternal(); - - void DisposeParser(); - - CDVDDemuxPVRClient * m_parent; - AVCodecParserContext* m_parser; - AVCodecContext * m_context; - bool m_parser_split; -}; - -class CDemuxStreamVideoPVRClient - : public CDemuxStreamVideo - , public CDemuxStreamPVRInternal -{ -public: - CDemuxStreamVideoPVRClient(CDVDDemuxPVRClient *parent) - : CDemuxStreamPVRInternal(parent) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - -class CDemuxStreamAudioPVRClient - : public CDemuxStreamAudio - , public CDemuxStreamPVRInternal -{ -public: - CDemuxStreamAudioPVRClient(CDVDDemuxPVRClient *parent) - : CDemuxStreamPVRInternal(parent) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - -class CDemuxStreamSubtitlePVRClient - : public CDemuxStreamSubtitle - , public CDemuxStreamPVRInternal -{ -public: - CDemuxStreamSubtitlePVRClient(CDVDDemuxPVRClient *parent) - : CDemuxStreamPVRInternal(parent) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - - -class CDVDDemuxPVRClient : public CDVDDemux -{ - friend class CDemuxStreamPVRInternal; - -public: - - CDVDDemuxPVRClient(); - ~CDVDDemuxPVRClient(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Abort(); - void Flush(); - DemuxPacket* Read(); - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - void SetSpeed(int iSpeed); - int GetStreamLength() { return 0; } - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - std::string GetFileName(); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - -protected: - CDVDInputStream* m_pInput; -#ifndef MAX_STREAMS - #define MAX_STREAMS 100 -#endif - CDemuxStream* m_streams[MAX_STREAMS]; // maximum number of streams that ffmpeg can handle - std::shared_ptr m_pvrClient; - -private: - void RequestStreams(); - void ParsePacket(DemuxPacket* pPacket); - void DisposeStream(int iStreamId); -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp deleted file mode 100644 index a69342a..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DVDCodecs/DVDCodecs.h" -#include "DVDInputStreams/DVDInputStreamHttp.h" -#include "DVDDemuxShoutcast.h" -#include "DVDDemuxUtils.h" -#include "DVDClock.h" // for DVD_TIME_BASE -#include "../../../utils/HttpHeader.h" - -#define ICY_NOTICE1 "icy-notice1" // string -#define ICY_NOTICE2 "icy-notice2" // string -#define ICY_NAME "icy-name" // string -#define ICY_GENRE "icy-genre" // string -#define ICY_URL "icy-url" // string -#define ICY_PUBLIC "icy-pub" // int (1 / 0) -#define ICY_BITRATE "icy-br" // int (bitrate = val * 1000 ?) -#define ICY_METAINTERVAL "icy-metaint" // int - -#define CONTENT_TYPE_MP3 "audio/mpeg" -#define CONTENT_TYPE_AAC "audio/aac" -#define CONTENT_TYPE_AACPLUS "audio/aacp" - -// class CDemuxStreamVideoFFmpeg -void CDemuxStreamAudioShoutcast::GetStreamInfo(std::string& strInfo) -{ - strInfo = "Shoutcast"; -} - -CDVDDemuxShoutcast::CDVDDemuxShoutcast() : CDVDDemux() -{ - m_pInput = NULL; - m_pDemuxStream = NULL; - m_iMetaStreamInterval = 0; -} - -CDVDDemuxShoutcast::~CDVDDemuxShoutcast() -{ - Dispose(); -} - -bool CDVDDemuxShoutcast::Open(CDVDInputStream* pInput) -{ - Dispose(); - - m_pInput = pInput; - - // the input stream should be a http stream - if (!pInput->IsStreamType(DVDSTREAM_TYPE_HTTP)) return false; - CDVDInputStreamHttp* pInputStreamHttp = (CDVDInputStreamHttp*)pInput; - - CHttpHeader* pHeader = pInputStreamHttp->GetHttpHeader(); - - std::string strMetaInt = pHeader->GetValue(ICY_METAINTERVAL); - std::string strMimeType = pHeader->GetMimeType(); - - // create new demuxer stream - m_pDemuxStream = new CDemuxStreamAudioShoutcast(); - m_pDemuxStream->iId = 0; - m_pDemuxStream->iPhysicalId = 0; - m_pDemuxStream->iDuration = 0; - m_pDemuxStream->iChannels = 2; - m_pDemuxStream->iSampleRate = 0; - - // set meta interval - m_iMetaStreamInterval = atoi(strMetaInt.c_str()); - - if (stricmp(strMimeType.c_str(), CONTENT_TYPE_AAC) == 0 || - stricmp(strMimeType.c_str(), CONTENT_TYPE_AACPLUS) == 0) - { - // need an aac decoder first - m_pDemuxStream->codec = AV_CODEC_ID_AAC; - } - else // (stricmp(strMimeType, CONTENT_TYPE_MP3) == 0) - { - // default to mp3 - m_pDemuxStream->codec = AV_CODEC_ID_MP3; - } - - return true; -} - -void CDVDDemuxShoutcast::Dispose() -{ - if (m_pDemuxStream) delete m_pDemuxStream; - m_pDemuxStream = NULL; - - m_pInput = NULL; -} - -void CDVDDemuxShoutcast::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxShoutcast::Flush() -{ -} - -DemuxPacket* CDVDDemuxShoutcast::Read() -{ - // XXX - // if meta interval is greater than FileCurl's max read size (currently 64k) - // it will simply fail becuse the meta-interval will get incorrect - - int iDataToRead = SHOUTCAST_BUFFER_SIZE; - if (m_iMetaStreamInterval > 0) iDataToRead = m_iMetaStreamInterval; - - DemuxPacket* pPacket; - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(iDataToRead); - if (pPacket) - { - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - pPacket->iStreamId = 0; - - // read the data - int iRead = m_pInput->Read(pPacket->pData, iDataToRead); - - pPacket->iSize = iRead; - - if (iRead <= 0) - { - CDVDDemuxUtils::FreeDemuxPacket(pPacket); - pPacket = NULL; - } - } - - if (m_iMetaStreamInterval > 0) - { - // we already have read m_iMetaStreamInterval bytes of streaming data - // metadata follows - uint8_t l; - int iRead = m_pInput->Read(&l, 1); - if (iRead > 0) - { - int iMetaLength = l * 16; - - if (iMetaLength > 0) - { - // iMetaLength cannot be larger then 16 * 255 - uint8_t buffer[16 * 255]; - - // skip meta data for now - m_pInput->Read(buffer, iMetaLength); - } - } - } - - return pPacket; -} - -bool CDVDDemuxShoutcast::SeekTime(int time, bool backwords, double* startpts) -{ - return false; -} - -int CDVDDemuxShoutcast::GetStreamLength() -{ - return 0; -} - -CDemuxStream* CDVDDemuxShoutcast::GetStream(int iStreamId) -{ - return m_pDemuxStream; -} - -int CDVDDemuxShoutcast::GetNrOfStreams() -{ - return 1; -} - -std::string CDVDDemuxShoutcast::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h deleted file mode 100644 index a802167..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DVDDemux.h" - -class CDemuxStreamAudioShoutcast : public CDemuxStreamAudio -{ -public: - virtual void GetStreamInfo(std::string& strInfo); -}; - -#define SHOUTCAST_BUFFER_SIZE 1024 * 32 - -class CDVDDemuxShoutcast : public CDVDDemux -{ -public: - CDVDDemuxShoutcast(); - virtual ~CDVDDemuxShoutcast(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Flush(); - void Abort(){} - void SetSpeed(int iSpeed){}; - virtual std::string GetFileName(); - - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - int GetStreamLength(); - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - -protected: - - CDemuxStreamAudioShoutcast* m_pDemuxStream; - - int m_iMetaStreamInterval; - CDVDInputStream* m_pInput; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp deleted file mode 100644 index ab298b2..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS) - #include "config.h" -#endif -#include "DVDDemuxUtils.h" -#include "DVDClock.h" -#include "utils/log.h" - -extern "C" { -#include "libavcodec/avcodec.h" -} - -void CDVDDemuxUtils::FreeDemuxPacket(DemuxPacket* pPacket) -{ - if (pPacket) - { - try { - if (pPacket->pData) _aligned_free(pPacket->pData); - delete pPacket; - } - catch(...) { - CLog::Log(LOGERROR, "%s - Exception thrown while freeing packet", __FUNCTION__); - } - } -} - -DemuxPacket* CDVDDemuxUtils::AllocateDemuxPacket(int iDataSize) -{ - DemuxPacket* pPacket = new DemuxPacket; - if (!pPacket) return NULL; - - try - { - memset(pPacket, 0, sizeof(DemuxPacket)); - - if (iDataSize > 0) - { - // need to allocate a few bytes more. - // From avcodec.h (ffmpeg) - /** - * Required number of additionally allocated bytes at the end of the input bitstream for decoding. - * this is mainly needed because some optimized bitstream readers read - * 32 or 64 bit at once and could read over the end
- * Note, if the first 23 bits of the additional bytes are not 0 then damaged - * MPEG bitstreams could cause overread and segfault - */ - pPacket->pData =(uint8_t*)_aligned_malloc(iDataSize + FF_INPUT_BUFFER_PADDING_SIZE, 16); - if (!pPacket->pData) - { - FreeDemuxPacket(pPacket); - return NULL; - } - - // reset the last 8 bytes to 0; - memset(pPacket->pData + iDataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE); - } - - // setup defaults - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - pPacket->iStreamId = -1; - } - catch(...) - { - CLog::Log(LOGERROR, "%s - Exception thrown", __FUNCTION__); - FreeDemuxPacket(pPacket); - pPacket = NULL; - } - return pPacket; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h deleted file mode 100644 index 2c12df3..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DVDDemuxPacket.h" - -class CDVDDemuxUtils -{ -public: - static void FreeDemuxPacket(DemuxPacket* pPacket); - static DemuxPacket* AllocateDemuxPacket(int iDataSize = 0); -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp deleted file mode 100644 index 9625a19..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DVDDemuxVobsub.h" -#include "DVDInputStreams/DVDFactoryInputStream.h" -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDStreamInfo.h" -#include "DVDCodecs/DVDCodecs.h" -#include "DVDDemuxers/DVDDemuxFFmpeg.h" -#include "DVDDemuxers/DVDDemuxUtils.h" -#include "DVDClock.h" -#include "DVDSubtitles/DVDSubtitleStream.h" - -#include - -using namespace std; - -CDVDDemuxVobsub::CDVDDemuxVobsub() -{ -} - -CDVDDemuxVobsub::~CDVDDemuxVobsub() -{ - for(unsigned i=0;i pStream(new CDVDSubtitleStream()); - if(!pStream->Open(filename)) - return false; - - string vobsub = subfilename; - if ( vobsub == "") - { - vobsub = filename; - vobsub.erase(vobsub.rfind('.'), vobsub.size()); - vobsub += ".sub"; - } - - m_Input.reset(CDVDFactoryInputStream::CreateInputStream(NULL, vobsub, "")); - if(!m_Input.get() || !m_Input->Open(vobsub.c_str(), "video/x-vobsub")) - return false; - - m_Demuxer.reset(new CDVDDemuxFFmpeg()); - if(!m_Demuxer->Open(m_Input.get())) - return false; - - CDVDStreamInfo hints; - CDVDCodecOptions options; - hints.codec = AV_CODEC_ID_DVD_SUBTITLE; - - char line[2048]; - DECLARE_UNUSED(bool,res) - - SState state; - state.delay = 0; - state.id = -1; - - while( pStream->ReadLine(line, sizeof(line)) ) - { - if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#') - continue; - else if (strncmp("langidx:", line, 8) == 0) - res = ParseLangIdx(state, line + 8); - else if (strncmp("delay:", line, 6) == 0) - res = ParseDelay(state, line + 6); - else if (strncmp("id:", line, 3) == 0) - res = ParseId(state, line + 3); - else if (strncmp("timestamp:", line, 10) == 0) - res = ParseTimestamp(state, line + 10); - else if (strncmp("palette:", line, 8) == 0 - || strncmp("size:", line, 5) == 0 - || strncmp("org:", line, 4) == 0 - || strncmp("custom colors:", line, 14) == 0 - || strncmp("scale:", line, 6) == 0 - || strncmp("alpha:", line, 6) == 0 - || strncmp("fadein/out:", line, 11) == 0 - || strncmp("forced subs:", line, 12) == 0) - res = ParseExtra(state, line); - else - continue; - } - - struct sorter s; - sort(m_Timestamps.begin(), m_Timestamps.end(), s); - m_Timestamp = m_Timestamps.begin(); - - for(unsigned i=0;iExtraSize = state.extra.length()+1; - m_Streams[i]->ExtraData = new uint8_t[m_Streams[i]->ExtraSize]; - strcpy((char*)m_Streams[i]->ExtraData, state.extra.c_str()); - } - - return true; -} - -void CDVDDemuxVobsub::Reset() -{ - Flush(); -} - -void CDVDDemuxVobsub::Flush() -{ - m_Demuxer->Flush(); -} - -bool CDVDDemuxVobsub::SeekTime(int time, bool backwords, double* startpts) -{ - double pts = DVD_MSEC_TO_TIME(time); - m_Timestamp = m_Timestamps.begin(); - for(;m_Timestamp != m_Timestamps.end();++m_Timestamp) - { - if(m_Timestamp->pts > pts) - break; - } - for(unsigned i=0;i::iterator current; - do { - if(m_Timestamp == m_Timestamps.end()) - return NULL; - - current = m_Timestamp++; - } while(m_Streams[current->id]->m_discard == AVDISCARD_ALL); - - if(!m_Demuxer->SeekByte(current->pos)) - return NULL; - - DemuxPacket *packet = m_Demuxer->Read(); - if(!packet) - return NULL; - - packet->iStreamId = current->id; - packet->pts = current->pts; - packet->dts = current->pts; - - return packet; -} - -bool CDVDDemuxVobsub::ParseLangIdx(SState& state, char* line) -{ - return true; -} - -bool CDVDDemuxVobsub::ParseDelay(SState& state, char* line) -{ - int h,m,s,ms; - bool negative = false; - - while(*line == ' ') line++; - if(*line == '-') - { - line++; - negative = true; - } - if(sscanf(line, "%d:%d:%d:%d", &h, &m, &s, &ms) != 4) - return false; - state.delay = h*3600.0 + m*60.0 + s + ms*0.001; - if(negative) - state.delay *= -1; - return true; -} - -bool CDVDDemuxVobsub::ParseId(SState& state, char* line) -{ - unique_ptr stream(new CStream(this)); - - while(*line == ' ') line++; - strncpy(stream->language, line, 2); - stream->language[2] = '\0'; - line+=2; - - while(*line == ' ' || *line == ',') line++; - if (strncmp("index:", line, 6) == 0) - { - line+=6; - while(*line == ' ') line++; - stream->iPhysicalId = atoi(line); - } - else - stream->iPhysicalId = -1; - - stream->codec = AV_CODEC_ID_DVD_SUBTITLE; - stream->iId = m_Streams.size(); - stream->source = STREAM_SOURCE_DEMUX_SUB; - - state.id = stream->iId; - m_Streams.push_back(stream.release()); - return true; -} - -bool CDVDDemuxVobsub::ParseExtra(SState& state, char* line) -{ - state.extra += line; - state.extra += '\n'; - return true; -} - -bool CDVDDemuxVobsub::ParseTimestamp(SState& state, char* line) -{ - if(state.id < 0) - return false; - - int h,m,s,ms; - STimestamp timestamp; - - while(*line == ' ') line++; - if(sscanf(line, "%d:%d:%d:%d, filepos:%" PRIx64, &h, &m, &s, &ms, ×tamp.pos) != 5) - return false; - - timestamp.id = state.id; - timestamp.pts = DVD_SEC_TO_TIME(state.delay + h*3600.0 + m*60.0 + s + ms*0.001); - m_Timestamps.push_back(timestamp); - return true; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h deleted file mode 100644 index 0c75c4a..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "DVDDemux.h" - -#include -#include - -class CDVDOverlayCodecFFmpeg; -class CDVDInputStream; -class CDVDDemuxFFmpeg; - -class CDVDDemuxVobsub : public CDVDDemux -{ -public: - CDVDDemuxVobsub(); - virtual ~CDVDDemuxVobsub(); - - virtual bool Open(const std::string& filename, const std::string& subfilename = ""); - virtual void Reset(); - virtual void Abort() {}; - virtual void Flush(); - virtual DemuxPacket* Read(); - virtual bool SeekTime(int time, bool backwords, double* startpts = NULL); - virtual void SetSpeed(int speed) {} - virtual CDemuxStream* GetStream(int index) { return m_Streams[index]; } - virtual int GetNrOfStreams() { return m_Streams.size(); } - virtual int GetStreamLength() { return 0; } - virtual std::string GetFileName() { return m_Filename; } - -private: - class CStream - : public CDemuxStreamSubtitle - { - public: - CStream(CDVDDemuxVobsub* parent) - : m_discard(AVDISCARD_NONE), m_parent(parent) - {} - virtual void SetDiscard(AVDiscard discard) { m_discard = discard; } - virtual AVDiscard GetDiscard() { return m_discard; } - - AVDiscard m_discard; - CDVDDemuxVobsub* m_parent; - }; - - typedef struct STimestamp - { - int64_t pos; - double pts; - int id; - } STimestamp; - - std::string m_Filename; - std::unique_ptr m_Input; - std::unique_ptr m_Demuxer; - std::vector m_Timestamps; - std::vector::iterator m_Timestamp; - std::vector m_Streams; - - typedef struct SState - { - int id; - double delay; - std::string extra; - } SState; - - struct sorter - { - bool operator()(const STimestamp &p1, const STimestamp &p2) - { - return p1.pts < p2.pts || (p1.pts == p2.pts && p1.id < p2.id); - } - }; - - bool ParseLangIdx(SState& state, char* line); - bool ParseDelay(SState& state, char* line); - bool ParseId(SState& state, char* line); - bool ParseExtra(SState& state, char* line); - bool ParseTimestamp(SState& state, char* line); -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp deleted file mode 100644 index f909c32..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2005-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 - * . - * - */ - -#include "system.h" -#include "DVDFactoryDemuxer.h" - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDInputStreams/DVDInputStreamHttp.h" -#include "DVDInputStreams/DVDInputStreamPVRManager.h" - -#include "DVDDemuxFFmpeg.h" -#include "DVDDemuxShoutcast.h" -#ifdef HAS_FILESYSTEM_HTSP -#include "DVDDemuxHTSP.h" -#endif -#include "DVDDemuxBXA.h" -#include "DVDDemuxCDDA.h" -#include "DVDDemuxPVRClient.h" -#include "pvr/PVRManager.h" -#include "pvr/addons/PVRClients.h" - -using namespace std; -using namespace PVR; - -CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream, bool fileinfo) -{ - if (!pInputStream) - return NULL; - - // Try to open the AirTunes demuxer - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FILE) && pInputStream->GetContent().compare("audio/x-xbmc-pcm") == 0 ) - { - // audio/x-xbmc-pcm this is the used codec for AirTunes - // (apples audio only streaming) - unique_ptr demuxer(new CDVDDemuxBXA()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } - - // Try to open CDDA demuxer - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FILE) && pInputStream->GetContent().compare("application/octet-stream") == 0) - { - std::string filename = pInputStream->GetFileName(); - if (filename.substr(0, 7) == "cdda://") - { - CLog::Log(LOGDEBUG, "DVDFactoryDemuxer: Stream is probably CD audio. Creating CDDA demuxer."); - - unique_ptr demuxer(new CDVDDemuxCDDA()); - if (demuxer->Open(pInputStream)) - { - return demuxer.release(); - } - } - } - - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_HTTP)) - { - CDVDInputStreamHttp* pHttpStream = (CDVDInputStreamHttp*)pInputStream; - CHttpHeader *header = pHttpStream->GetHttpHeader(); - - /* check so we got the meta information as requested in our http header */ - if( header->GetValue("icy-metaint").length() > 0 ) - { - unique_ptr demuxer(new CDVDDemuxShoutcast()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } - } - -#ifdef HAS_FILESYSTEM_HTSP - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_HTSP)) - { - unique_ptr demuxer(new CDVDDemuxHTSP()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } -#endif - - bool streaminfo = true; /* Look for streams before playback */ - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) - { - CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream; - CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream(); - - /* Don't parse the streaminfo for some cases of streams to reduce the channel switch time */ - bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); - streaminfo = !useFastswitch; - - if(pOtherStream) - { - /* Used for MediaPortal PVR addon (uses PVR otherstream for playback of rtsp streams) */ - if (pOtherStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) - { - unique_ptr demuxer(new CDVDDemuxFFmpeg()); - if(demuxer->Open(pOtherStream, streaminfo)) - return demuxer.release(); - else - return NULL; - } - } - - /* Use PVR demuxer only for live streams */ - if (URIUtils::IsPVRChannel(pInputStream->GetFileName())) - { - std::shared_ptr client; - if (g_PVRClients->GetPlayingClient(client) && - client->HandlesDemuxing()) - { - unique_ptr demuxer(new CDVDDemuxPVRClient()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } - } - } - - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) - { - bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); - streaminfo = !useFastswitch; - } - - unique_ptr demuxer(new CDVDDemuxFFmpeg()); - if(demuxer->Open(pInputStream, streaminfo, fileinfo)) - return demuxer.release(); - else - return NULL; -} - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h deleted file mode 100644 index 8281d28..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-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 - * . - * - */ - -class CDVDDemux; -class CDVDInputStream; - -class CDVDFactoryDemuxer -{ -public: - static CDVDDemux* CreateDemuxer(CDVDInputStream* pInputStream, bool fileinfo = false); -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in b/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in deleted file mode 100644 index 98493fe..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in +++ /dev/null @@ -1,19 +0,0 @@ -INCLUDES+=-I@abs_top_srcdir@/xbmc/cores/dvdplayer - -SRCS = DVDDemux.cpp -SRCS += DVDDemuxBXA.cpp -SRCS += DVDDemuxCDDA.cpp -SRCS += DVDDemuxFFmpeg.cpp -SRCS += DVDDemuxHTSP.cpp -SRCS += DVDDemuxPVRClient.cpp -SRCS += DVDDemuxShoutcast.cpp -SRCS += DVDDemuxUtils.cpp -SRCS += DVDDemuxVobsub.cpp -SRCS += DVDDemuxCC.cpp -SRCS += DVDFactoryDemuxer.cpp - -LIB = DVDDemuxers.a - -include @abs_top_srcdir@/Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) - -- cgit v1.2.3