From 0afb1d4d51973cf52973617c92236d851a039d31 Mon Sep 17 00:00:00 2001 From: manuel Date: Sat, 2 Sep 2017 15:02:54 +0200 Subject: sync with upstream --- .../kodi-addon-dev-kit/include/kodi/AudioEngine.h | 145 ++++++++++-------- .../kodi-addon-dev-kit/include/kodi/Filesystem.h | 81 +++++++++- .../include/kodi/addon-instance/AudioDecoder.h | 2 +- .../include/kodi/addon-instance/AudioEncoder.h | 2 +- .../include/kodi/addon-instance/ImageDecoder.h | 2 +- .../include/kodi/addon-instance/Inputstream.h | 29 +++- .../include/kodi/addon-instance/Peripheral.h | 2 +- .../include/kodi/addon-instance/PeripheralUtils.h | 12 +- .../include/kodi/addon-instance/Screensaver.h | 2 +- .../include/kodi/addon-instance/VFS.h | 6 +- .../include/kodi/addon-instance/VideoCodec.h | 2 +- .../include/kodi/addon-instance/Visualization.h | 2 +- .../kodi-addon-dev-kit/include/kodi/gui/ListItem.h | 4 +- .../kodi-addon-dev-kit/include/kodi/gui/Window.h | 4 + .../include/kodi/gui/definitions.h | 2 + .../include/kodi/gui/dialogs/ContextMenu.h | 94 ++++++++++++ .../include/kodi/gui/dialogs/ExtendedProgress.h | 2 +- .../include/kodi/gui/dialogs/Keyboard.h | 24 +-- .../include/kodi/gui/dialogs/Numeric.h | 15 +- .../include/kodi/gui/dialogs/Select.h | 165 +++++++++++++++++++++ .../include/kodi/libXBMC_addon.h | 13 ++ .../kodi-addon-dev-kit/include/kodi/libXBMC_pvr.h | 5 +- .../kodi-addon-dev-kit/include/kodi/versions.h | 25 ++-- .../include/kodi/xbmc_epg_types.h | 2 +- .../kodi-addon-dev-kit/include/kodi/xbmc_pvr_dll.h | 38 ++++- .../include/kodi/xbmc_pvr_types.h | 12 +- 26 files changed, 552 insertions(+), 140 deletions(-) (limited to 'xbmc/addons/kodi-addon-dev-kit/include') diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/AudioEngine.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/AudioEngine.h index 1265dcd..02faf86 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/AudioEngine.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/AudioEngine.h @@ -139,7 +139,7 @@ extern "C" } } - return true; + return true; } }; //@} @@ -154,33 +154,34 @@ extern "C" */ typedef struct AddonToKodiFuncTable_kodi_audioengine { - AEStreamHandle* (*MakeStream) (void *kodiBase, AudioEngineFormat format, unsigned int options); - void (*FreeStream) (void *kodiBase, AEStreamHandle *stream); - bool (*GetCurrentSinkFormat) (void *kodiBase, AudioEngineFormat *SinkFormat); + AEStreamHandle* (*make_stream)(void *kodiBase, AudioEngineFormat* format, unsigned int options); + void (*free_stream)(void *kodiBase, AEStreamHandle *stream); + bool (*get_current_sink_format)(void *kodiBase, AudioEngineFormat* sink_format); // Audio Engine Stream definitions - unsigned int (*AEStream_GetSpace) (void *kodiBase, AEStreamHandle *handle); - unsigned int (*AEStream_AddData) (void *kodiBase, AEStreamHandle *handle, uint8_t* const *Data, unsigned int Offset, unsigned int Frames); - double (*AEStream_GetDelay)(void *kodiBase, AEStreamHandle *handle); - bool (*AEStream_IsBuffering)(void *kodiBase, AEStreamHandle *handle); - double (*AEStream_GetCacheTime)(void *kodiBase, AEStreamHandle *handle); - double (*AEStream_GetCacheTotal)(void *kodiBase, AEStreamHandle *handle); - void (*AEStream_Pause)(void *kodiBase, AEStreamHandle *handle); - void (*AEStream_Resume)(void *kodiBase, AEStreamHandle *handle); - void (*AEStream_Drain)(void *kodiBase, AEStreamHandle *handle, bool Wait); - bool (*AEStream_IsDraining)(void *kodiBase, AEStreamHandle *handle); - bool (*AEStream_IsDrained)(void *kodiBase, AEStreamHandle *handle); - void (*AEStream_Flush)(void *kodiBase, AEStreamHandle *handle); - float (*AEStream_GetVolume)(void *kodiBase, AEStreamHandle *handle); - void (*AEStream_SetVolume)(void *kodiBase, AEStreamHandle *handle, float Volume); - float (*AEStream_GetAmplification)(void *kodiBase, AEStreamHandle *handle); - void (*AEStream_SetAmplification)(void *kodiBase, AEStreamHandle *handle, float Amplify); - unsigned int (*AEStream_GetFrameSize)(void *kodiBase, AEStreamHandle *handle); - unsigned int (*AEStream_GetChannelCount)(void *kodiBase, AEStreamHandle *handle); - unsigned int (*AEStream_GetSampleRate)(void *kodiBase, AEStreamHandle *handle); - AEDataFormat (*AEStream_GetDataFormat)(void *kodiBase, AEStreamHandle *handle); - double (*AEStream_GetResampleRatio)(void *kodiBase, AEStreamHandle *handle); - void (*AEStream_SetResampleRatio)(void *kodiBase, AEStreamHandle *handle, double Ratio); + unsigned int (*aestream_get_space)(void *kodiBase, AEStreamHandle *handle); + unsigned int (*aestream_add_data)(void *kodiBase, AEStreamHandle *handle, uint8_t* const *data, + unsigned int offset, unsigned int frames, double pts); + double (*aestream_get_delay)(void *kodiBase, AEStreamHandle *handle); + bool (*aestream_is_buffering)(void *kodiBase, AEStreamHandle *handle); + double (*aestream_get_cache_time)(void *kodiBase, AEStreamHandle *handle); + double (*aestream_get_cache_total)(void *kodiBase, AEStreamHandle *handle); + void (*aestream_pause)(void *kodiBase, AEStreamHandle *handle); + void (*aestream_resume)(void *kodiBase, AEStreamHandle *handle); + void (*aestream_drain)(void *kodiBase, AEStreamHandle *handle, bool wait); + bool (*aestream_is_draining)(void *kodiBase, AEStreamHandle *handle); + bool (*aestream_is_drained)(void *kodiBase, AEStreamHandle *handle); + void (*aestream_flush)(void *kodiBase, AEStreamHandle *handle); + float (*aestream_get_volume)(void *kodiBase, AEStreamHandle *handle); + void (*aestream_set_volume)(void *kodiBase, AEStreamHandle *handle, float volume); + float (*aestream_get_amplification)(void *kodiBase, AEStreamHandle *handle); + void (*aestream_set_amplification)(void *kodiBase, AEStreamHandle *handle, float amplify); + unsigned int (*aestream_get_frame_size)(void *kodiBase, AEStreamHandle *handle); + unsigned int (*aestream_get_channel_count)(void *kodiBase, AEStreamHandle *handle); + unsigned int (*aestream_get_sample_rate)(void *kodiBase, AEStreamHandle *handle); + AEDataFormat (*aestream_get_data_format)(void *kodiBase, AEStreamHandle *handle); + double (*aestream_get_resample_ratio)(void *kodiBase, AEStreamHandle *handle); + void (*aestream_set_resample_ratio)(void *kodiBase, AEStreamHandle *handle, double ratio); } AddonToKodiFuncTable_kodi_audioengine; } /* extern "C" */ @@ -242,12 +243,12 @@ namespace audioengine /// /// **Bit options to pass to CAELib_Stream (on Kodi by IAE::MakeStream)** /// - /// | enum AEStreamOptions | Value: | Description: - /// |-------------------------:|:------:|:----------------------------------- - /// | AE_STREAM_FORCE_RESAMPLE | 1 << 0 | Force resample even if rates match - /// | AE_STREAM_PAUSED | 1 << 1 | Create the stream paused - /// | AE_STREAM_AUTOSTART | 1 << 2 | Autostart the stream when enough data is buffered - /// | AE_STREAM_BYPASS_ADSP | 1 << 3 | if this option is set the ADSP-System is bypassed and the raw stream will be passed through IAESink. + /// | enum AEStreamOptions | Value: | Description: + /// |----------------------------:|:------:|:----------------------------------- + /// | AUDIO_STREAM_FORCE_RESAMPLE | 1 << 0 | Force resample even if rates match + /// | AUDIO_STREAM_PAUSED | 1 << 1 | Create the stream paused + /// | AUDIO_STREAM_AUTOSTART | 1 << 2 | Autostart the stream when enough data is buffered + /// | AUDIO_STREAM_BYPASS_ADSP | 1 << 3 | if this option is set the ADSP-System is bypassed and the raw stream will be passed through IAESink. /// /// /// ------------------------------------------------------------------------ @@ -261,7 +262,16 @@ namespace audioengine /// /// ... /// - /// CAddonAEStream* stream = new CAddonAEStream(AE_FMT_S16LE, AE_STREAM_AUTOSTART | AE_STREAM_BYPASS_ADSP); + /// AudioEngineFormat format; + /// format.m_dataFormat = AE_FMT_FLOAT; + /// format.m_channelCount = 2; + /// format.m_channels[0] = AE_CH_FL; + /// format.m_channels[1] = AE_CH_FR; + /// format.m_channels[2] = AE_CH_NULL; + /// format.m_sampleRate = 48000; + /// format.m_frameSize = sizeof(float)*format.m_channelCount; + /// format.m_frames = 512; + /// CAddonAEStream* stream = new CAddonAEStream(format, AE_STREAM_AUTOSTART | AE_STREAM_BYPASS_ADSP); /// /// ~~~~~~~~~~~~~ /// @@ -269,22 +279,27 @@ namespace audioengine : m_kodiBase(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase), m_cb(::kodi::addon::CAddonBase::m_interface->toKodi->kodi_audioengine) { - m_StreamHandle = m_cb->MakeStream(m_kodiBase, format, options); + m_StreamHandle = m_cb->make_stream(m_kodiBase, &format, options); if (m_StreamHandle == nullptr) { - kodi::Log(ADDON_LOG_FATAL, "CAddonAEStream: MakeStream failed!"); + kodi::Log(ADDON_LOG_FATAL, "CAddonAEStream: make_stream failed!"); } } //-------------------------------------------------------------------------- + //========================================================================== + /// @ingroup cpp_kodi_audioengine_CAddonAEStream + /// @brief Class destructor + /// ~CAddonAEStream() { if (m_StreamHandle) { - m_cb->FreeStream(m_kodiBase, m_StreamHandle); + m_cb->free_stream(m_kodiBase, m_StreamHandle); m_StreamHandle = nullptr; } } + //-------------------------------------------------------------------------- //========================================================================== /// @ingroup cpp_kodi_audioengine_CAddonAEStream @@ -294,7 +309,7 @@ namespace audioengine /// unsigned int GetSpace() { - return m_cb->AEStream_GetSpace(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_space(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -302,14 +317,15 @@ namespace audioengine /// @ingroup cpp_kodi_audioengine_CAddonAEStream /// @brief Add planar or interleaved PCM data to the stream /// - /// @param data array of pointers to the planes - /// @param offset to frame in frames - /// @param frames number of frames + /// @param[in] data array of pointers to the planes + /// @param[in] offset to frame in frames + /// @param[in] frames number of frames + /// @param[in] pts presentation timestamp /// @return The number of frames consumed /// - unsigned int AddData(uint8_t* const *data, unsigned int offset, unsigned int frames) + unsigned int AddData(uint8_t* const *data, unsigned int offset, unsigned int frames, double pts = 0.0) { - return m_cb->AEStream_AddData(m_kodiBase, m_StreamHandle, data, offset, frames); + return m_cb->aestream_add_data(m_kodiBase, m_StreamHandle, data, offset, frames, pts); } //-------------------------------------------------------------------------- @@ -322,7 +338,7 @@ namespace audioengine /// double GetDelay() { - return m_cb->AEStream_GetDelay(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_delay(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -334,7 +350,7 @@ namespace audioengine /// bool IsBuffering() { - return m_cb->AEStream_IsBuffering(m_kodiBase, m_StreamHandle); + return m_cb->aestream_is_buffering(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -347,7 +363,7 @@ namespace audioengine /// double GetCacheTime() { - return m_cb->AEStream_GetCacheTime(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_cache_time(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -359,7 +375,7 @@ namespace audioengine /// double GetCacheTotal() { - return m_cb->AEStream_GetCacheTotal(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_cache_total(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -369,7 +385,7 @@ namespace audioengine /// void Pause() { - return m_cb->AEStream_Pause(m_kodiBase, m_StreamHandle); + return m_cb->aestream_pause(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -379,7 +395,7 @@ namespace audioengine /// void Resume() { - return m_cb->AEStream_Resume(m_kodiBase, m_StreamHandle); + return m_cb->aestream_resume(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -392,9 +408,9 @@ namespace audioengine /// /// @note Once called AddData will not consume more data. /// - void Drain(bool wait) + void Drain(bool wait = true) { - return m_cb->AEStream_Drain(m_kodiBase, m_StreamHandle, wait=true); + return m_cb->aestream_drain(m_kodiBase, m_StreamHandle, wait); } //-------------------------------------------------------------------------- @@ -404,7 +420,7 @@ namespace audioengine /// bool IsDraining() { - return m_cb->AEStream_IsDraining(m_kodiBase, m_StreamHandle); + return m_cb->aestream_is_draining(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -414,7 +430,7 @@ namespace audioengine /// bool IsDrained() { - return m_cb->AEStream_IsDrained(m_kodiBase, m_StreamHandle); + return m_cb->aestream_is_drained(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -424,7 +440,7 @@ namespace audioengine /// void Flush() { - return m_cb->AEStream_Flush(m_kodiBase, m_StreamHandle); + return m_cb->aestream_flush(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -436,7 +452,7 @@ namespace audioengine /// float GetVolume() { - return m_cb->AEStream_GetVolume(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_volume(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -448,7 +464,7 @@ namespace audioengine /// void SetVolume(float volume) { - return m_cb->AEStream_SetVolume(m_kodiBase, m_StreamHandle, volume); + return m_cb->aestream_set_volume(m_kodiBase, m_StreamHandle, volume); } //-------------------------------------------------------------------------- @@ -460,7 +476,7 @@ namespace audioengine /// float GetAmplification() { - return m_cb->AEStream_GetAmplification(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_amplification(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -473,7 +489,7 @@ namespace audioengine /// void SetAmplification(float amplify) { - return m_cb->AEStream_SetAmplification(m_kodiBase, m_StreamHandle, amplify); + return m_cb->aestream_set_amplification(m_kodiBase, m_StreamHandle, amplify); } //-------------------------------------------------------------------------- @@ -485,7 +501,7 @@ namespace audioengine /// unsigned int GetFrameSize() const { - return m_cb->AEStream_GetFrameSize(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_frame_size(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -497,7 +513,7 @@ namespace audioengine /// unsigned int GetChannelCount() const { - return m_cb->AEStream_GetChannelCount(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_channel_count(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -511,7 +527,7 @@ namespace audioengine /// unsigned int GetSampleRate() const { - return m_cb->AEStream_GetSampleRate(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_sample_rate(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -523,7 +539,7 @@ namespace audioengine /// AEDataFormat GetDataFormat() const { - return m_cb->AEStream_GetDataFormat(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_data_format(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -537,7 +553,7 @@ namespace audioengine /// double GetResampleRatio() { - return m_cb->AEStream_GetResampleRatio(m_kodiBase, m_StreamHandle); + return m_cb->aestream_get_resample_ratio(m_kodiBase, m_StreamHandle); } //-------------------------------------------------------------------------- @@ -553,7 +569,7 @@ namespace audioengine /// void SetResampleRatio(double ratio) { - m_cb->AEStream_SetResampleRatio(m_kodiBase, m_StreamHandle, ratio); + m_cb->aestream_set_resample_ratio(m_kodiBase, m_StreamHandle, ratio); } //-------------------------------------------------------------------------- @@ -572,7 +588,8 @@ namespace audioengine /// inline bool GetCurrentSinkFormat(AudioEngineFormat &format) { - return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_audioengine->GetCurrentSinkFormat(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, &format); + using namespace kodi::addon; + return CAddonBase::m_interface->toKodi->kodi_audioengine->get_current_sink_format(CAddonBase::m_interface->toKodi->kodiBase, &format); } //---------------------------------------------------------------------------- diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h index 76210cf..b06770c 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h @@ -110,6 +110,7 @@ extern "C" double (*get_file_download_speed)(void* kodiBase, void* file); void (*close_file)(void* kodiBase, void* file); int (*get_file_chunk_size)(void* kodiBase, void* file); + char* (*get_property)(void* kodiBase, void* file, int type, const char *name); void* (*curl_create)(void* kodiBase, const char* url); bool (*curl_add_option)(void* kodiBase, void* file, int type, const char* name, const char* value); @@ -194,6 +195,25 @@ typedef enum CURLOptiontype } CURLOptiontype; //------------------------------------------------------------------------------ +//============================================================================== +/// \ingroup cpp_kodi_vfs_Defs +/// @brief Used CURL message types +/// +typedef enum FilePropertyTypes +{ + /// Get protocol response line + ADDON_FILE_PROPERTY_RESPONSE_PROTOCOL, + /// Get a response header + ADDON_FILE_PROPERTY_RESPONSE_HEADER, + /// Get file content type + ADDON_FILE_PROPERTY_CONTENT_TYPE, + /// Get file content charset + ADDON_FILE_PROPERTY_CONTENT_CHARSET, + /// Get file mime type + ADDON_FILE_PROPERTY_MIME_TYPE +} FilePropertyTypes; +//------------------------------------------------------------------------------ + //============================================================================ /// /// \ingroup cpp_kodi_vfs_Defs @@ -310,7 +330,7 @@ namespace vfs // // @param[in] dirEntry pointer to own class type // - CDirEntry(const VFSDirEntry& dirEntry) : + explicit CDirEntry(const VFSDirEntry& dirEntry) : m_label(dirEntry.label ? dirEntry.label : ""), m_path(dirEntry.path ? dirEntry.path : ""), m_folder(dirEntry.folder), @@ -906,6 +926,37 @@ namespace vfs } //---------------------------------------------------------------------------- + + //============================================================================ + /// + /// @ingroup cpp_kodi_vfs + /// @brief Remove the slash on given path name + /// + /// @param[in,out] path The complete path + /// + /// + /// ------------------------------------------------------------------------ + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include + /// ... + /// std::string dirName = "special://temp/"; + /// kodi::vfs::RemoveSlashAtEnd(dirName); + /// fprintf(stderr, "Directory name is '%s'\n", dirName.c_str()); + /// ~~~~~~~~~~~~~ + /// + inline void RemoveSlashAtEnd(std::string& path) + { + if (!path.empty()) + { + char last = path[path.size() - 1]; + if (last == '/' || last == '\\') + path.erase(path.size() - 1); + } + } + //---------------------------------------------------------------------------- + //============================================================================ /// /// @ingroup cpp_kodi_vfs @@ -1480,6 +1531,34 @@ namespace vfs } //-------------------------------------------------------------------------- + //========================================================================== + /// + /// @ingroup cpp_kodi_vfs_CFile + /// @brief retrieve a file property + /// + /// @param[in] type The type of the file property to retrieve the value for + /// @param[in] name The name of a named property value (e.g. Header) + /// @return value of requested property, empty on failure / non-existance + /// + const std::string GetProperty(FilePropertyTypes type, const std::string &name) const + { + if (!m_file) + { + kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before GetProperty!"); + return ""; + } + char *res(::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_property( + ::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, type, name.c_str())); + if (res) + { + std::string strReturn(res); + ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, res); + return strReturn; + } + return ""; + } + //-------------------------------------------------------------------------- + //========================================================================== /// /// @ingroup cpp_kodi_vfs_CFile diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h index f56f8ae..ca253ff 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h @@ -83,7 +83,7 @@ namespace addon /// @param[in] instance The from Kodi given instance given be /// add-on CreateInstance call with instance /// id ADDON_INSTANCE_AUDIODECODER. - CInstanceAudioDecoder(KODI_HANDLE instance) + explicit CInstanceAudioDecoder(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_AUDIODECODER) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioEncoder.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioEncoder.h index 3d59a99..7d2464d 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioEncoder.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioEncoder.h @@ -75,7 +75,7 @@ namespace addon /// @param[in] instance The from Kodi given instance given be /// add-on CreateInstance call with instance /// id ADDON_INSTANCE_AUDIOENCODER. - CInstanceAudioEncoder(KODI_HANDLE instance) + explicit CInstanceAudioEncoder(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_AUDIOENCODER) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/ImageDecoder.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/ImageDecoder.h index a854711..5ccb859 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/ImageDecoder.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/ImageDecoder.h @@ -81,7 +81,7 @@ namespace addon /// @param[in] instance The from Kodi given instance given be /// add-on CreateInstance call with instance /// id ADDON_INSTANCE_IMAGEDECODER. - CInstanceImageDecoder(KODI_HANDLE instance) + explicit CInstanceImageDecoder(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_IMAGEDECODER) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Inputstream.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Inputstream.h index 76cfe92..8db17c0 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Inputstream.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Inputstream.h @@ -109,11 +109,26 @@ extern "C" { TYPE_TELETEXT } m_streamType; - enum Codec_FEATURES + enum Codec_FEATURES : uint32_t { FEATURE_DECODE = 1 }; - unsigned int m_features; + uint32_t m_features; + + enum STREAM_FLAGS : uint32_t + { + 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 + }; + uint32_t m_flags; char m_codecName[32]; /*!< @brief (required) name of codec according to ffmpeg */ char m_codecInternalName[32]; /*!< @brief (optional) internal name of codec (selectionstream info) */ @@ -173,7 +188,7 @@ extern "C" { struct INPUTSTREAM_IDS (__cdecl* get_stream_ids)(const AddonInstance_InputStream* instance); struct INPUTSTREAM_INFO (__cdecl* get_stream)(const AddonInstance_InputStream* instance, int streamid); void (__cdecl* enable_stream)(const AddonInstance_InputStream* instance, int streamid, bool enable); - void(__cdecl* open_stream)(const AddonInstance_InputStream* instance, int streamid); + bool(__cdecl* open_stream)(const AddonInstance_InputStream* instance, int streamid); void (__cdecl* demux_reset)(const AddonInstance_InputStream* instance); void (__cdecl* demux_abort)(const AddonInstance_InputStream* instance); void (__cdecl* demux_flush)(const AddonInstance_InputStream* instance); @@ -218,7 +233,7 @@ namespace addon class CInstanceInputStream : public IAddonInstance { public: - CInstanceInputStream(KODI_HANDLE instance) + explicit CInstanceInputStream(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_INPUTSTREAM) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) @@ -278,7 +293,7 @@ namespace addon * @param streamid unique id of stream * @remarks */ - virtual void OpenStream(int streamid) = 0; + virtual bool OpenStream(int streamid) = 0; /*! * Reset the demultiplexer in the add-on. @@ -513,9 +528,9 @@ namespace addon instance->toAddon.addonInstance->EnableStream(streamid, enable); } - inline static void ADDON_OpenStream(const AddonInstance_InputStream* instance, int streamid) + inline static bool ADDON_OpenStream(const AddonInstance_InputStream* instance, int streamid) { - instance->toAddon.addonInstance->OpenStream(streamid); + return instance->toAddon.addonInstance->OpenStream(streamid); } inline static void ADDON_DemuxReset(const AddonInstance_InputStream* instance) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h index 045a925..c1a18e0 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h @@ -319,7 +319,7 @@ namespace addon CAddonBase::m_interface->globalSingleInstance = this; } - CInstancePeripheral(KODI_HANDLE instance) + explicit CInstancePeripheral(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_PERIPHERAL) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h index 721da35..ea70b30 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h @@ -104,7 +104,7 @@ namespace addon { } - Peripheral(const PERIPHERAL_INFO& info) : + explicit Peripheral(const PERIPHERAL_INFO& info) : m_type(info.type), m_strName(info.name ? info.name : ""), m_vendorId(info.vendor_id), @@ -196,7 +196,7 @@ namespace addon SetAxisState(state); } - PeripheralEvent(const PERIPHERAL_EVENT& event) : + explicit PeripheralEvent(const PERIPHERAL_EVENT& event) : m_event(event) { } @@ -259,7 +259,7 @@ namespace addon *this = other; } - Joystick(const JOYSTICK_INFO& info) : + explicit Joystick(const JOYSTICK_INFO& info) : Peripheral(info.peripheral), m_provider(info.provider ? info.provider : ""), m_requestedPort(info.requested_port), @@ -445,7 +445,7 @@ namespace addon return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR, motorIndex); } - DriverPrimitive(const JOYSTICK_DRIVER_PRIMITIVE& primitive) : + explicit DriverPrimitive(const JOYSTICK_DRIVER_PRIMITIVE& primitive) : m_type(primitive.type), m_driverIndex(0), m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN), @@ -604,12 +604,12 @@ namespace addon *this = other; } - JoystickFeature(const JOYSTICK_FEATURE& feature) : + explicit JoystickFeature(const JOYSTICK_FEATURE& feature) : m_name(feature.name ? feature.name : ""), m_type(feature.type) { for (unsigned int i = 0; i < JOYSTICK_PRIMITIVE_MAX; i++) - m_primitives[i] = feature.primitives[i]; + m_primitives[i] = DriverPrimitive(feature.primitives[i]); } JoystickFeature& operator=(const JoystickFeature& rhs) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Screensaver.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Screensaver.h index 85cd7bc..04821b2 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Screensaver.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Screensaver.h @@ -261,7 +261,7 @@ namespace addon /// /// @warning Only use `instance` from the CreateInstance call /// - CInstanceScreensaver(KODI_HANDLE instance) + explicit CInstanceScreensaver(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_SCREENSAVER) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h index 4bb3e69..8e688d7 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h @@ -119,7 +119,7 @@ namespace addon class CInstanceVFS : public IAddonInstance { public: - CInstanceVFS(KODI_HANDLE instance) + explicit CInstanceVFS(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_VFS) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) @@ -350,7 +350,7 @@ namespace addon m_cb->require_authentication(m_cb->ctx, url.c_str()); } - CVFSCallbacks(const VFSGetDirectoryCallbacks* cb) : m_cb(cb) { } + explicit CVFSCallbacks(const VFSGetDirectoryCallbacks* cb) : m_cb(cb) { } private: const VFSGetDirectoryCallbacks* m_cb; @@ -519,7 +519,7 @@ namespace addon VFSGetDirectoryCallbacks* callbacks) { std::vector addonEntries; - bool ret = instance->toAddon.addonInstance->GetDirectory(*url, addonEntries, callbacks); + bool ret = instance->toAddon.addonInstance->GetDirectory(*url, addonEntries, CVFSCallbacks(callbacks)); if (ret) { VFSDirEntry* entries = static_cast(malloc(sizeof(VFSDirEntry) * addonEntries.size())); diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VideoCodec.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VideoCodec.h index 710fda0..02d39c6 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VideoCodec.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VideoCodec.h @@ -158,7 +158,7 @@ namespace kodi class CInstanceVideoCodec : public IAddonInstance { public: - CInstanceVideoCodec(KODI_HANDLE instance) + explicit CInstanceVideoCodec(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_VIDEOCODEC) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h index b1ded64..452085a 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h @@ -340,7 +340,7 @@ namespace addon /// /// @warning Only use `instance` from the CreateInstance call /// - CInstanceVisualization(KODI_HANDLE instance) + explicit CInstanceVisualization(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_VISUALIZATION), m_presetLockedByUser(false) { diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/ListItem.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/ListItem.h index 944b1b9..13cf2d1 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/ListItem.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/ListItem.h @@ -37,7 +37,7 @@ namespace gui GUIHANDLE GetControlHandle() const { return m_controlHandle; } protected: - CAddonGUIControlBase(CAddonGUIControlBase* window) + explicit CAddonGUIControlBase(CAddonGUIControlBase* window) : m_controlHandle(nullptr), m_interface(::kodi::addon::CAddonBase::m_interface->toKodi), m_Window(window) {} @@ -111,7 +111,7 @@ namespace gui * Related to call of "ListItemPtr kodi::gui::CWindow::GetListItem(int listPos)" * Not needed for addon development itself */ - CListItem(GUIHANDLE listItemHandle) + explicit CListItem(GUIHANDLE listItemHandle) : CAddonGUIControlBase(nullptr) { m_controlHandle = listItemHandle; diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/Window.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/Window.h index b78585f..c369c62 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/Window.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/Window.h @@ -128,6 +128,10 @@ namespace gui /// @note If your Add-On ends this window will be closed to. To show it forever, /// make a loop at the end of your Add-On or use doModal() instead. /// + /// @warning If used must be the class be global present until Kodi becomes + /// closed. The creation can be done after before "Show" becomes called, but + /// not delete class after them. + /// /// @return Return true if call and show is successed, /// if false was something failed to get needed /// skin parts. diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/definitions.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/definitions.h index 61af9fe..1dd03cc 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/definitions.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/definitions.h @@ -262,6 +262,8 @@ typedef struct AddonToKodiFuncTable_kodi_gui_dialogProgress typedef struct AddonToKodiFuncTable_kodi_gui_dialogSelect { int (*open)(void* kodiBase, const char *heading, const char *entries[], unsigned int size, int selected, unsigned int autoclose); + bool (*open_multi_select)(void* kodiBase, const char* heading, const char* entryIDs[], const char* entryNames[], + bool entriesSelected[], unsigned int size, unsigned int autoclose); } AddonToKodiFuncTable_kodi_gui_dialogSelect; typedef struct AddonToKodiFuncTable_kodi_gui_dialogTextViewer diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ContextMenu.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ContextMenu.h index 47afc23..39b21b4 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ContextMenu.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ContextMenu.h @@ -91,6 +91,100 @@ namespace dialogs return ret; } //-------------------------------------------------------------------------- + + //========================================================================== + /// + /// \ingroup cpp_kodi_gui_dialogs_ContextMenu + /// @brief Show a context menu dialog about given parts. + /// + /// @param[in] heading Dialog heading name + /// @param[in] entries String list about entries + /// @return The selected entry, if return -1 was nothing selected or canceled + /// + /// + ///------------------------------------------------------------------------- + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include + /// + /// const std::vector> entries + /// { + /// { "ID 1", "Test 1" }, + /// { "ID 2", "Test 2" }, + /// { "ID 3", "Test 3" }, + /// { "ID 4", "Test 4" }, + /// { "ID 5", "Test 5" } + /// }; + /// + /// int selected = kodi::gui::dialogs::ContextMenu::Show("Test selection", entries); + /// if (selected < 0) + /// fprintf(stderr, "Item selection canceled\n"); + /// else + /// fprintf(stderr, "Selected item is: %i\n", selected); + /// ~~~~~~~~~~~~~ + /// + inline int Show(const std::string& heading, const std::vector>& entries) + { + using namespace ::kodi::addon; + unsigned int size = entries.size(); + const char** cEntries = static_cast(malloc(size*sizeof(const char**))); + for (unsigned int i = 0; i < size; ++i) + { + cEntries[i] = entries[i].second.c_str(); + } + int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size); + free(cEntries); + return ret; + } + //-------------------------------------------------------------------------- + + //========================================================================== + /// + /// \ingroup cpp_kodi_gui_dialogs_ContextMenu + /// @brief Show a context menu dialog about given parts. + /// + /// @param[in] heading Dialog heading name + /// @param[in] entries String list about entries + /// @return The selected entry, if return -1 was nothing selected or canceled + /// + /// + ///------------------------------------------------------------------------- + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include + /// + /// const std::vector> entries + /// { + /// { 1, "Test 1" }, + /// { 2, "Test 2" }, + /// { 3, "Test 3" }, + /// { 4, "Test 4" }, + /// { 5, "Test 5" } + /// }; + /// + /// int selected = kodi::gui::dialogs::ContextMenu::Show("Test selection", entries); + /// if (selected < 0) + /// fprintf(stderr, "Item selection canceled\n"); + /// else + /// fprintf(stderr, "Selected item is: %i\n", selected); + /// ~~~~~~~~~~~~~ + /// + inline int Show(const std::string& heading, const std::vector>& entries) + { + using namespace ::kodi::addon; + unsigned int size = entries.size(); + const char** cEntries = static_cast(malloc(size*sizeof(const char**))); + for (unsigned int i = 0; i < size; ++i) + { + cEntries[i] = entries[i].second.c_str(); + } + int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size); + free(cEntries); + return ret; + } + //-------------------------------------------------------------------------- }; } /* namespace dialogs */ diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h index e9c5a9d..5878958 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h @@ -75,7 +75,7 @@ namespace dialogs /// /// @param[in] title Title string /// - CExtendedProgress(const std::string& title = "") + explicit CExtendedProgress(const std::string& title = "") { using namespace ::kodi::addon; m_DialogHandle = CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->new_dialog(CAddonBase::m_interface->toKodi->kodiBase, title.c_str()); diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Keyboard.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Keyboard.h index cff30d8..6d2b32b 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Keyboard.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Keyboard.h @@ -96,8 +96,7 @@ namespace dialogs hiddenInput, autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - text = retString; + text = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -129,8 +128,7 @@ namespace dialogs allowEmptyResult, autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - text = retString; + text = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -162,8 +160,7 @@ namespace dialogs allowEmptyResult, autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - newPassword = retString; + newPassword = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -192,8 +189,7 @@ namespace dialogs newPassword.c_str(), &retString, autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - newPassword = retString; + newPassword = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -275,8 +271,7 @@ namespace dialogs autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - newPassword = retString; + newPassword = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -305,8 +300,7 @@ namespace dialogs &retString, autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - newPassword = retString; + newPassword = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -339,8 +333,7 @@ namespace dialogs retries, autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - password = retString; + password = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -373,8 +366,7 @@ namespace dialogs text.c_str(), &retString, searching, autoCloseMs); if (retString != nullptr) { - if (std::strlen(retString)) - text = retString; + text = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Numeric.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Numeric.h index dddbf7e..70e9e7b 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Numeric.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Numeric.h @@ -68,8 +68,7 @@ namespace dialogs bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_new_password(CAddonBase::m_interface->toKodi->kodiBase, &pw); if (pw != nullptr) { - if (std::strlen(pw)) - newPassword = pw; + newPassword = pw; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, pw); } return ret; @@ -172,8 +171,7 @@ namespace dialogs toVerify.c_str(), &retString, heading.c_str(), verifyInput); if (retString != nullptr) { - if (std::strlen(retString)) - toVerify = retString; + toVerify = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -279,8 +277,7 @@ namespace dialogs ipAddress.c_str(), &retString, heading.c_str()); if (retString != nullptr) { - if (std::strlen(retString)) - ipAddress = retString; + ipAddress = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -326,8 +323,7 @@ namespace dialogs input.c_str(), &retString, heading.c_str(), autoCloseTimeoutMs); if (retString != nullptr) { - if (std::strlen(retString)) - input = retString; + input = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; @@ -354,8 +350,7 @@ namespace dialogs time.c_str(), &retString, heading.c_str()); if (retString != nullptr) { - if (std::strlen(retString)) - time = retString; + time = retString; CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString); } return ret; diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Select.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Select.h index 963c84c..8276832 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Select.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/dialogs/Select.h @@ -22,6 +22,38 @@ #include "../definitions.h" #include "../../AddonBase.h" +//============================================================================== +/// \defgroup cpp_kodi_vfs_Defs Definitions, structures and enumerators +/// \ingroup cpp_kodi_gui_dialogs_Select +/// @brief **Dialog Select definition values** +//------------------------------------------------------------------------------ + +//============================================================================== +/// \ingroup cpp_kodi_vfs_Defs +/// @brief **Selection entry structure** +/// +typedef struct SSelectionEntry +{ + //============================================================================ + /// Structure constructor + /// + /// There becomes selected always set to false. + /// + SSelectionEntry() : selected(false) { } + //---------------------------------------------------------------------------- + + /// Entry identfication string + std::string id; + + /// Entry name to show on GUI dialog + std::string name; + + /// Place where entry can be preselected and after return the from user + /// selected is set. + bool selected; +} SSelectionEntry; +//------------------------------------------------------------------------------ + namespace kodi { namespace gui @@ -97,6 +129,139 @@ namespace dialogs return ret; } //-------------------------------------------------------------------------- + + //========================================================================== + /// + /// \ingroup cpp_kodi_gui_dialogs_Select + /// @brief Show a selection dialog about given parts. + /// + /// This function is mostly equal to the other, only becomes the string list + /// here done by a SSelectionEntry, where a ID string can be defined. + /// + /// @param[in] heading Dialog heading name + /// @param[in] entries SSelectionEntry list about entries + /// @param[in] selected [opt] Predefined selection (default is + /// -1 for the first) + /// @param[in] autoclose [opt] To close dialog automatic after the given + /// time in ms. As '0' it stays open. + /// @return The selected entry, if return -1 was + /// nothing selected or canceled + /// + /// + ///------------------------------------------------------------------------- + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include + /// + /// std::vector entries + /// { + /// { "ID 1", "Test 1", false }, + /// { "ID 2", "Test 2", false }, + /// { "ID 3", "Test 3", false }, + /// { "ID 4", "Test 4", false }, + /// { "ID 5", "Test 5", false } + /// }; + /// + /// int selected = kodi::gui::dialogs::Select::Show("Test selection", entries, -1); + /// if (selected < 0) + /// fprintf(stderr, "Item selection canceled\n"); + /// else + /// fprintf(stderr, "Selected item is: %i\n", selected); + /// ~~~~~~~~~~~~~ + /// + inline int Show(const std::string& heading, std::vector& entries, int selected = -1, unsigned int autoclose = 0) + { + using namespace ::kodi::addon; + unsigned int size = entries.size(); + const char** cEntries = static_cast(malloc(size*sizeof(const char*))); + for (unsigned int i = 0; i < size; ++i) + { + cEntries[i] = entries[i].name.c_str(); + if (selected == -1 && entries[i].selected) + selected = i; + } + int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), + cEntries, size, selected, autoclose); + if (ret >= 0) + { + entries[ret].selected = true; + } + free(cEntries); + return ret; + } + //-------------------------------------------------------------------------- + + //========================================================================== + /// + /// \ingroup cpp_kodi_gui_dialogs_Select + /// @brief Show a multiple selection dialog about given parts. + /// + /// @param[in] heading Dialog heading name + /// @param[in] entries SSelectionEntry list about entries + /// @param[in] autoclose [opt] To close dialog automatic after the given + /// time in ms. As '0' it stays open. + /// @return The selected entries, if return empty was + /// nothing selected or canceled + /// + /// With selected on SSelectionEntry can be a pre selection defined. + /// + ///------------------------------------------------------------------------- + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include + /// + /// std::vector entries + /// { + /// { "ID 1", "Test 1", false }, + /// { "ID 2", "Test 2", false }, + /// { "ID 3", "Test 3", false }, + /// { "ID 4", "Test 4", false }, + /// { "ID 5", "Test 5", false } + /// }; + /// + /// bool ret = kodi::gui::dialogs::Select::ShowMultiSelect("Test selection", entries); + /// if (!ret) + /// fprintf(stderr, "Selection canceled\n"); + /// else + /// { + /// fprintf(stderr, "Selected items:\n"); + /// for (const auto& entry : entries) + /// { + /// if (entry.selected) + /// fprintf(stderr, " - %s\n", entry.selected.id.c_str()); + /// } + /// } + /// ~~~~~~~~~~~~~ + /// + inline bool ShowMultiSelect(const std::string& heading, std::vector& entries, int autoclose = 0) + { + using namespace ::kodi::addon; + unsigned int size = entries.size(); + const char** cEntryIDs = static_cast(malloc(size*sizeof(const char*))); + const char** cEntryNames = static_cast(malloc(size*sizeof(const char*))); + bool* cEntriesSelected = static_cast(malloc(size*sizeof(bool))); + for (unsigned int i = 0; i < size; ++i) + { + cEntryIDs[i] = entries[i].id.c_str(); + cEntryNames[i] = entries[i].name.c_str(); + cEntriesSelected[i] = entries[i].selected; + } + bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open_multi_select(CAddonBase::m_interface->toKodi->kodiBase, + heading.c_str(), cEntryIDs, cEntryNames, + cEntriesSelected, size, autoclose); + if (ret) + { + for (unsigned int i = 0; i < size; ++i) + entries[i].selected = cEntriesSelected[i]; + } + free(cEntryNames); + free(cEntryIDs); + free(cEntriesSelected); + return ret; + } + //-------------------------------------------------------------------------- }; /// @} diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_addon.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_addon.h index 8b02e33..c264578 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_addon.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_addon.h @@ -155,6 +155,7 @@ typedef struct CB_AddOn int (*GetFileChunkSize)(const void* addonData, void* file); bool (*FileExists)(const void* addonData, const char *strFileName, bool bUseCache); int (*StatFile)(const void* addonData, const char *strFileName, struct __stat64* buffer); + char *(*GetFileProperty)(const void* addonData, void* file, XFILE::FileProperty type, const char *name); bool (*DeleteFile)(const void* addonData, const char *strFileName); bool (*CanOpenDirectory)(const void* addonData, const char* strURL); bool (*CreateDirectory)(const void* addonData, const char *strPath); @@ -464,6 +465,18 @@ namespace ADDON return m_Callbacks->StatFile(m_Handle->addonData, strFileName, buffer); } + /*! + * @brief Get a property from an open file. + * @param file The file to get an property for + * @param type type of the requested property. + * @param name of the requested property / can be null. + * @return The value of the requested property, must be FreeString'ed. + */ + char *GetFileProperty(void* file, XFILE::FileProperty type, const char *name) + { + return m_Callbacks->GetFileProperty(m_Handle->addonData, file, type, name); + } + /*! * @brief Deletes a file. * @param strFileName The filename to delete. diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_pvr.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_pvr.h index 6a9145e..f470566 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_pvr.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_pvr.h @@ -222,13 +222,12 @@ public: /*! * @brief Notify a state change for an EPG event * @param tag The EPG event. - * @param iUniqueChannelId The unique id of the channel for the EPG event * @param newState The new state. For EPG_EVENT_CREATED and EPG_EVENT_UPDATED, tag must be filled with all available * event data, not just a delta. For EPG_EVENT_DELETED, it is sufficient to fill EPG_TAG.iUniqueBroadcastId */ - void EpgEventStateChange(EPG_TAG *tag, unsigned int iUniqueChannelId, EPG_EVENT_STATE newState) + void EpgEventStateChange(EPG_TAG *tag, EPG_EVENT_STATE newState) { - return m_Callbacks->toKodi.EpgEventStateChange(m_Callbacks->toKodi.kodiInstance, tag, iUniqueChannelId, newState); + return m_Callbacks->toKodi.EpgEventStateChange(m_Callbacks->toKodi.kodiInstance, tag, newState); } /*! diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h index 870a646..32e6b1a 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h @@ -41,8 +41,8 @@ * overview. */ -#define ADDON_GLOBAL_VERSION_MAIN "1.0.10" -#define ADDON_GLOBAL_VERSION_MAIN_MIN "1.0.10" +#define ADDON_GLOBAL_VERSION_MAIN "1.0.11" +#define ADDON_GLOBAL_VERSION_MAIN_MIN "1.0.11" #define ADDON_GLOBAL_VERSION_MAIN_XML_ID "kodi.binary.global.main" #define ADDON_GLOBAL_VERSION_MAIN_DEPENDS "AddonBase.h" \ "xbmc_addon_dll.h" \ @@ -55,18 +55,19 @@ #define ADDON_GLOBAL_VERSION_GENERAL_XML_ID "kodi.binary.global.general" #define ADDON_GLOBAL_VERSION_GENERAL_DEPENDS "General.h" -#define ADDON_GLOBAL_VERSION_GUI "5.11.0" +#define ADDON_GLOBAL_VERSION_GUI "5.12.0" #define ADDON_GLOBAL_VERSION_GUI_MIN "5.10.0" #define ADDON_GLOBAL_VERSION_GUI_XML_ID "kodi.binary.global.gui" -#define ADDON_GLOBAL_VERSION_GUI_DEPENDS "libKODI_guilib.h" +#define ADDON_GLOBAL_VERSION_GUI_DEPENDS "libKODI_guilib.h" \ + "gui/" -#define ADDON_GLOBAL_VERSION_AUDIOENGINE "1.0.0" -#define ADDON_GLOBAL_VERSION_AUDIOENGINE_MIN "1.0.0" +#define ADDON_GLOBAL_VERSION_AUDIOENGINE "1.0.1" +#define ADDON_GLOBAL_VERSION_AUDIOENGINE_MIN "1.0.1" #define ADDON_GLOBAL_VERSION_AUDIOENGINE_XML_ID "kodi.binary.global.audioengine" #define ADDON_GLOBAL_VERSION_AUDIOENGINE_DEPENDS "AudioEngine.h" -#define ADDON_GLOBAL_VERSION_FILESYSTEM "1.0.0" -#define ADDON_GLOBAL_VERSION_FILESYSTEM_MIN "1.0.0" +#define ADDON_GLOBAL_VERSION_FILESYSTEM "1.0.1" +#define ADDON_GLOBAL_VERSION_FILESYSTEM_MIN "1.0.1" #define ADDON_GLOBAL_VERSION_FILESYSTEM_XML_ID "kodi.binary.global.filesystem" #define ADDON_GLOBAL_VERSION_FILESYSTEM_DEPENDS "Filesystem.h" @@ -102,8 +103,8 @@ #define ADDON_INSTANCE_VERSION_IMAGEDECODER_XML_ID "kodi.binary.instance.imagedecoder" #define ADDON_INSTANCE_VERSION_IMAGEDECODER_DEPENDS "addon-instance/ImageDecoder.h" -#define ADDON_INSTANCE_VERSION_INPUTSTREAM "2.0.2" -#define ADDON_INSTANCE_VERSION_INPUTSTREAM_MIN "2.0.2" +#define ADDON_INSTANCE_VERSION_INPUTSTREAM "2.0.4" +#define ADDON_INSTANCE_VERSION_INPUTSTREAM_MIN "2.0.4" #define ADDON_INSTANCE_VERSION_INPUTSTREAM_XML_ID "kodi.binary.instance.inputstream" #define ADDON_INSTANCE_VERSION_INPUTSTREAM_DEPENDS "addon-instance/Inputstream.h" @@ -113,8 +114,8 @@ #define ADDON_INSTANCE_VERSION_PERIPHERAL_DEPENDS "addon-instance/Peripheral.h" \ "addon-instance/PeripheralUtils.h" -#define ADDON_INSTANCE_VERSION_PVR "5.6.0" -#define ADDON_INSTANCE_VERSION_PVR_MIN "5.6.0" +#define ADDON_INSTANCE_VERSION_PVR "5.7.0" +#define ADDON_INSTANCE_VERSION_PVR_MIN "5.7.0" #define ADDON_INSTANCE_VERSION_PVR_XML_ID "kodi.binary.instance.pvr" #define ADDON_INSTANCE_VERSION_PVR_DEPENDS "xbmc_pvr_dll.h" \ "xbmc_pvr_types.h" \ diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_epg_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_epg_types.h index c2b5458..7561ff6 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_epg_types.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_epg_types.h @@ -91,8 +91,8 @@ extern "C" { */ typedef struct EPG_TAG { unsigned int iUniqueBroadcastId; /*!< @brief (required) identifier for this event. Event uids must be unique for a channel. Valid uids must be greater than EPG_TAG_INVALID_UID. */ + unsigned int iUniqueChannelId; /*!< @brief (required) unique identifier of the channel this event belongs to. */ const char * strTitle; /*!< @brief (required) this event's title */ - unsigned int iChannelNumber; /*!< @brief (required) the number of the channel this event occurs on */ time_t startTime; /*!< @brief (required) start time in UTC */ time_t endTime; /*!< @brief (required) end time in UTC */ const char * strPlotOutline; /*!< @brief (optional) plot outline */ diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_dll.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_dll.h index 3dbf1c8..019644b 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_dll.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_dll.h @@ -97,6 +97,35 @@ extern "C" * @remarks Required if bSupportsEPG is set to true. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. */ PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL& channel, time_t iStart, time_t iEnd); + + /* + * Check if the given EPG tag can be recorded. + * @param tag the epg tag to check. + * @param [out] bIsRecordable Set to true if the tag can be recorded. + * @return PVR_ERROR_NO_ERROR if bIsRecordable has been set successfully. + * @remarks Optional, return PVR_ERROR_NOT_IMPLEMENTED to let Kodi decide. + */ + PVR_ERROR IsEPGTagRecordable(const EPG_TAG* tag, bool* bIsRecordable); + + /* + * Check if the given EPG tag can be played. + * @param tag the epg tag to check. + * @param [out] bIsPlayable Set to true if the tag can be played. + * @return PVR_ERROR_NO_ERROR if bIsPlayable has been set successfully. + * @remarks Required if add-on supports playing epg tags. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + */ + PVR_ERROR IsEPGTagPlayable(const EPG_TAG* tag, bool* bIsPlayable); + + /*! + * Get the stream properties for an epg tag from the backend. + * @param[in] tag The epg tag to get the stream properties for. + * @param[inout] properties in: an array for the properties to return, out: the properties required to play the stream. + * @param[inout] iPropertiesCount in: the size of the properties array, out: the number of properties returned. + * @return PVR_ERROR_NO_ERROR if the stream is available. + * @remarks Required if add-on supports playing epg tags. In this case your implementation must fill the property PVR_STREAM_PROPERTY_STREAMURL with the URL Kodi should resolve to playback the epg tag. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + */ + PVR_ERROR GetEPGTagStreamProperties(const EPG_TAG* tag, PVR_NAMED_VALUE* properties, unsigned int* iPropertiesCount); + //@} /*! @name PVR channel group methods @@ -429,7 +458,7 @@ extern "C" * Get the stream properties for a channel from the backend. * @param[in] channel The channel to get the stream properties for. * @param[inout] properties in: an array for the properties to return, out: the properties required to play the stream. - * @param[inout] iPropertiesCount: in the size of the properties array, out: the number of properties returned. + * @param[inout] iPropertiesCount in: the size of the properties array, out: the number of properties returned. * @return PVR_ERROR_NO_ERROR if the stream is available. * @remarks Required if PVR_ADDON_CAPABILITIES::bSupportsTV or PVR_ADDON_CAPABILITIES::bSupportsRadio are set to true and PVR_ADDON_CAPABILITIES::bHandlesInputStream is set to false. In this case the implementation must fill the property PVR_STREAM_PROPERTY_STREAMURL with the URL Kodi should resolve to playback the channel. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. */ @@ -439,7 +468,7 @@ extern "C" * Get the stream properties for a recording from the backend. * @param[in] channel The recording to get the stream properties for. * @param[inout] properties in: an array for the properties to return, out: the properties required to play the stream. - * @param[inout] iPropertiesCount: in the size of the properties array, out: the number of properties returned. + * @param[inout] iPropertiesCount in: the size of the properties array, out: the number of properties returned. * @return PVR_ERROR_NO_ERROR if the stream is available. * @remarks Required if PVR_ADDON_CAPABILITIES::bSupportsRecordings is set to true and the add-on does not implement recording stream functions (OpenRecordedStream, ...). In this case your implementation must fill the property PVR_STREAM_PROPERTY_STREAMURL with the URL Kodi should resolve to playback the recording. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. */ @@ -657,7 +686,10 @@ extern "C" pClient->toAddon.OpenDialogChannelScan = OpenDialogChannelScan; pClient->toAddon.MenuHook = CallMenuHook; - pClient->toAddon.GetEpg = GetEPGForChannel; + pClient->toAddon.GetEPGForChannel = GetEPGForChannel; + pClient->toAddon.IsEPGTagRecordable = IsEPGTagRecordable; + pClient->toAddon.IsEPGTagPlayable = IsEPGTagPlayable; + pClient->toAddon.GetEPGTagStreamProperties = GetEPGTagStreamProperties; pClient->toAddon.GetChannelGroupsAmount = GetChannelGroupsAmount; pClient->toAddon.GetChannelGroups = GetChannelGroups; diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h index 9a64f92..a7d21ed 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h @@ -77,9 +77,10 @@ struct DemuxPacket; #define XBMC_INVALID_CODEC_ID 0 #define XBMC_INVALID_CODEC { XBMC_CODEC_TYPE_UNKNOWN, XBMC_INVALID_CODEC_ID } -/* defines for GetChannelStreamProperties and GetRecordingStreamProperties */ +/* defines for GetChannelStreamProperties, GetRecordingStreamProperties and GetEPGTagStreamProperties */ #define PVR_STREAM_MAX_PROPERTIES 20 -#define PVR_STREAM_PROPERTY_STREAMURL "streamurl" +#define PVR_STREAM_PROPERTY_STREAMURL "streamurl" /*!< @brief the URL of the stream that should be played. */ +#define PVR_STREAM_PROPERTY_INPUTSTREAMADDON "inputstreamaddon" /*!< @brief the name of the inputstream add-on that should be used by Kodi to play the stream denoted by PVR_STREAM_PROPERTY_STREAMURL. Leave blank to use Kodi's built-in playing capabilities. */ /* using the default avformat's MAX_STREAMS value to be safe */ #define PVR_STREAM_MAX_STREAMS 20 @@ -620,7 +621,7 @@ extern "C" { DemuxPacket* (*AllocateDemuxPacket)(void* kodiInstance, int iDataSize); void (*ConnectionStateChange)(void* kodiInstance, const char* strConnectionString, PVR_CONNECTION_STATE newState, const char *strMessage); - void (*EpgEventStateChange)(void* kodiInstance, EPG_TAG* tag, unsigned int iUniqueChannelId, EPG_EVENT_STATE newState); + void (*EpgEventStateChange)(void* kodiInstance, EPG_TAG* tag, EPG_EVENT_STATE newState); xbmc_codec_t (*GetCodecByName)(const void* kodiInstance, const char* strCodecName); } AddonToKodiFuncTable_PVR; @@ -639,7 +640,10 @@ extern "C" { const char* (__cdecl* GetConnectionString)(void); PVR_ERROR (__cdecl* GetDriveSpace)(long long*, long long*); PVR_ERROR (__cdecl* MenuHook)(const PVR_MENUHOOK&, const PVR_MENUHOOK_DATA&); - PVR_ERROR (__cdecl* GetEpg)(ADDON_HANDLE, const PVR_CHANNEL&, time_t, time_t); + PVR_ERROR (__cdecl* GetEPGForChannel)(ADDON_HANDLE, const PVR_CHANNEL&, time_t, time_t); + PVR_ERROR (__cdecl* IsEPGTagRecordable)(const EPG_TAG*, bool*); + PVR_ERROR (__cdecl* IsEPGTagPlayable)(const EPG_TAG*, bool*); + PVR_ERROR (__cdecl* GetEPGTagStreamProperties)(const EPG_TAG*, PVR_NAMED_VALUE*, unsigned int*); int (__cdecl* GetChannelGroupsAmount)(void); PVR_ERROR (__cdecl* GetChannelGroups)(ADDON_HANDLE, bool); PVR_ERROR (__cdecl* GetChannelGroupMembers)(ADDON_HANDLE, const PVR_CHANNEL_GROUP&); -- cgit v1.2.3