summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/interfaces/General.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /xbmc/addons/interfaces/General.cpp
parentInitial commit. (diff)
downloadkodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz
kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/addons/interfaces/General.cpp')
-rw-r--r--xbmc/addons/interfaces/General.cpp468
1 files changed, 468 insertions, 0 deletions
diff --git a/xbmc/addons/interfaces/General.cpp b/xbmc/addons/interfaces/General.cpp
new file mode 100644
index 0000000..eef6ccd
--- /dev/null
+++ b/xbmc/addons/interfaces/General.cpp
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "General.h"
+
+#include "CompileInfo.h"
+#include "LangInfo.h"
+#include "ServiceBroker.h"
+#include "addons/AddonManager.h"
+#include "addons/AddonVersion.h"
+#include "addons/binary-addons/AddonDll.h"
+#include "addons/kodi-dev-kit/include/kodi/General.h"
+#include "application/ApplicationComponents.h"
+#include "application/ApplicationPowerHandling.h"
+#include "dialogs/GUIDialogKaiToast.h"
+#include "input/KeyboardLayout.h"
+#include "input/KeyboardLayoutManager.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "utils/CharsetConverter.h"
+#include "utils/Digest.h"
+#include "utils/LangCodeExpander.h"
+#include "utils/MemUtils.h"
+#include "utils/StringUtils.h"
+#include "utils/log.h"
+
+#include <string.h>
+
+using namespace kodi; // addon-dev-kit namespace
+using KODI::UTILITY::CDigest;
+
+namespace ADDON
+{
+
+void Interface_General::Init(AddonGlobalInterface* addonInterface)
+{
+ addonInterface->toKodi->kodi = static_cast<AddonToKodiFuncTable_kodi*>(malloc(sizeof(AddonToKodiFuncTable_kodi)));
+
+ addonInterface->toKodi->kodi->unknown_to_utf8 = unknown_to_utf8;
+ addonInterface->toKodi->kodi->get_language = get_language;
+ addonInterface->toKodi->kodi->queue_notification = queue_notification;
+ addonInterface->toKodi->kodi->get_md5 = get_md5;
+ addonInterface->toKodi->kodi->get_region = get_region;
+ addonInterface->toKodi->kodi->get_free_mem = get_free_mem;
+ addonInterface->toKodi->kodi->get_global_idle_time = get_global_idle_time;
+ addonInterface->toKodi->kodi->is_addon_avilable = is_addon_avilable;
+ addonInterface->toKodi->kodi->kodi_version = kodi_version;
+ addonInterface->toKodi->kodi->get_current_skin_id = get_current_skin_id;
+ addonInterface->toKodi->kodi->get_keyboard_layout = get_keyboard_layout;
+ addonInterface->toKodi->kodi->change_keyboard_layout = change_keyboard_layout;
+}
+
+void Interface_General::DeInit(AddonGlobalInterface* addonInterface)
+{
+ if (addonInterface->toKodi && /* <-- needed as long as the old addon way is used */
+ addonInterface->toKodi->kodi)
+ {
+ free(addonInterface->toKodi->kodi);
+ addonInterface->toKodi->kodi = nullptr;
+ }
+}
+
+char* Interface_General::unknown_to_utf8(void* kodiBase, const char* source, bool* ret, bool failOnBadChar)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (!addon || !source || !ret)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', source='{}', ret='{}')",
+ __FUNCTION__, kodiBase, static_cast<const void*>(source), static_cast<void*>(ret));
+ return nullptr;
+ }
+
+ std::string string;
+ *ret = g_charsetConverter.unknownToUTF8(source, string, failOnBadChar);
+ char* buffer = strdup(string.c_str());
+ return buffer;
+}
+
+char* Interface_General::get_language(void* kodiBase, int format, bool region)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (!addon)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}')", __FUNCTION__,
+ kodiBase);
+ return nullptr;
+ }
+
+ std::string string = g_langInfo.GetEnglishLanguageName();
+ switch (format)
+ {
+ case LANG_FMT_ISO_639_1:
+ {
+ std::string langCode;
+ g_LangCodeExpander.ConvertToISO6391(string, langCode);
+ string = langCode;
+ if (region)
+ {
+ std::string region2Code;
+ g_LangCodeExpander.ConvertToISO6391(g_langInfo.GetRegionLocale(), region2Code);
+ if (!region2Code.empty())
+ string += "-" + region2Code;
+ }
+ break;
+ }
+ case LANG_FMT_ISO_639_2:
+ {
+ std::string langCode;
+ g_LangCodeExpander.ConvertToISO6392B(string, langCode);
+ string = langCode;
+ if (region)
+ {
+ std::string region3Code;
+ g_LangCodeExpander.ConvertToISO6392B(g_langInfo.GetRegionLocale(), region3Code);
+ if (!region3Code.empty())
+ string += "-" + region3Code;
+ }
+ break;
+ }
+ case LANG_FMT_ENGLISH_NAME:
+ default:
+ {
+ if (region)
+ string += "-" + g_langInfo.GetCurrentRegion();
+ break;
+ }
+ }
+
+ char* buffer = strdup(string.c_str());
+ return buffer;
+}
+
+bool Interface_General::queue_notification(void* kodiBase, int type, const char* header,
+ const char* message, const char* imageFile,
+ unsigned int displayTime, bool withSound,
+ unsigned int messageTime)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || message == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', message='{}')",
+ __FUNCTION__, kodiBase, static_cast<const void*>(message));
+ return false;
+ }
+
+ std::string usedHeader;
+ if (header && strlen(header) > 0)
+ usedHeader = header;
+ else
+ usedHeader = addon->Name();
+
+ QueueMsg qtype = static_cast<QueueMsg>(type);
+
+ if (qtype != QUEUE_OWN_STYLE)
+ {
+ CGUIDialogKaiToast::eMessageType usedType;
+ switch (qtype)
+ {
+ case QueueMsg::QUEUE_WARNING:
+ usedType = CGUIDialogKaiToast::Warning;
+ withSound = true;
+ CLog::Log(LOGDEBUG, "Interface_General::{} - {} - Warning Message: '{}'", __FUNCTION__,
+ addon->Name(), message);
+ break;
+ case QueueMsg::QUEUE_ERROR:
+ usedType = CGUIDialogKaiToast::Error;
+ withSound = true;
+ CLog::Log(LOGDEBUG, "Interface_General::{} - {} - Error Message : '{}'", __FUNCTION__,
+ addon->Name(), message);
+ break;
+ case QueueMsg::QUEUE_INFO:
+ default:
+ usedType = CGUIDialogKaiToast::Info;
+ withSound = false;
+ CLog::Log(LOGDEBUG, "Interface_General::{} - {} - Info Message : '{}'", __FUNCTION__,
+ addon->Name(), message);
+ break;
+ }
+
+ if (imageFile && strlen(imageFile) > 0)
+ {
+ CLog::Log(LOGERROR,
+ "Interface_General::{} - To use given image file '{}' must be type value set to "
+ "'QUEUE_OWN_STYLE'",
+ __FUNCTION__, imageFile);
+ }
+
+ CGUIDialogKaiToast::QueueNotification(usedType, usedHeader, message, 3000, withSound);
+ }
+ else
+ {
+ CGUIDialogKaiToast::QueueNotification(imageFile, usedHeader, message, displayTime, withSound, messageTime);
+ }
+ return true;
+}
+
+void Interface_General::get_md5(void* kodiBase, const char* text, char* md5)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || text == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', text='{}')",
+ __FUNCTION__, kodiBase, static_cast<const void*>(text));
+ return;
+ }
+
+ std::string md5Int = CDigest::Calculate(CDigest::Type::MD5, std::string(text));
+ strncpy(md5, md5Int.c_str(), 40);
+}
+
+char* Interface_General::get_region(void* kodiBase, const char* id)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || id == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', id='{}')", __FUNCTION__,
+ kodiBase, static_cast<const void*>(id));
+ return nullptr;
+ }
+
+ std::string result;
+ if (StringUtils::CompareNoCase(id, "datelong") == 0)
+ {
+ result = g_langInfo.GetDateFormat(true);
+ StringUtils::Replace(result, "DDDD", "%A");
+ StringUtils::Replace(result, "MMMM", "%B");
+ StringUtils::Replace(result, "D", "%d");
+ StringUtils::Replace(result, "YYYY", "%Y");
+ }
+ else if (StringUtils::CompareNoCase(id, "dateshort") == 0)
+ {
+ result = g_langInfo.GetDateFormat(false);
+ StringUtils::Replace(result, "MM", "%m");
+ StringUtils::Replace(result, "DD", "%d");
+#ifdef TARGET_WINDOWS
+ StringUtils::Replace(result, "M", "%#m");
+ StringUtils::Replace(result, "D", "%#d");
+#else
+ StringUtils::Replace(result, "M", "%-m");
+ StringUtils::Replace(result, "D", "%-d");
+#endif
+ StringUtils::Replace(result, "YYYY", "%Y");
+ }
+ else if (StringUtils::CompareNoCase(id, "tempunit") == 0)
+ result = g_langInfo.GetTemperatureUnitString();
+ else if (StringUtils::CompareNoCase(id, "speedunit") == 0)
+ result = g_langInfo.GetSpeedUnitString();
+ else if (StringUtils::CompareNoCase(id, "time") == 0)
+ {
+ result = g_langInfo.GetTimeFormat();
+ StringUtils::Replace(result, "H", "%H");
+ StringUtils::Replace(result, "h", "%I");
+ StringUtils::Replace(result, "mm", "%M");
+ StringUtils::Replace(result, "ss", "%S");
+ StringUtils::Replace(result, "xx", "%p");
+ }
+ else if (StringUtils::CompareNoCase(id, "meridiem") == 0)
+ result = StringUtils::Format("{}/{}", g_langInfo.GetMeridiemSymbol(MeridiemSymbolAM),
+ g_langInfo.GetMeridiemSymbol(MeridiemSymbolPM));
+ else
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - add-on '{}' requests invalid id '{}'",
+ __FUNCTION__, addon->Name(), id);
+ return nullptr;
+ }
+
+ char* buffer = strdup(result.c_str());
+ return buffer;
+}
+
+void Interface_General::get_free_mem(void* kodiBase, long* free, long* total, bool as_bytes)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || free == nullptr || total == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', free='{}', total='{}')",
+ __FUNCTION__, kodiBase, static_cast<void*>(free), static_cast<void*>(total));
+ return;
+ }
+
+ KODI::MEMORY::MemoryStatus stat;
+ KODI::MEMORY::GetMemoryStatus(&stat);
+ *free = static_cast<long>(stat.availPhys);
+ *total = static_cast<long>(stat.totalPhys);
+ if (!as_bytes)
+ {
+ *free = *free / ( 1024 * 1024 );
+ *total = *total / ( 1024 * 1024 );
+ }
+}
+
+int Interface_General::get_global_idle_time(void* kodiBase)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}')", __FUNCTION__,
+ kodiBase);
+ return -1;
+ }
+
+ auto& components = CServiceBroker::GetAppComponents();
+ const auto appPower = components.GetComponent<CApplicationPowerHandling>();
+ return appPower->GlobalIdleTime();
+}
+
+bool Interface_General::is_addon_avilable(void* kodiBase,
+ const char* id,
+ char** version,
+ bool* enabled)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || id == nullptr || version == nullptr || enabled == nullptr)
+ {
+ CLog::Log(
+ LOGERROR,
+ "Interface_General::{} - invalid data (addon='{}', id='{}', version='{}', enabled='{}')",
+ __FUNCTION__, kodiBase, static_cast<const void*>(id), static_cast<void*>(version),
+ static_cast<void*>(enabled));
+ return false;
+ }
+
+ AddonPtr addonInfo;
+ if (!CServiceBroker::GetAddonMgr().GetAddon(id, addonInfo, OnlyEnabled::CHOICE_NO))
+ return false;
+
+ *version = strdup(addonInfo->Version().asString().c_str());
+ *enabled = !CServiceBroker::GetAddonMgr().IsAddonDisabled(id);
+ return true;
+}
+
+void Interface_General::kodi_version(void* kodiBase, char** compile_name, int* major, int* minor, char** revision, char** tag, char** tagversion)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || compile_name == nullptr || major == nullptr || minor == nullptr ||
+ revision == nullptr || tag == nullptr || tagversion == nullptr)
+ {
+ CLog::Log(LOGERROR,
+ "Interface_General::{} - invalid data (addon='{}', compile_name='{}', major='{}', "
+ "minor='{}', revision='{}', tag='{}', tagversion='{}')",
+ __FUNCTION__, kodiBase, static_cast<void*>(compile_name), static_cast<void*>(major),
+ static_cast<void*>(minor), static_cast<void*>(revision), static_cast<void*>(tag),
+ static_cast<void*>(tagversion));
+ return;
+ }
+
+ *compile_name = strdup(CCompileInfo::GetAppName());
+ *major = CCompileInfo::GetMajor();
+ *minor = CCompileInfo::GetMinor();
+ *revision = strdup(CCompileInfo::GetSCMID());
+ std::string tagStr = CCompileInfo::GetSuffix();
+ if (StringUtils::StartsWithNoCase(tagStr, "alpha"))
+ {
+ *tag = strdup("alpha");
+ *tagversion = strdup(StringUtils::Mid(tagStr, 5).c_str());
+ }
+ else if (StringUtils::StartsWithNoCase(tagStr, "beta"))
+ {
+ *tag = strdup("beta");
+ *tagversion = strdup(StringUtils::Mid(tagStr, 4).c_str());
+ }
+ else if (StringUtils::StartsWithNoCase(tagStr, "rc"))
+ {
+ *tag = strdup("releasecandidate");
+ *tagversion = strdup(StringUtils::Mid(tagStr, 2).c_str());
+ }
+ else if (tagStr.empty())
+ *tag = strdup("stable");
+ else
+ *tag = strdup("prealpha");
+}
+
+char* Interface_General::get_current_skin_id(void* kodiBase)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}')", __FUNCTION__,
+ kodiBase);
+ return nullptr;
+ }
+
+ return strdup(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN).c_str());
+}
+
+bool Interface_General::get_keyboard_layout(void* kodiBase, char** layout_name, int modifier_key, AddonKeyboardKeyTable* c_layout)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || c_layout == nullptr || layout_name == nullptr)
+ {
+ CLog::Log(LOGERROR,
+ "Interface_General::{} - invalid data (addon='{}', c_layout='{}', layout_name='{}')",
+ __FUNCTION__, kodiBase, static_cast<void*>(c_layout),
+ static_cast<void*>(layout_name));
+ return false;
+ }
+
+ std::string activeLayout = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT);
+
+ CKeyboardLayout layout;
+ if (!CServiceBroker::GetKeyboardLayoutManager()->GetLayout(activeLayout, layout))
+ return false;
+
+ *layout_name = strdup(layout.GetName().c_str());
+
+ unsigned int modifiers = CKeyboardLayout::ModifierKeyNone;
+ if (modifier_key & STD_KB_MODIFIER_KEY_SHIFT)
+ modifiers |= CKeyboardLayout::ModifierKeyShift;
+ if (modifier_key & STD_KB_MODIFIER_KEY_SYMBOL)
+ modifiers |= CKeyboardLayout::ModifierKeySymbol;
+
+ for (unsigned int row = 0; row < STD_KB_BUTTONS_MAX_ROWS; row++)
+ {
+ for (unsigned int column = 0; column < STD_KB_BUTTONS_PER_ROW; column++)
+ {
+ std::string label = layout.GetCharAt(row, column, modifiers);
+ c_layout->keys[row][column] = strdup(label.c_str());
+ }
+ }
+
+ return true;
+}
+
+bool Interface_General::change_keyboard_layout(void* kodiBase, char** layout_name)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || layout_name == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', layout_name='{}')",
+ __FUNCTION__, kodiBase, static_cast<void*>(layout_name));
+ return false;
+ }
+
+ std::vector<CKeyboardLayout> layouts;
+ unsigned int currentLayout = 0;
+
+ const KeyboardLayouts& keyboardLayouts = CServiceBroker::GetKeyboardLayoutManager()->GetLayouts();
+ const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
+ std::vector<CVariant> layoutNames = settings->GetList(CSettings::SETTING_LOCALE_KEYBOARDLAYOUTS);
+ std::string activeLayout = settings->GetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT);
+
+ for (const auto& layoutName : layoutNames)
+ {
+ const auto keyboardLayout = keyboardLayouts.find(layoutName.asString());
+ if (keyboardLayout != keyboardLayouts.end())
+ {
+ layouts.emplace_back(keyboardLayout->second);
+ if (layoutName.asString() == activeLayout)
+ currentLayout = layouts.size() - 1;
+ }
+ }
+
+ currentLayout++;
+ if (currentLayout >= layouts.size())
+ currentLayout = 0;
+ CKeyboardLayout layout = layouts.empty() ? CKeyboardLayout() : layouts[currentLayout];
+ CServiceBroker::GetSettingsComponent()->GetSettings()->SetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT, layout.GetName());
+
+ *layout_name = strdup(layout.GetName().c_str());
+ return true;
+}
+
+} /* namespace ADDON */