#pragma once
/*
* Copyright (C) 2005-2017 Team Kodi
* http://kodi.tv
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 Kodi; see the file COPYING. If not, see
* .
*
*/
#include "../AddonBase.h"
namespace kodi { namespace addon { class CInstanceScreensaver; }}
extern "C"
{
struct AddonInstance_Screensaver;
/*!
* @brief Screensaver properties
*
* Not to be used outside this header.
*/
typedef struct AddonProps_Screensaver
{
void *device;
int x;
int y;
int width;
int height;
float pixelRatio;
const char *name;
const char *presets;
const char *profile;
} AddonProps_Screensaver;
/*!
* @brief Screensaver callbacks
*
* Not to be used outside this header.
*/
typedef struct AddonToKodiFuncTable_Screensaver
{
KODI_HANDLE kodiInstance;
} AddonToKodiFuncTable_Screensaver;
/*!
* @brief Screensaver function hooks
*
* Not to be used outside this header.
*/
typedef struct KodiToAddonFuncTable_Screensaver
{
kodi::addon::CInstanceScreensaver* addonInstance;
bool (__cdecl* Start) (AddonInstance_Screensaver* instance);
void (__cdecl* Stop) (AddonInstance_Screensaver* instance);
void (__cdecl* Render) (AddonInstance_Screensaver* instance);
} KodiToAddonFuncTable_Screensaver;
/*!
* @brief Screensaver instance
*
* Not to be used outside this header.
*/
typedef struct AddonInstance_Screensaver
{
AddonProps_Screensaver props;
AddonToKodiFuncTable_Screensaver toKodi;
KodiToAddonFuncTable_Screensaver toAddon;
} AddonInstance_Screensaver;
} /* extern "C" */
namespace kodi
{
namespace addon
{
//============================================================================
///
/// \addtogroup cpp_kodi_addon_screensaver
/// @brief \cpp_class{ kodi::addon::CInstanceScreensaver }
/// **Screensaver add-on instance**
///
/// A screensaver is a Kodi addon that fills the screen with moving images or
/// patterns when the computer is not in use. Initially designed to prevent
/// phosphor burn-in on CRT and plasma computer monitors (hence the name),
/// screensavers are now used primarily for entertainment, security or to
/// display system status information.
///
/// Include the header \ref ScreenSaver.h "#include "
/// to use this class.
///
/// This interface allows the creating of screensavers for Kodi, based upon
/// **DirectX** or/and **OpenGL** rendering with `C++` code.
///
/// The interface is small and easy usable. It has three functions:
///
/// * Start() - Called on creation
/// * Render() - Called at render time
/// * Stop() - Called when the screensaver has no work
///
/// Additionally, there are several \ref cpp_kodi_addon_screensaver_CB "other functions"
/// available in which the child class can ask about the current hardware,
/// including the device, display and several other parts.
///
///
/// --------------------------------------------------------------------------
///
///
/// **Here is an example of the minimum required code to start a screensaver:**
/// ~~~~~~~~~~~~~{.cpp}
/// #include
///
/// class CMyScreenSaver : public kodi::addon::CAddonBase,
/// public kodi::addon::CInstanceScreensaver
/// {
/// public:
/// CMyScreenSaver();
///
/// bool Start() override;
/// void Render() override;
/// };
///
/// CMyScreenSaver::CMyScreenSaver()
/// {
/// ...
/// }
///
/// bool CMyScreenSaver::Start()
/// {
/// ...
/// return true;
/// }
///
/// void CMyScreenSaver::Render()
/// {
/// ...
/// }
///
/// ADDONCREATOR(CMyScreenSaver)
/// ~~~~~~~~~~~~~
///
///
/// --------------------------------------------------------------------------
///
///
/// **Here is another example where the screensaver is used together with
/// other instance types:**
///
/// ~~~~~~~~~~~~~{.cpp}
/// #include
///
/// class CMyScreenSaver : public ::kodi::addon::CInstanceScreensaver
/// {
/// public:
/// CMyScreenSaver(KODI_HANDLE instance);
///
/// bool Start() override;
/// void Render() override;
/// };
///
/// CMyScreenSaver::CMyScreenSaver(KODI_HANDLE instance)
/// : CInstanceScreensaver(instance)
/// {
/// ...
/// }
///
/// bool CMyScreenSaver::Start()
/// {
/// ...
/// return true;
/// }
///
/// void CMyScreenSaver::Render()
/// {
/// ...
/// }
///
///
/// /*----------------------------------------------------------------------*/
///
/// class CMyAddon : public ::kodi::addon::CAddonBase
/// {
/// public:
/// CMyAddon() { }
/// ADDON_STATUS CreateInstance(int instanceType,
/// std::string instanceID,
/// KODI_HANDLE instance,
/// KODI_HANDLE& addonInstance) override;
/// };
///
/// /* If you use only one instance in your add-on, can be instanceType and
/// * instanceID ignored */
/// ADDON_STATUS CMyAddon::CreateInstance(int instanceType,
/// std::string instanceID,
/// KODI_HANDLE instance,
/// KODI_HANDLE& addonInstance)
/// {
/// if (instanceType == ADDON_INSTANCE_SCREENSAVER)
/// {
/// kodi::Log(ADDON_LOG_NOTICE, "Creating my Screensaver");
/// addonInstance = new CMyScreenSaver(instance);
/// return ADDON_STATUS_OK;
/// }
/// else if (...)
/// {
/// ...
/// }
/// return ADDON_STATUS_UNKNOWN;
/// }
///
/// ADDONCREATOR(CMyAddon)
/// ~~~~~~~~~~~~~
///
/// The destruction of the example class `CMyScreenSaver` is called from
/// Kodi's header. Manually deleting the add-on instance is not required.
///
//----------------------------------------------------------------------------
class CInstanceScreensaver : public IAddonInstance
{
public:
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver
/// @brief Screensaver class constructor
///
/// Used by an add-on that only supports screensavers.
///
CInstanceScreensaver()
: IAddonInstance(ADDON_INSTANCE_SCREENSAVER)
{
if (CAddonBase::m_interface->globalSingleInstance != nullptr)
throw std::logic_error("kodi::addon::CInstanceScreensaver: Creation of more as one in single instance way is not allowed!");
SetAddonStruct(CAddonBase::m_interface->firstKodiInstance);
CAddonBase::m_interface->globalSingleInstance = this;
}
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver
/// @brief Screensaver class constructor used to support multiple instance
/// types
///
/// @param[in] instance The instance value given to
/// `kodi::addon::CAddonBase::CreateInstance(...)`.
///
/// @warning Only use `instance` from the CreateInstance call
///
CInstanceScreensaver(KODI_HANDLE instance)
: IAddonInstance(ADDON_INSTANCE_SCREENSAVER)
{
if (CAddonBase::m_interface->globalSingleInstance != nullptr)
throw std::logic_error("kodi::addon::CInstanceScreensaver: Creation of multiple together with single instance way is not allowed!");
SetAddonStruct(instance);
}
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver
/// @brief Destructor
///
~CInstanceScreensaver() override = default;
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver
/// @brief Used to notify the screensaver that it has been started
///
/// @return true if the screensaver was started
/// successfully, false otherwise
///
virtual bool Start() { return true; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver
/// @brief Used to inform the screensaver that the rendering control was
/// stopped
///
virtual void Stop() {}
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver
/// @brief Used to indicate when the add-on should render
///
virtual void Render() {}
//--------------------------------------------------------------------------
//==========================================================================
///
/// \defgroup cpp_kodi_addon_screensaver_CB Information functions
/// \ingroup cpp_kodi_addon_screensaver
/// @brief **To get info about the device, display and several other parts**
///
//@{
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Device that represents the display adapter
///
/// @return A pointer to the device
///
/// @note This is only available on **DirectX**, It us unused (`nullptr`) on
/// **OpenGL**
///
inline void* Device() { return m_instanceData->props.device; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Returns the X position of the rendering window
///
/// @return The X position, in pixels
///
inline int X() { return m_instanceData->props.x; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Returns the Y position of the rendering window
///
/// @return The Y position, in pixels
///
inline int Y() { return m_instanceData->props.y; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Returns the width of the rendering window
///
/// @return The width, in pixels
///
inline int Width() { return m_instanceData->props.width; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Returns the height of the rendering window
///
/// @return The height, in pixels
///
inline int Height() { return m_instanceData->props.height; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Pixel aspect ratio (often abbreviated PAR) is a ratio that
/// describes how the width of a pixel compares to the height of that pixel.
///
/// @return The pixel aspect ratio used by the display
///
inline float PixelRatio() { return m_instanceData->props.pixelRatio; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Used to get the name of the add-on defined in `addon.xml`
///
/// @return The add-on name
///
inline std::string Name() { return m_instanceData->props.name; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Used to get the full path where the add-on is installed
///
/// @return The add-on installation path
///
inline std::string Presets() { return m_instanceData->props.presets; }
//--------------------------------------------------------------------------
//==========================================================================
///
/// @ingroup cpp_kodi_addon_screensaver_CB
/// @brief Used to get the full path to the add-on's user profile
///
/// @note The trailing folder (consisting of the add-on's ID) is not created
/// by default. If it is needed, you must call kodi::vfs::CreateDirectory()
/// to create the folder.
///
/// @return Path to the user profile
///
inline std::string Profile() { return m_instanceData->props.profile; }
//--------------------------------------------------------------------------
//@}
private:
void SetAddonStruct(KODI_HANDLE instance)
{
if (instance == nullptr)
throw std::logic_error("kodi::addon::CInstanceScreensaver: Creation with empty addon structure not allowed, table must be given from Kodi!");
m_instanceData = static_cast(instance);
m_instanceData->toAddon.addonInstance = this;
m_instanceData->toAddon.Start = ADDON_Start;
m_instanceData->toAddon.Stop = ADDON_Stop;
m_instanceData->toAddon.Render = ADDON_Render;
}
inline static bool ADDON_Start(AddonInstance_Screensaver* instance)
{
return instance->toAddon.addonInstance->Start();
}
inline static void ADDON_Stop(AddonInstance_Screensaver* instance)
{
instance->toAddon.addonInstance->Stop();
}
inline static void ADDON_Render(AddonInstance_Screensaver* instance)
{
instance->toAddon.addonInstance->Render();
}
AddonInstance_Screensaver* m_instanceData;
};
} /* namespace addon */
} /* namespace kodi */